mirror of
https://github.com/corda/corda.git
synced 2025-06-20 08:03:53 +00:00
CORDA-654: Handle non-standard file systems in NodeInfoWatcher (#1818)
Handle non-standard file systems such as JimFs, in NodeInfoWatcher. Instead of using `toFile()` to convert a Path to a File, open the Path for writing to directly.
This commit is contained in:
@ -1,16 +1,16 @@
|
|||||||
package net.corda.node.services.network
|
package net.corda.node.services.network
|
||||||
|
|
||||||
|
import com.google.common.jimfs.Configuration
|
||||||
|
import com.google.common.jimfs.Jimfs
|
||||||
import net.corda.cordform.CordformNode
|
import net.corda.cordform.CordformNode
|
||||||
import net.corda.core.internal.createDirectories
|
import net.corda.core.internal.createDirectories
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.node.services.KeyManagementService
|
import net.corda.core.node.services.KeyManagementService
|
||||||
import net.corda.core.utilities.seconds
|
|
||||||
import net.corda.node.services.identity.InMemoryIdentityService
|
import net.corda.node.services.identity.InMemoryIdentityService
|
||||||
import net.corda.testing.ALICE
|
import net.corda.testing.ALICE
|
||||||
import net.corda.testing.ALICE_KEY
|
import net.corda.testing.ALICE_KEY
|
||||||
import net.corda.testing.DEV_TRUST_ROOT
|
import net.corda.testing.DEV_TRUST_ROOT
|
||||||
import net.corda.testing.eventually
|
|
||||||
import net.corda.testing.getTestPartyAndCertificate
|
import net.corda.testing.getTestPartyAndCertificate
|
||||||
import net.corda.testing.node.MockKeyManagementService
|
import net.corda.testing.node.MockKeyManagementService
|
||||||
import net.corda.testing.node.NodeBasedTest
|
import net.corda.testing.node.NodeBasedTest
|
||||||
@ -56,6 +56,7 @@ class NodeInfoWatcherTest : NodeBasedTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `save a NodeInfo`() {
|
fun `save a NodeInfo`() {
|
||||||
|
assertEquals(0, folder.root.list().size)
|
||||||
NodeInfoWatcher.saveToFile(folder.root.toPath(), nodeInfo, keyManagementService)
|
NodeInfoWatcher.saveToFile(folder.root.toPath(), nodeInfo, keyManagementService)
|
||||||
|
|
||||||
assertEquals(1, folder.root.list().size)
|
assertEquals(1, folder.root.list().size)
|
||||||
@ -66,30 +67,45 @@ class NodeInfoWatcherTest : NodeBasedTest() {
|
|||||||
assertThat(contentOf(file)).isNotEmpty()
|
assertThat(contentOf(file)).isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `save a NodeInfo to JimFs`() {
|
||||||
|
val jimFs = Jimfs.newFileSystem(Configuration.unix())
|
||||||
|
val jimFolder = jimFs.getPath("/nodeInfo")
|
||||||
|
NodeInfoWatcher.saveToFile(jimFolder, nodeInfo, keyManagementService)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `load an empty Directory`() {
|
fun `load an empty Directory`() {
|
||||||
nodeInfoPath.createDirectories()
|
nodeInfoPath.createDirectories()
|
||||||
|
|
||||||
nodeInfoWatcher.nodeInfoUpdates()
|
val subscription = nodeInfoWatcher.nodeInfoUpdates()
|
||||||
.subscribe(testSubscriber)
|
.subscribe(testSubscriber)
|
||||||
|
try {
|
||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
val readNodes = testSubscriber.onNextEvents.distinct()
|
val readNodes = testSubscriber.onNextEvents.distinct()
|
||||||
assertEquals(0, readNodes.size)
|
assertEquals(0, readNodes.size)
|
||||||
|
} finally {
|
||||||
|
subscription.unsubscribe()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `load a non empty Directory`() {
|
fun `load a non empty Directory`() {
|
||||||
createNodeInfoFileInPath(nodeInfo)
|
createNodeInfoFileInPath(nodeInfo)
|
||||||
|
|
||||||
nodeInfoWatcher.nodeInfoUpdates()
|
val subscription = nodeInfoWatcher.nodeInfoUpdates()
|
||||||
.subscribe(testSubscriber)
|
.subscribe(testSubscriber)
|
||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
|
try {
|
||||||
val readNodes = testSubscriber.onNextEvents.distinct()
|
val readNodes = testSubscriber.onNextEvents.distinct()
|
||||||
|
|
||||||
assertEquals(1, readNodes.size)
|
assertEquals(1, readNodes.size)
|
||||||
assertEquals(nodeInfo, readNodes.first())
|
assertEquals(nodeInfo, readNodes.first())
|
||||||
|
} finally {
|
||||||
|
subscription.unsubscribe()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -97,8 +113,9 @@ class NodeInfoWatcherTest : NodeBasedTest() {
|
|||||||
nodeInfoPath.createDirectories()
|
nodeInfoPath.createDirectories()
|
||||||
|
|
||||||
// Start polling with an empty folder.
|
// Start polling with an empty folder.
|
||||||
nodeInfoWatcher.nodeInfoUpdates()
|
val subscription = nodeInfoWatcher.nodeInfoUpdates()
|
||||||
.subscribe(testSubscriber)
|
.subscribe(testSubscriber)
|
||||||
|
try {
|
||||||
// Ensure the watch service is started.
|
// Ensure the watch service is started.
|
||||||
advanceTime()
|
advanceTime()
|
||||||
// Check no nodeInfos are read.
|
// Check no nodeInfos are read.
|
||||||
@ -108,11 +125,12 @@ class NodeInfoWatcherTest : NodeBasedTest() {
|
|||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
// We need the WatchService to report a change and that might not happen immediately.
|
// We need the WatchService to report a change and that might not happen immediately.
|
||||||
eventually<AssertionError, Unit>(5.seconds) {
|
testSubscriber.awaitValueCount(1, 5, TimeUnit.SECONDS)
|
||||||
// The same folder can be reported more than once, so take unique values.
|
// The same folder can be reported more than once, so take unique values.
|
||||||
val readNodes = testSubscriber.onNextEvents.distinct()
|
val readNodes = testSubscriber.onNextEvents.distinct()
|
||||||
assertEquals(1, readNodes.size)
|
|
||||||
assertEquals(nodeInfo, readNodes.first())
|
assertEquals(nodeInfo, readNodes.first())
|
||||||
|
} finally {
|
||||||
|
subscription.unsubscribe()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,8 @@
|
|||||||
package net.corda.node.services.network
|
package net.corda.node.services.network
|
||||||
|
|
||||||
import net.corda.cordform.CordformNode
|
import net.corda.cordform.CordformNode
|
||||||
import net.corda.core.crypto.SecureHash
|
|
||||||
import net.corda.core.crypto.SignedData
|
import net.corda.core.crypto.SignedData
|
||||||
import net.corda.core.internal.createDirectories
|
import net.corda.core.internal.*
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.isDirectory
|
|
||||||
import net.corda.core.internal.isRegularFile
|
|
||||||
import net.corda.core.internal.list
|
|
||||||
import net.corda.core.internal.readAll
|
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.node.services.KeyManagementService
|
import net.corda.core.node.services.KeyManagementService
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
@ -17,6 +11,7 @@ import net.corda.core.utilities.loggerFor
|
|||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Scheduler
|
import rx.Scheduler
|
||||||
import rx.schedulers.Schedulers
|
import rx.schedulers.Schedulers
|
||||||
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.streams.toList
|
import kotlin.streams.toList
|
||||||
@ -52,11 +47,9 @@ class NodeInfoWatcher(private val nodePath: Path,
|
|||||||
try {
|
try {
|
||||||
path.createDirectories()
|
path.createDirectories()
|
||||||
val serializedBytes = nodeInfo.serialize()
|
val serializedBytes = nodeInfo.serialize()
|
||||||
val regSig = keyManager.sign(serializedBytes.bytes,
|
val regSig = keyManager.sign(serializedBytes.bytes, nodeInfo.legalIdentities.first().owningKey)
|
||||||
nodeInfo.legalIdentities.first().owningKey)
|
|
||||||
val signedData = SignedData(serializedBytes, regSig)
|
val signedData = SignedData(serializedBytes, regSig)
|
||||||
val file = (path / ("nodeInfo-" + SecureHash.sha256(serializedBytes.bytes).toString())).toFile()
|
signedData.serialize().open().copyTo(path / "nodeInfo-${serializedBytes.hash}")
|
||||||
file.writeBytes(signedData.serialize().bytes)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logger.warn("Couldn't write node info to file", e)
|
logger.warn("Couldn't write node info to file", e)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user