CORDA-1489 Exposure of node internals in mock network (#4130)

* Introduce public subset of config to tweak config via mock net work without exposing internal node config.

* Removal of functions exposing (internal) NodeConfiguration from the public test API

* Code review fixes

* Blank lines removed

* Documented mock network API change in upgrade notes.

* Updated documentation and API doc.

* More documentation/API doc
This commit is contained in:
Christian Sailer
2018-11-05 09:29:05 +00:00
committed by GitHub
parent 460cf3480f
commit 3260d9f2c4
12 changed files with 113 additions and 94 deletions

View File

@ -6167,12 +6167,6 @@ public class net.corda.testing.node.MockNetwork extends java.lang.Object
@NotNull @NotNull
public final net.corda.testing.node.StartedMockNode createNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger) public final net.corda.testing.node.StartedMockNode createNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger)
@NotNull @NotNull
public final net.corda.testing.node.StartedMockNode createNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>)
@NotNull
public final net.corda.testing.node.StartedMockNode createNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>, java.util.Collection<? extends net.corda.testing.node.TestCordapp>)
@NotNull
public final net.corda.testing.node.StartedMockNode createNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>, java.util.List<String>)
@NotNull
public final net.corda.testing.node.StartedMockNode createNode(net.corda.testing.node.MockNodeParameters) public final net.corda.testing.node.StartedMockNode createNode(net.corda.testing.node.MockNodeParameters)
@NotNull @NotNull
public final net.corda.testing.node.StartedMockNode createPartyNode(net.corda.core.identity.CordaX500Name) public final net.corda.testing.node.StartedMockNode createPartyNode(net.corda.core.identity.CordaX500Name)
@ -6185,12 +6179,6 @@ public class net.corda.testing.node.MockNetwork extends java.lang.Object
@NotNull @NotNull
public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger) public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger)
@NotNull @NotNull
public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>)
@NotNull
public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>, java.util.Collection<? extends net.corda.testing.node.TestCordapp>)
@NotNull
public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.core.identity.CordaX500Name, Integer, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>, java.util.List<String>)
@NotNull
public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.testing.node.MockNodeParameters) public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.testing.node.MockNodeParameters)
@NotNull @NotNull
public final java.util.List<String> getCordappPackages() public final java.util.List<String> getCordappPackages()
@ -6269,24 +6257,14 @@ public final class net.corda.testing.node.MockNetworkParameters extends java.lan
## ##
public final class net.corda.testing.node.MockNodeParameters extends java.lang.Object public final class net.corda.testing.node.MockNodeParameters extends java.lang.Object
public <init>() public <init>()
public <init>(Integer, net.corda.core.identity.CordaX500Name, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>)
public <init>(Integer, net.corda.core.identity.CordaX500Name, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>, java.util.Collection<? extends net.corda.testing.node.TestCordapp>)
@Nullable @Nullable
public final Integer component1() public final Integer component1()
@Nullable @Nullable
public final net.corda.core.identity.CordaX500Name component2() public final net.corda.core.identity.CordaX500Name component2()
@NotNull @NotNull
public final java.math.BigInteger component3() public final java.math.BigInteger component3()
@NotNull
public final kotlin.jvm.functions.Function1<net.corda.node.services.config.NodeConfiguration, Object> component4()
@NotNull
public final net.corda.testing.node.MockNodeParameters copy(Integer, net.corda.core.identity.CordaX500Name, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>)
@NotNull
public final net.corda.testing.node.MockNodeParameters copy(Integer, net.corda.core.identity.CordaX500Name, java.math.BigInteger, kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>, java.util.Collection<? extends net.corda.testing.node.TestCordapp>)
public boolean equals(Object) public boolean equals(Object)
@NotNull @NotNull
public final kotlin.jvm.functions.Function1<net.corda.node.services.config.NodeConfiguration, Object> getConfigOverrides()
@NotNull
public final java.math.BigInteger getEntropyRoot() public final java.math.BigInteger getEntropyRoot()
@Nullable @Nullable
public final Integer getForcedID() public final Integer getForcedID()
@ -6295,8 +6273,6 @@ public final class net.corda.testing.node.MockNodeParameters extends java.lang.O
public int hashCode() public int hashCode()
public String toString() public String toString()
@NotNull @NotNull
public final net.corda.testing.node.MockNodeParameters withConfigOverrides(kotlin.jvm.functions.Function1<? super net.corda.node.services.config.NodeConfiguration, ?>)
@NotNull
public final net.corda.testing.node.MockNodeParameters withEntropyRoot(java.math.BigInteger) public final net.corda.testing.node.MockNodeParameters withEntropyRoot(java.math.BigInteger)
@NotNull @NotNull
public final net.corda.testing.node.MockNodeParameters withForcedID(Integer) public final net.corda.testing.node.MockNodeParameters withForcedID(Integer)

