From 73528d287d8f84833d59e77f07a0897e85cf1652 Mon Sep 17 00:00:00 2001 From: Andrzej Cichocki Date: Thu, 3 Aug 2017 11:06:22 +0100 Subject: [PATCH] Refactoring related to obsolete attachments directory (#1150) * No longer create obsolete "attachments" directory * Remove redundant NodeAttachmentService param * Add type param to MockNetwork.Factory to eliminate casts * Use null not -1 for unforced node ID * Remove redundant createNode args --- .../AttachmentSerializationTest.kt | 2 +- .../net/corda/node/internal/AbstractNode.kt | 7 +- .../persistence/NodeAttachmentService.kt | 6 +- .../corda/node/messaging/AttachmentTests.kt | 4 +- .../node/messaging/TwoPartyTradeFlowTests.kt | 9 +-- .../network/AbstractNetworkMapServiceTest.kt | 14 ++-- .../network/InMemoryNetworkMapCacheTest.kt | 4 +- .../network/InMemoryNetworkMapServiceTest.kt | 3 +- .../PersistentNetworkMapServiceTest.kt | 4 +- .../persistence/NodeAttachmentStorageTest.kt | 8 +- .../statemachine/FlowFrameworkTests.kt | 4 +- .../transactions/NotaryServiceTests.kt | 2 +- .../ValidatingNotaryServiceTests.kt | 2 +- .../net/corda/netmap/simulation/Simulation.kt | 33 ++++---- .../kotlin/net/corda/testing/node/MockNode.kt | 76 ++++++++----------- 15 files changed, 75 insertions(+), 103 deletions(-) diff --git a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt index 6c8f11b6e9..eb32504316 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -151,7 +151,7 @@ class AttachmentSerializationTest { private fun rebootClientAndGetAttachmentContent(checkAttachmentsOnLoad: Boolean = true): String { client.stop() - client = mockNet.createNode(server.network.myAddress, client.id, object : MockNetwork.Factory { + client = mockNet.createNode(server.network.myAddress, client.id, object : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, entropyRoot: BigInteger): MockNetwork.MockNode { return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, overrideServices, entropyRoot) { override fun startMessagingService(rpcOps: RPCOps) { diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 21f9952e41..8698a2c6fb 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -413,7 +413,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, private fun makeServices(): MutableList { checkpointStorage = DBCheckpointStorage() _services = ServiceHubInternalImpl() - attachments = createAttachmentStorage() + attachments = NodeAttachmentService(configuration.dataSourceProperties, services.monitoringService.metrics, configuration.database) network = makeMessagingService() info = makeInfo() @@ -762,11 +762,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, protected open fun generateKeyPair() = cryptoGenerateKeyPair() - private fun createAttachmentStorage(): NodeAttachmentService { - val attachmentsDir = (configuration.baseDirectory / "attachments").createDirectories() - return NodeAttachmentService(attachmentsDir, configuration.dataSourceProperties, services.monitoringService.metrics, configuration.database) - } - private inner class ServiceHubInternalImpl : ServiceHubInternal, SingletonSerializeAsToken() { override val rpcFlows = ArrayList>>() override val uploaders = ArrayList() diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt index 5d6672a32b..354ebb3609 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt @@ -9,7 +9,6 @@ import com.google.common.io.CountingInputStream import net.corda.core.contracts.AbstractAttachment import net.corda.core.contracts.Attachment import net.corda.core.crypto.SecureHash -import net.corda.core.internal.isDirectory import net.corda.core.node.services.AttachmentStorage import net.corda.core.serialization.* import net.corda.core.utilities.loggerFor @@ -22,7 +21,6 @@ import java.io.FilterInputStream import java.io.IOException import java.io.InputStream import java.nio.file.FileAlreadyExistsException -import java.nio.file.Path import java.nio.file.Paths import java.util.* import java.util.jar.JarInputStream @@ -32,7 +30,7 @@ import javax.annotation.concurrent.ThreadSafe * Stores attachments in H2 database. */ @ThreadSafe -class NodeAttachmentService(val storePath: Path, dataSourceProperties: Properties, metrics: MetricRegistry, databaseProperties: Properties?) +class NodeAttachmentService(dataSourceProperties: Properties, metrics: MetricRegistry, databaseProperties: Properties?) : AttachmentStorage, AcceptsFileUpload, SingletonSerializeAsToken() { companion object { private val log = loggerFor() @@ -47,8 +45,6 @@ class NodeAttachmentService(val storePath: Path, dataSourceProperties: Propertie private val attachmentCount = metrics.counter("Attachments") init { - require(storePath.isDirectory()) { "$storePath must be a directory" } - session.withTransaction { attachmentCount.inc(session.count(AttachmentEntity::class).get().value().toLong()) } diff --git a/node/src/test/kotlin/net/corda/node/messaging/AttachmentTests.kt b/node/src/test/kotlin/net/corda/node/messaging/AttachmentTests.kt index ec55bba2eb..1970c8f8e5 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/AttachmentTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/AttachmentTests.kt @@ -103,7 +103,7 @@ class AttachmentTests { @Test fun `malicious response`() { // Make a node that doesn't do sanity checking at load time. - val n0 = mockNet.createNode(null, -1, object : MockNetwork.Factory { + val n0 = mockNet.createNode(nodeFactory = object : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, @@ -115,7 +115,7 @@ class AttachmentTests { } } } - }, true, null, null, ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)) + }, advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))) val n1 = mockNet.createNode(n0.network.myAddress) val attachment = fakeAttachment() diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index d9b395ffda..017b961ab4 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -249,7 +249,7 @@ class TwoPartyTradeFlowTests { // ... bring the node back up ... the act of constructing the SMM will re-register the message handlers // that Bob was waiting on before the reboot occurred. - bobNode = mockNet.createNode(networkMapAddress, bobAddr.id, object : MockNetwork.Factory { + bobNode = mockNet.createNode(networkMapAddress, bobAddr.id, object : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, entropyRoot: BigInteger): MockNetwork.MockNode { @@ -290,10 +290,9 @@ class TwoPartyTradeFlowTests { // of gets and puts. private fun makeNodeWithTracking( networkMapAddress: SingleMessageRecipient?, - name: X500Name, - overridenServices: Map? = null): MockNetwork.MockNode { + name: X500Name): MockNetwork.MockNode { // Create a node in the mock network ... - return mockNet.createNode(networkMapAddress, -1, object : MockNetwork.Factory { + return mockNet.createNode(networkMapAddress, nodeFactory = object : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, @@ -307,7 +306,7 @@ class TwoPartyTradeFlowTests { } } } - }, true, name, overridenServices) + }, legalName = name) } @Test diff --git a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt index 6b6d20da42..4306107d9c 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt @@ -1,7 +1,6 @@ package net.corda.node.services.network import com.google.common.util.concurrent.ListenableFuture -import net.corda.core.crypto.random63BitValue import net.corda.core.getOrThrow import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.NodeInfo @@ -53,8 +52,11 @@ abstract class AbstractNetworkMapServiceTest @Before fun setup() { mockNet = MockNetwork(defaultFactory = nodeFactory) - mapServiceNode = mockNet.createNode(null, -1, nodeFactory, true, DUMMY_MAP.name, null, BigInteger.valueOf(random63BitValue()), ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)) - alice = mockNet.createNode(mapServiceNode.network.myAddress, -1, nodeFactory, true, ALICE.name) + mapServiceNode = mockNet.createNode( + nodeFactory = nodeFactory, + legalName = DUMMY_MAP.name, + advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))) + alice = mockNet.createNode(mapServiceNode.network.myAddress, nodeFactory = nodeFactory, legalName = ALICE.name) mockNet.runNetwork() lastSerial = System.currentTimeMillis() } @@ -64,7 +66,7 @@ abstract class AbstractNetworkMapServiceTest mockNet.stopNodes() } - protected abstract val nodeFactory: MockNetwork.Factory + protected abstract val nodeFactory: MockNetwork.Factory<*> protected abstract val networkMapService: S @@ -249,7 +251,7 @@ abstract class AbstractNetworkMapServiceTest } private fun addNewNodeToNetworkMap(legalName: X500Name): MockNode { - val node = mockNet.createNode(networkMapAddress = mapServiceNode.network.myAddress, legalName = legalName) + val node = mockNet.createNode(mapServiceNode.network.myAddress, legalName = legalName) mockNet.runNetwork() lastSerial = System.currentTimeMillis() return node @@ -269,7 +271,7 @@ abstract class AbstractNetworkMapServiceTest } } - private object NoNMSNodeFactory : MockNetwork.Factory { + private object NoNMSNodeFactory : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, diff --git a/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapCacheTest.kt b/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapCacheTest.kt index 2d25f28741..d6a3e36852 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapCacheTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapCacheTest.kt @@ -38,8 +38,8 @@ class InMemoryNetworkMapCacheTest { @Test fun `key collision`() { val entropy = BigInteger.valueOf(24012017L) - val nodeA = mockNet.createNode(null, -1, MockNetwork.DefaultFactory, true, ALICE.name, null, entropy, ServiceInfo(NetworkMapService.type)) - val nodeB = mockNet.createNode(null, -1, MockNetwork.DefaultFactory, true, BOB.name, null, entropy, ServiceInfo(NetworkMapService.type)) + val nodeA = mockNet.createNode(nodeFactory = MockNetwork.DefaultFactory, legalName = ALICE.name, entropyRoot = entropy, advertisedServices = ServiceInfo(NetworkMapService.type)) + val nodeB = mockNet.createNode(nodeFactory = MockNetwork.DefaultFactory, legalName = BOB.name, entropyRoot = entropy, advertisedServices = ServiceInfo(NetworkMapService.type)) assertEquals(nodeA.info.legalIdentity, nodeB.info.legalIdentity) mockNet.runNetwork() diff --git a/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapServiceTest.kt index 0185e4a47c..c6d8566560 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/InMemoryNetworkMapServiceTest.kt @@ -1,10 +1,9 @@ package net.corda.node.services.network -import net.corda.node.services.network.InMemoryNetworkMapService import net.corda.testing.node.MockNetwork class InMemoryNetworkMapServiceTest : AbstractNetworkMapServiceTest() { - override val nodeFactory: MockNetwork.Factory get() = MockNetwork.DefaultFactory + override val nodeFactory get() = MockNetwork.DefaultFactory override val networkMapService: InMemoryNetworkMapService get() = mapServiceNode.inNodeNetworkMapService as InMemoryNetworkMapService override fun swizzle() = Unit } diff --git a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt index c4f412d429..27dac2cd35 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt @@ -15,7 +15,7 @@ import java.security.KeyPair */ class PersistentNetworkMapServiceTest : AbstractNetworkMapServiceTest() { - override val nodeFactory: MockNetwork.Factory get() = NodeFactory + override val nodeFactory: MockNetwork.Factory<*> get() = NodeFactory override val networkMapService: PersistentNetworkMapService get() = (mapServiceNode.inNodeNetworkMapService as SwizzleNetworkMapService).delegate @@ -26,7 +26,7 @@ class PersistentNetworkMapServiceTest : AbstractNetworkMapServiceTest { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt index f1d5a529e1..076db8da53 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt @@ -60,7 +60,7 @@ class NodeAttachmentStorageTest { val expectedHash = testJar.readAll().sha256() database.transaction { - val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) + val storage = NodeAttachmentService(dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) val id = testJar.read { storage.importAttachment(it) } assertEquals(expectedHash, id) @@ -86,7 +86,7 @@ class NodeAttachmentStorageTest { fun `duplicates not allowed`() { val testJar = makeTestJar() database.transaction { - val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) + val storage = NodeAttachmentService(dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) testJar.read { storage.importAttachment(it) } @@ -102,7 +102,7 @@ class NodeAttachmentStorageTest { fun `corrupt entry throws exception`() { val testJar = makeTestJar() database.transaction { - val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) + val storage = NodeAttachmentService(dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) val id = testJar.read { storage.importAttachment(it) } // Corrupt the file in the store. @@ -130,7 +130,7 @@ class NodeAttachmentStorageTest { @Test fun `non jar rejected`() { database.transaction { - val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) + val storage = NodeAttachmentService(dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties()) val path = fs.getPath("notajar") path.writeLines(listOf("Hey", "there!")) path.read { diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index 7591588402..a7a080e9a7 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -170,7 +170,7 @@ class FlowFrameworkTests { node3.disableDBCloseOnStop() node3.stop() - node3 = mockNet.createNode(node1.network.myAddress, forcedID = node3.id) + node3 = mockNet.createNode(node1.network.myAddress, node3.id) val restoredFlow = node3.getSingleFlow().first assertEquals(false, restoredFlow.flowStarted) // Not started yet as no network activity has been allowed yet mockNet.runNetwork() // Allow network map messages to flow @@ -180,7 +180,7 @@ class FlowFrameworkTests { node3.stop() // Now it is completed the flow should leave no Checkpoint. - node3 = mockNet.createNode(node1.network.myAddress, forcedID = node3.id) + node3 = mockNet.createNode(node1.network.myAddress, node3.id) mockNet.runNetwork() // Allow network map messages to flow node3.smm.executor.flush() assertTrue(node3.smm.findStateMachines(NoOpFlow::class.java).isEmpty()) diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt index 3c9e7b3dc3..effb4d8145 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt @@ -37,7 +37,7 @@ class NotaryServiceTests { notaryNode = mockNet.createNode( legalName = DUMMY_NOTARY.name, advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))) - clientNode = mockNet.createNode(networkMapAddress = notaryNode.network.myAddress) + clientNode = mockNet.createNode(notaryNode.network.myAddress) mockNet.runNetwork() // Clear network map registration messages } diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt index b5ec968164..3d5cee46e1 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt @@ -39,7 +39,7 @@ class ValidatingNotaryServiceTests { legalName = DUMMY_NOTARY.name, advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(ValidatingNotaryService.type)) ) - clientNode = mockNet.createNode(networkMapAddress = notaryNode.network.myAddress) + clientNode = mockNet.createNode(notaryNode.network.myAddress) mockNet.runNetwork() // Clear network map registration messages } diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt index 82bfbfee2a..ca71e3e50e 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt @@ -61,12 +61,12 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } } - inner class BankFactory : MockNetwork.Factory { + inner class BankFactory : MockNetwork.Factory { var counter = 0 override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, - entropyRoot: BigInteger): MockNetwork.MockNode { + entropyRoot: BigInteger): SimulatedNode { val letter = 'A' + counter val (city, country) = bankLocations[counter++ % bankLocations.size] @@ -79,17 +79,17 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, fun createAll(): List { return bankLocations.mapIndexed { i, _ -> // Use deterministic seeds so the simulation is stable. Needed so that party owning keys are stable. - mockNet.createNode(networkMap.network.myAddress, start = false, nodeFactory = this, entropyRoot = BigInteger.valueOf(i.toLong())) as SimulatedNode + mockNet.createNode(networkMap.network.myAddress, nodeFactory = this, start = false, entropyRoot = BigInteger.valueOf(i.toLong())) } } } val bankFactory = BankFactory() - object NetworkMapNodeFactory : MockNetwork.Factory { + object NetworkMapNodeFactory : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, - entropyRoot: BigInteger): MockNetwork.MockNode { + entropyRoot: BigInteger): SimulatedNode { require(advertisedServices.containsType(NetworkMapService.type)) val cfg = testNodeConfiguration( baseDirectory = config.baseDirectory, @@ -98,10 +98,10 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } } - object NotaryNodeFactory : MockNetwork.Factory { + object NotaryNodeFactory : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, - entropyRoot: BigInteger): MockNetwork.MockNode { + entropyRoot: BigInteger): SimulatedNode { require(advertisedServices.containsType(SimpleNotaryService.type)) val cfg = testNodeConfiguration( baseDirectory = config.baseDirectory, @@ -110,13 +110,13 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } } - object RatesOracleFactory : MockNetwork.Factory { + object RatesOracleFactory : MockNetwork.Factory { // TODO: Make a more realistic legal name val RATES_SERVICE_NAME = X500Name("CN=Rates Service Provider,O=R3,OU=corda,L=Madrid,C=ES") override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, - entropyRoot: BigInteger): MockNetwork.MockNode { + entropyRoot: BigInteger): SimulatedNode { require(advertisedServices.containsType(NodeInterestRates.Oracle.type)) val cfg = testNodeConfiguration( baseDirectory = config.baseDirectory, @@ -136,10 +136,10 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } } - object RegulatorFactory : MockNetwork.Factory { + object RegulatorFactory : MockNetwork.Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, - entropyRoot: BigInteger): MockNetwork.MockNode { + entropyRoot: BigInteger): SimulatedNode { val cfg = testNodeConfiguration( baseDirectory = config.baseDirectory, myLegalName = DUMMY_REGULATOR.name) @@ -153,13 +153,10 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val mockNet = MockNetwork(networkSendManuallyPumped, runAsync) // This one must come first. - val networkMap: SimulatedNode - = mockNet.createNode(null, nodeFactory = NetworkMapNodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type)) as SimulatedNode - val notary: SimulatedNode - = mockNet.createNode(networkMap.network.myAddress, nodeFactory = NotaryNodeFactory, advertisedServices = ServiceInfo(SimpleNotaryService.type)) as SimulatedNode - val regulators: List = listOf(mockNet.createNode(networkMap.network.myAddress, start = false, nodeFactory = RegulatorFactory) as SimulatedNode) - val ratesOracle: SimulatedNode - = mockNet.createNode(networkMap.network.myAddress, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.Oracle.type)) as SimulatedNode + val networkMap = mockNet.createNode(nodeFactory = NetworkMapNodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type)) + val notary = mockNet.createNode(networkMap.network.myAddress, nodeFactory = NotaryNodeFactory, advertisedServices = ServiceInfo(SimpleNotaryService.type)) + val regulators = listOf(mockNet.createNode(networkMap.network.myAddress, start = false, nodeFactory = RegulatorFactory)) + val ratesOracle = mockNet.createNode(networkMap.network.myAddress, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.Oracle.type)) // All nodes must be in one of these two lists for the purposes of the visualiser tool. val serviceProviders: List = listOf(notary, ratesOracle, networkMap) diff --git a/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt b/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt index 284d680ce2..09485a824d 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -13,7 +13,6 @@ import net.corda.core.getOrThrow import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectory -import net.corda.core.internal.div import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.RPCOps import net.corda.core.messaging.SingleMessageRecipient @@ -38,11 +37,9 @@ import org.apache.activemq.artemis.utils.ReusableLatch import org.bouncycastle.asn1.x500.X500Name import org.slf4j.Logger import java.math.BigInteger -import java.nio.file.FileSystem import java.nio.file.Path import java.security.KeyPair import java.security.cert.X509Certificate -import java.util.* import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicInteger @@ -63,23 +60,19 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, private val threadPerNode: Boolean = false, servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(), - private val defaultFactory: Factory = MockNetwork.DefaultFactory, + private val defaultFactory: Factory<*> = MockNetwork.DefaultFactory, private val initialiseSerialization: Boolean = true) { - val nextNodeId - get() = _nextNodeId - private var _nextNodeId = 0 - val filesystem: FileSystem = Jimfs.newFileSystem(unix()) - private val busyLatch: ReusableLatch = ReusableLatch() + var nextNodeId = 0 + private set + private val filesystem = Jimfs.newFileSystem(unix()) + private val busyLatch = ReusableLatch() val messagingNetwork = InMemoryMessagingNetwork(networkSendManuallyPumped, servicePeerAllocationStrategy, busyLatch) - // A unique identifier for this network to segregate databases with the same nodeID but different networks. private val networkId = random63BitValue() - - val identities = ArrayList() - - private val _nodes = ArrayList() + private val identities = mutableListOf() + private val _nodes = mutableListOf() /** A read only view of the current set of executing nodes. */ - val nodes: List = _nodes + val nodes: List get() = _nodes init { if (initialiseSerialization) initialiseTestSerialization() @@ -87,7 +80,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, } /** Allows customisation of how nodes are created. */ - interface Factory { + interface Factory { /** * @param overrideServices a set of service entries to use in place of the node's default service entries, * for example where a node's service is part of a cluster. @@ -96,10 +89,10 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, */ fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, - entropyRoot: BigInteger): MockNode + entropyRoot: BigInteger): N } - object DefaultFactory : Factory { + object DefaultFactory : Factory { override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, overrideServices: Map?, entropyRoot: BigInteger): MockNode { @@ -277,16 +270,6 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, } } - /** - * Returns a node, optionally created by the passed factory method. - * @param overrideServices a set of service entries to use in place of the node's default service entries, - * for example where a node's service is part of a cluster. - */ - fun createNode(networkMapAddress: SingleMessageRecipient? = null, forcedID: Int = -1, nodeFactory: Factory = defaultFactory, - start: Boolean = true, legalName: X500Name? = null, overrideServices: Map? = null, - vararg advertisedServices: ServiceInfo): MockNode - = createNode(networkMapAddress, forcedID, nodeFactory, start, legalName, overrideServices, BigInteger.valueOf(random63BitValue()), *advertisedServices) - /** * Returns a node, optionally created by the passed factory method. * @param overrideServices a set of service entries to use in place of the node's default service entries, @@ -295,29 +278,31 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, * but can be overridden to cause nodes to have stable or colliding identity/service keys. * @param configOverrides add/override behaviour of the [NodeConfiguration] mock object. */ - fun createNode(networkMapAddress: SingleMessageRecipient? = null, forcedID: Int = -1, nodeFactory: Factory = defaultFactory, + fun createNode(networkMapAddress: SingleMessageRecipient? = null, forcedID: Int? = null, start: Boolean = true, legalName: X500Name? = null, overrideServices: Map? = null, entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), vararg advertisedServices: ServiceInfo, configOverrides: (NodeConfiguration) -> Any? = {}): MockNode { - val newNode = forcedID == -1 - val id = if (newNode) _nextNodeId++ else forcedID - - val path = baseDirectory(id) - if (newNode) - (path / "attachments").createDirectories() + return createNode(networkMapAddress, forcedID, defaultFactory, start, legalName, overrideServices, entropyRoot, *advertisedServices, configOverrides = configOverrides) + } + /** Like the other [createNode] but takes a [Factory] and propagates its [MockNode] subtype. */ + fun createNode(networkMapAddress: SingleMessageRecipient? = null, forcedID: Int? = null, nodeFactory: Factory, + start: Boolean = true, legalName: X500Name? = null, overrideServices: Map? = null, + entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), + vararg advertisedServices: ServiceInfo, + configOverrides: (NodeConfiguration) -> Any? = {}): N { + val id = forcedID ?: nextNodeId++ val config = testNodeConfiguration( - baseDirectory = path, + baseDirectory = baseDirectory(id).createDirectories(), myLegalName = legalName ?: getTestX509Name("Mock Company $id")).also { whenever(it.dataSourceProperties).thenReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")) configOverrides(it) } return nodeFactory.create(config, this, networkMapAddress, advertisedServices.toSet(), id, overrideServices, entropyRoot).apply { if (start) { - configuration.baseDirectory.createDirectories() start() - if (threadPerNode && networkMapAddress != null) networkMapRegistrationFuture.getOrThrow() + if (threadPerNode && networkMapAddress != null) networkMapRegistrationFuture.getOrThrow() // XXX: What about manually-started nodes? } _nodes.add(this) } @@ -354,20 +339,19 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, /** * Sets up a network with the requested number of nodes (defaulting to two), with one or more service nodes that - * run a notary, network map, any oracles etc. Can't be combined with [createTwoNodes]. + * run a notary, network map, any oracles etc. */ @JvmOverloads - fun createSomeNodes(numPartyNodes: Int = 2, nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = DUMMY_NOTARY_KEY): BasketOfNodes { + fun createSomeNodes(numPartyNodes: Int = 2, nodeFactory: Factory<*> = defaultFactory, notaryKeyPair: KeyPair? = DUMMY_NOTARY_KEY): BasketOfNodes { require(nodes.isEmpty()) val notaryServiceInfo = ServiceInfo(SimpleNotaryService.type) val notaryOverride = if (notaryKeyPair != null) mapOf(Pair(notaryServiceInfo, notaryKeyPair)) else null - val mapNode = createNode(null, nodeFactory = nodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type)) + val mapNode = createNode(nodeFactory = nodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type)) val mapAddress = mapNode.network.myAddress - val notaryNode = createNode(mapAddress, nodeFactory = nodeFactory, overrideServices = notaryOverride, - advertisedServices = notaryServiceInfo) + val notaryNode = createNode(mapAddress, nodeFactory = nodeFactory, overrideServices = notaryOverride, advertisedServices = notaryServiceInfo) val nodes = ArrayList() repeat(numPartyNodes) { nodes += createPartyNode(mapAddress) @@ -382,14 +366,14 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, legalName: X500Name? = null, overrideServices: Map? = null, serviceName: X500Name? = null): MockNode { - return createNode(networkMapAddress, -1, defaultFactory, true, legalName, overrideServices, BigInteger.valueOf(random63BitValue()), - ServiceInfo(NetworkMapService.type), ServiceInfo(ValidatingNotaryService.type, serviceName)) + return createNode(networkMapAddress, legalName = legalName, overrideServices = overrideServices, + advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(ValidatingNotaryService.type, serviceName))) } fun createPartyNode(networkMapAddress: SingleMessageRecipient, legalName: X500Name? = null, overrideServices: Map? = null): MockNode { - return createNode(networkMapAddress, -1, defaultFactory, true, legalName, overrideServices) + return createNode(networkMapAddress, legalName = legalName, overrideServices = overrideServices) } @Suppress("unused") // This is used from the network visualiser tool.