View File

@ -179,14 +179,14 @@ provide different parameters to each node using the following methods on ``MockN
* @param forcedID A unique identifier for the node. * @param forcedID A unique identifier for the node.
* @param entropyRoot The initial entropy value to use when generating keys. Defaults to an (insecure) random value, * @param entropyRoot The initial entropy value to use when generating keys. Defaults to an (insecure) random value,
* but can be overridden to cause nodes to have stable or colliding identity/service keys. * 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. * @param configOverrides Add/override the default configuration/behaviour of the node
* @param extraCordappPackages Extra CorDapp packages to add for this node. * @param extraCordappPackages Extra CorDapp packages to add for this node.
*/ */
@JvmOverloads @JvmOverloads
fun createNode(legalName: CordaX500Name? = null, fun createNode(legalName: CordaX500Name? = null,
forcedID: Int? = null, forcedID: Int? = null,
entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
configOverrides: (NodeConfiguration) -> Any? = {}, configOverrides: MockNodeConfigOverrides? = null,
extraCordappPackages: List<String> = emptyList() extraCordappPackages: List<String> = emptyList()
): StartedMockNode ): StartedMockNode
@ -194,8 +194,9 @@ provide different parameters to each node using the following methods on ``MockN
fun createNode(parameters: MockNodeParameters = MockNodeParameters()): StartedMockNode fun createNode(parameters: MockNodeParameters = MockNodeParameters()): StartedMockNode
As you can see above, parameters can be added individually or encapsulated within a ``MockNodeParameters`` object. Of As you can see above, parameters can be added individually or encapsulated within a ``MockNodeParameters`` object. Of
particular interest are ``configOverrides`` which allow you to override any default config option specified within the particular interest are ``configOverrides`` which allow you to override some of the default node
``NodeConfiguration`` object. Also, the ``extraCordappPackages`` parameter allows you to add extra CorDapps to a configuration options. Please refer to the ``MockNodeConfigOverrides`` class for details what can currently be overridden.
Also, the ``extraCordappPackages`` parameter allows you to add extra CorDapps to a
specific node. This is useful when you wish for all nodes to load a common CorDapp but for a subset of nodes to load specific node. This is useful when you wish for all nodes to load a common CorDapp but for a subset of nodes to load
CorDapps specific to their role in the network. CorDapps specific to their role in the network.

View File

@ -84,6 +84,9 @@ For H2:
No action is needed for default node tables as ``PersistentStateRef`` is used as Primary Key only and the backing columns are automatically not nullable No action is needed for default node tables as ``PersistentStateRef`` is used as Primary Key only and the backing columns are automatically not nullable
or custom Cordapp entities using ``PersistentStateRef`` as Primary Key. or custom Cordapp entities using ``PersistentStateRef`` as Primary Key.
* MockNetwork: ``MockNodeParameters`` and functions creating it no longer use a lambda expecting a ``NodeConfiguration``
object. Use a ``MockNetworkConfigOverrides`` object instead.
V3.2 to v3.3 V3.2 to v3.3
------------ ------------

View File

@ -1,7 +1,5 @@
package net.corda.notary.bftsmart package net.corda.notary.bftsmart
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import net.corda.core.contracts.ContractState import net.corda.core.contracts.ContractState
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
@ -21,7 +19,6 @@ import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.Try import net.corda.core.utilities.Try
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.services.config.NotaryConfig
import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.DevIdentityGenerator
import net.corda.nodeapi.internal.config.toConfig import net.corda.nodeapi.internal.config.toConfig
import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NetworkParametersCopier
@ -29,6 +26,8 @@ import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.dummyCommand import net.corda.testing.core.dummyCommand
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.node.MockNetNotaryConfig
import net.corda.testing.node.MockNodeConfigOverrides
import net.corda.testing.node.TestClock import net.corda.testing.node.TestClock
import net.corda.testing.node.internal.* import net.corda.testing.node.internal.*
import org.hamcrest.Matchers.instanceOf import org.hamcrest.Matchers.instanceOf
@ -81,15 +80,12 @@ class BFTNotaryServiceTests {
val clusterAddresses = replicaIds.map { NetworkHostAndPort("localhost", 11000 + it * 10) } val clusterAddresses = replicaIds.map { NetworkHostAndPort("localhost", 11000 + it * 10) }
val nodes = replicaIds.map { replicaId -> val nodes = replicaIds.map { replicaId ->
mockNet.createUnstartedNode(InternalMockNodeParameters(configOverrides = { mockNet.createUnstartedNode(InternalMockNodeParameters(configOverrides = MockNodeConfigOverrides(notary = MockNetNotaryConfig(
val notary = NotaryConfig(
validating = false, validating = false,
extraConfig = BFTSMaRtConfiguration(replicaId, clusterAddresses, exposeRaces = exposeRaces).toConfig(), extraConfig = BFTSMaRtConfiguration(replicaId, clusterAddresses, exposeRaces = exposeRaces).toConfig(),
className = "net.corda.notary.bftsmart.BftSmartNotaryService", className = "net.corda.notary.bftsmart.BftSmartNotaryService",
serviceLegalName = serviceLegalName serviceLegalName = serviceLegalName
) ))))
doReturn(notary).whenever(it).notary
}))
} + mockNet.createUnstartedNode() } + mockNet.createUnstartedNode()
// MockNetwork doesn't support BFT clusters, so we create all the nodes we need unstarted, and then install the // MockNetwork doesn't support BFT clusters, so we create all the nodes we need unstarted, and then install the

View File

@ -9,6 +9,7 @@ import net.corda.finance.flows.CashException
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeConfigOverrides
import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.MockNodeParameters
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.After import org.junit.After
@ -39,10 +40,10 @@ class CashSelectionH2ImplTest {
@Test @Test
fun `check does not hold connection over retries`() { fun `check does not hold connection over retries`() {
val bankA = mockNet.createNode(MockNodeParameters(configOverrides = { val bankA = mockNet.createNode(MockNodeParameters(
// Tweak connections to be minimal to make this easier (1 results in a hung node during start up, so use 2 connections). // Tweak connections to be minimal to make this easier (1 results in a hung node during start up, so use 2 connections).
it.dataSourceProperties.setProperty("maximumPoolSize", "2") configOverrides = MockNodeConfigOverrides(extraDataSourceProperties = mapOf("maximumPoolSize" to "2"))
})) ))
val notary = mockNet.defaultNotaryIdentity val notary = mockNet.defaultNotaryIdentity
// Start more cash spends than we have connections. If spend leaks a connection on retry, we will run out of connections. // Start more cash spends than we have connections. If spend leaks a connection on retry, we will run out of connections.

View File

@ -1,24 +1,24 @@
package net.corda.node.internal package net.corda.node.internal
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.crypto.generateKeyPair import net.corda.core.crypto.generateKeyPair
import net.corda.core.node.JavaPackageName import net.corda.core.node.JavaPackageName
import net.corda.core.node.NetworkParameters
import net.corda.core.node.NotaryInfo
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.days
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.node.services.config.NotaryConfig
import net.corda.core.node.NetworkParameters
import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.core.node.NotaryInfo import net.corda.testing.common.internal.testNetworkParameters
import net.corda.core.utilities.days
import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.node.MockNetNotaryConfig
import net.corda.testing.node.* import net.corda.testing.node.MockNetworkNotarySpec
import net.corda.testing.node.MockNetworkParameters
import net.corda.testing.node.MockNodeConfigOverrides
import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNodeParameters import net.corda.testing.node.internal.InternalMockNodeParameters
import net.corda.testing.node.internal.MOCK_VERSION_INFO import net.corda.testing.node.internal.MOCK_VERSION_INFO
@ -66,10 +66,8 @@ class NetworkParametersTest {
// Notaries tests // Notaries tests
@Test @Test
fun `choosing notary not specified in network parameters will fail`() { fun `choosing notary not specified in network parameters will fail`() {
val fakeNotary = mockNet.createNode(InternalMockNodeParameters(legalName = BOB_NAME, configOverrides = { val fakeNotary = mockNet.createNode(InternalMockNodeParameters(legalName = BOB_NAME,
val notary = NotaryConfig(false) configOverrides = MockNodeConfigOverrides(notary = MockNetNotaryConfig(validating = false))))
doReturn(notary).whenever(it).notary
}))
val fakeNotaryId = fakeNotary.info.singleIdentity() val fakeNotaryId = fakeNotary.info.singleIdentity()
val alice = mockNet.createPartyNode(ALICE_NAME) val alice = mockNet.createPartyNode(ALICE_NAME)
assertThat(alice.services.networkMapCache.notaryIdentities).doesNotContain(fakeNotaryId) assertThat(alice.services.networkMapCache.notaryIdentities).doesNotContain(fakeNotaryId)

View File

@ -1,9 +1,6 @@
package net.corda.node.services package net.corda.node.services
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
@ -25,9 +22,6 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.config.FlowTimeoutConfiguration
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.DevIdentityGenerator
import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
@ -35,8 +29,7 @@ import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.dummyCommand import net.corda.testing.core.dummyCommand
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.internal.LogHelper import net.corda.testing.internal.LogHelper
import net.corda.testing.node.InMemoryMessagingNetwork import net.corda.testing.node.*
import net.corda.testing.node.MockNetworkParameters
import net.corda.testing.node.internal.* import net.corda.testing.node.internal.*
import org.junit.AfterClass import org.junit.AfterClass
import org.junit.Before import org.junit.Before
@ -90,25 +83,22 @@ class TimedFlowTests {
serviceLegalName) serviceLegalName)
val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notaryIdentity, true)))) val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notaryIdentity, true))))
val notaryConfig = mock<NotaryConfig> { val notaryConfig = MockNetNotaryConfig(
whenever(it.serviceLegalName).thenReturn(serviceLegalName) serviceLegalName = serviceLegalName,
whenever(it.validating).thenReturn(true) validating = true,
whenever(it.className).thenReturn(TestNotaryService::class.java.name) className = TestNotaryService::class.java.name
} )
val notaryNodes = (0 until CLUSTER_SIZE).map { val notaryNodes = (0 until CLUSTER_SIZE).map {
mockNet.createUnstartedNode(InternalMockNodeParameters(configOverrides = { mockNet.createUnstartedNode(InternalMockNodeParameters(configOverrides = MockNodeConfigOverrides(
doReturn(notaryConfig).whenever(it).notary notary = notaryConfig
})) )))
} }
val aliceNode = mockNet.createUnstartedNode( val aliceNode = mockNet.createUnstartedNode(
InternalMockNodeParameters( InternalMockNodeParameters(
legalName = CordaX500Name("Alice", "AliceCorp", "GB"), legalName = CordaX500Name("Alice", "AliceCorp", "GB"),
configOverrides = { conf: NodeConfiguration -> configOverrides = MockNodeConfigOverrides(flowTimeout = MockNetFlowTimeOut(1.seconds, 3, 1.0))
val retryConfig = FlowTimeoutConfiguration(1.seconds, 3, 1.0)
doReturn(retryConfig).whenever(conf).flowTimeout
}
) )
) )

View File

@ -1,8 +1,6 @@
package net.corda.node.services.statemachine package net.corda.node.services.statemachine
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.InitiatingFlow
@ -11,8 +9,8 @@ import net.corda.core.internal.IdempotentFlow
import net.corda.core.internal.TimedFlow import net.corda.core.internal.TimedFlow
import net.corda.core.internal.packageName import net.corda.core.internal.packageName
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.services.config.FlowTimeoutConfiguration import net.corda.testing.node.MockNetFlowTimeOut
import net.corda.node.services.config.NodeConfiguration import net.corda.testing.node.MockNodeConfigOverrides
import net.corda.testing.node.internal.* import net.corda.testing.node.internal.*
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -37,11 +35,7 @@ class IdempotentFlowTests {
mockNet = InternalMockNetwork(threadPerNode = true, cordappsForAllNodes = cordappsForPackages(this.javaClass.packageName)) mockNet = InternalMockNetwork(threadPerNode = true, cordappsForAllNodes = cordappsForPackages(this.javaClass.packageName))
nodeA = mockNet.createNode(InternalMockNodeParameters( nodeA = mockNet.createNode(InternalMockNodeParameters(
legalName = CordaX500Name("Alice", "AliceCorp", "GB"), legalName = CordaX500Name("Alice", "AliceCorp", "GB"),
configOverrides = { configOverrides = MockNodeConfigOverrides(flowTimeout = MockNetFlowTimeOut(1.seconds, 3, 1.0))
conf: NodeConfiguration ->
val retryConfig = FlowTimeoutConfiguration(1.seconds, 3, 1.0)
doReturn(retryConfig).whenever(conf).flowTimeout
}
)) ))
nodeB = mockNet.createNode() nodeB = mockNet.createNode()
mockNet.startNodes() mockNet.startNodes()

View File

@ -22,6 +22,7 @@ import java.math.BigInteger
import java.nio.file.Path import java.nio.file.Path
import java.util.concurrent.Future import java.util.concurrent.Future
/** /**
* Immutable builder for configuring a [StartedMockNode] or an [UnstartedMockNode] via [MockNetwork.createNode] and * Immutable builder for configuring a [StartedMockNode] or an [UnstartedMockNode] via [MockNetwork.createNode] and
* [MockNetwork.createUnstartedNode]. Kotlin users can also use the named parameters overloads of those methods which * [MockNetwork.createUnstartedNode]. Kotlin users can also use the named parameters overloads of those methods which
@ -40,21 +41,21 @@ data class MockNodeParameters(
val forcedID: Int? = null, val forcedID: Int? = null,
val legalName: CordaX500Name? = null, val legalName: CordaX500Name? = null,
val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
val configOverrides: (NodeConfiguration) -> Any? = {}, val configOverrides: MockNodeConfigOverrides? = null,
val additionalCordapps: Collection<TestCordapp> = emptyList()) { val additionalCordapps: Collection<TestCordapp> = emptyList()) {
constructor(forcedID: Int? = null, constructor(forcedID: Int? = null,
legalName: CordaX500Name? = null, legalName: CordaX500Name? = null,
entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
configOverrides: (NodeConfiguration) -> Any? = {} configOverrides: MockNodeConfigOverrides
) : this(forcedID, legalName, entropyRoot, configOverrides, emptyList()) ) : this(forcedID, legalName, entropyRoot, configOverrides, emptyList())
fun withForcedID(forcedID: Int?): MockNodeParameters = copy(forcedID = forcedID) fun withForcedID(forcedID: Int?): MockNodeParameters = copy(forcedID = forcedID)
fun withLegalName(legalName: CordaX500Name?): MockNodeParameters = copy(legalName = legalName) fun withLegalName(legalName: CordaX500Name?): MockNodeParameters = copy(legalName = legalName)
fun withEntropyRoot(entropyRoot: BigInteger): MockNodeParameters = copy(entropyRoot = entropyRoot) fun withEntropyRoot(entropyRoot: BigInteger): MockNodeParameters = copy(entropyRoot = entropyRoot)
fun withConfigOverrides(configOverrides: (NodeConfiguration) -> Any?): MockNodeParameters = copy(configOverrides = configOverrides) fun withConfigOverrides(configOverrides: MockNodeConfigOverrides): MockNodeParameters = copy(configOverrides = configOverrides)
fun withAdditionalCordapps(additionalCordapps: Collection<TestCordapp>): MockNodeParameters = copy(additionalCordapps = additionalCordapps) fun withAdditionalCordapps(additionalCordapps: Collection<TestCordapp>): MockNodeParameters = copy(additionalCordapps = additionalCordapps)
fun copy(forcedID: Int?, legalName: CordaX500Name?, entropyRoot: BigInteger, configOverrides: (NodeConfiguration) -> Any?): MockNodeParameters { fun copy(forcedID: Int?, legalName: CordaX500Name?, entropyRoot: BigInteger, configOverrides: MockNodeConfigOverrides): MockNodeParameters {
return MockNodeParameters(forcedID, legalName, entropyRoot, configOverrides) return MockNodeParameters(forcedID, legalName, entropyRoot, configOverrides)
} }
} }
@ -344,14 +345,14 @@ open class MockNetwork(
* @param forcedID A unique identifier for the node. * @param forcedID A unique identifier for the node.
* @param entropyRoot The initial entropy value to use when generating keys. Defaults to an (insecure) random value, * @param entropyRoot The initial entropy value to use when generating keys. Defaults to an (insecure) random value,
* but can be overridden to cause nodes to have stable or colliding identity/service keys. * 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. * @param configOverrides Add/override the default configuration/behaviour of the node
* @param extraCordappPackages Extra CorDapp packages to add for this node. * @param extraCordappPackages Extra CorDapp packages to add for this node.
*/ */
@JvmOverloads @JvmOverloads
fun createNode(legalName: CordaX500Name? = null, fun createNode(legalName: CordaX500Name? = null,
forcedID: Int? = null, forcedID: Int? = null,
entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
configOverrides: (NodeConfiguration) -> Any? = {}, configOverrides: MockNodeConfigOverrides? = null,
extraCordappPackages: List<String> = emptyList()): StartedMockNode { extraCordappPackages: List<String> = emptyList()): StartedMockNode {
return createNode(legalName, forcedID, entropyRoot, configOverrides, cordappsForPackages(extraCordappPackages)) return createNode(legalName, forcedID, entropyRoot, configOverrides, cordappsForPackages(extraCordappPackages))
@ -370,7 +371,7 @@ open class MockNetwork(
fun createNode(legalName: CordaX500Name? = null, fun createNode(legalName: CordaX500Name? = null,
forcedID: Int? = null, forcedID: Int? = null,
entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
configOverrides: (NodeConfiguration) -> Any? = {}, configOverrides: MockNodeConfigOverrides? = null,
additionalCordapps: Collection<TestCordapp>): StartedMockNode { additionalCordapps: Collection<TestCordapp>): StartedMockNode {
val parameters = MockNodeParameters(forcedID, legalName, entropyRoot, configOverrides, additionalCordapps) val parameters = MockNodeParameters(forcedID, legalName, entropyRoot, configOverrides, additionalCordapps)
return StartedMockNode.create(internalMockNetwork.createNode(InternalMockNodeParameters(parameters))) return StartedMockNode.create(internalMockNetwork.createNode(InternalMockNodeParameters(parameters)))
@ -393,7 +394,7 @@ open class MockNetwork(
fun createUnstartedNode(legalName: CordaX500Name? = null, fun createUnstartedNode(legalName: CordaX500Name? = null,
forcedID: Int? = null, forcedID: Int? = null,
entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
configOverrides: (NodeConfiguration) -> Any? = {}, configOverrides: MockNodeConfigOverrides? = null,
extraCordappPackages: List<String> = emptyList()): UnstartedMockNode { extraCordappPackages: List<String> = emptyList()): UnstartedMockNode {
return createUnstartedNode(legalName, forcedID, entropyRoot, configOverrides, cordappsForPackages(extraCordappPackages)) return createUnstartedNode(legalName, forcedID, entropyRoot, configOverrides, cordappsForPackages(extraCordappPackages))
@ -412,7 +413,7 @@ open class MockNetwork(
fun createUnstartedNode(legalName: CordaX500Name? = null, fun createUnstartedNode(legalName: CordaX500Name? = null,
forcedID: Int? = null, forcedID: Int? = null,
entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
configOverrides: (NodeConfiguration) -> Any? = {}, configOverrides: MockNodeConfigOverrides? = null,
additionalCordapps: Collection<TestCordapp>): UnstartedMockNode { additionalCordapps: Collection<TestCordapp>): UnstartedMockNode {
val parameters = MockNodeParameters(forcedID, legalName, entropyRoot, configOverrides, additionalCordapps) val parameters = MockNodeParameters(forcedID, legalName, entropyRoot, configOverrides, additionalCordapps)
return UnstartedMockNode.create(internalMockNetwork.createUnstartedNode(InternalMockNodeParameters(parameters))) return UnstartedMockNode.create(internalMockNetwork.createUnstartedNode(InternalMockNodeParameters(parameters)))

View File

@ -0,0 +1,34 @@
package net.corda.testing.node
import com.typesafe.config.Config
import net.corda.core.identity.CordaX500Name
import java.time.Duration
/**
* This is a data class to configure overrides to the node configuration used in the mock network
* without having to expose/use the actual (internal) node configuration interface on the API.
* When passing one of these to [createNode] or [createUnstartedNode] functions, the bits that are
* set will be injected into the node configuration for the node to be created.
*/
data class MockNodeConfigOverrides(
val extraDataSourceProperties: Map<String, String>? = null,
val notary: MockNetNotaryConfig? = null,
val flowTimeout: MockNetFlowTimeOut? = null)
/**
* MockNetNotaryConfig can be used to configure a node to be a notary via the mock network API. Internally
* this will be translated into a NotaryConfiguration and passed to the respective node.
*/
data class MockNetNotaryConfig(
val validating: Boolean,
val extraConfig: Config? = null,
val className: String? = null,
val serviceLegalName: CordaX500Name? = null)
/**
* MockNetFlowTimeOut can be used to configure flow time out settings for a node via the mock network API.
*/
data class MockNetFlowTimeOut(
val timeout: Duration,
val maxRestartCount: Int,
val backoffBase: Double)

View File

@ -36,7 +36,6 @@ import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.api.StartedNodeServices
import net.corda.node.services.config.FlowTimeoutConfiguration import net.corda.node.services.config.FlowTimeoutConfiguration
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.config.VerifierType import net.corda.node.services.config.VerifierType
import net.corda.node.services.identity.PersistentIdentityService import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.services.keys.E2ETestKeyManagementService import net.corda.node.services.keys.E2ETestKeyManagementService
@ -89,7 +88,7 @@ data class InternalMockNodeParameters(
val forcedID: Int? = null, val forcedID: Int? = null,
val legalName: CordaX500Name? = null, val legalName: CordaX500Name? = null,
val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
val configOverrides: (NodeConfiguration) -> Any? = {}, val configOverrides: MockNodeConfigOverrides? = null,
val version: VersionInfo = MOCK_VERSION_INFO, val version: VersionInfo = MOCK_VERSION_INFO,
val additionalCordapps: Collection<TestCordapp>? = null, val additionalCordapps: Collection<TestCordapp>? = null,
val flowManager: MockNodeFlowManager = MockNodeFlowManager()) { val flowManager: MockNodeFlowManager = MockNodeFlowManager()) {
@ -257,7 +256,7 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe
return notarySpecs.map { (name, validating) -> return notarySpecs.map { (name, validating) ->
createNode(InternalMockNodeParameters( createNode(InternalMockNodeParameters(
legalName = name, legalName = name,
configOverrides = { doReturn(NotaryConfig(validating)).whenever(it).notary }, configOverrides = MockNodeConfigOverrides(notary = MockNetNotaryConfig(validating)),
version = version version = version
)) ))
} }
@ -463,7 +462,7 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe
doReturn(parameters.legalName ?: CordaX500Name("Mock Company $id", "London", "GB")).whenever(it).myLegalName doReturn(parameters.legalName ?: CordaX500Name("Mock Company $id", "London", "GB")).whenever(it).myLegalName
doReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")).whenever(it).dataSourceProperties doReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")).whenever(it).dataSourceProperties
doReturn(emptyList<SecureHash>()).whenever(it).extraNetworkMapKeys doReturn(emptyList<SecureHash>()).whenever(it).extraNetworkMapKeys
parameters.configOverrides(it) parameters.configOverrides?.applyMockNodeOverrides(it)
} }
val cordapps = (parameters.additionalCordapps ?: emptySet()) + cordappsForAllNodes val cordapps = (parameters.additionalCordapps ?: emptySet()) + cordappsForAllNodes
@ -630,4 +629,5 @@ class MockNodeFlowManager : NodeFlowManager() {
fun registerTestingFactory(initiator: Class<out FlowLogic<*>>, factory: InitiatedFlowFactory<*>) { fun registerTestingFactory(initiator: Class<out FlowLogic<*>>, factory: InitiatedFlowFactory<*>) {
testingRegistrations.put(initiator, factory) testingRegistrations.put(initiator, factory)
} }
} }

View File

@ -0,0 +1,25 @@
package net.corda.testing.node.internal
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.node.services.config.FlowTimeoutConfiguration
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.testing.node.MockNetNotaryConfig
import net.corda.testing.node.MockNodeConfigOverrides
fun MockNetNotaryConfig.toNotaryConfig(): NotaryConfig {
return if (this.className == null) {
NotaryConfig(validating = this.validating, extraConfig = this.extraConfig, serviceLegalName = this.serviceLegalName)
} else {
NotaryConfig(validating = this.validating, extraConfig = this.extraConfig, serviceLegalName = this.serviceLegalName, className = this.className)
}
}
fun MockNodeConfigOverrides.applyMockNodeOverrides(config: NodeConfiguration) {
config.also {
this.notary?.also { n -> doReturn(n.toNotaryConfig()).whenever(it).notary }
this.extraDataSourceProperties?.forEach { k, v -> it.dataSourceProperties.put(k, v) }
this.flowTimeout?.also { fto -> doReturn(FlowTimeoutConfiguration(fto.timeout, fto.maxRestartCount, fto.backoffBase)).whenever(config).flowTimeout }
}
}