Adds a builder for configuring nodes in the driver for Java interop.

This commit is contained in:
joeldudleyr3 2017-09-01 16:45:00 +01:00
parent 78dd62359a
commit 83d0095142
22 changed files with 105 additions and 67 deletions

View File

@ -58,13 +58,13 @@ class NodeMonitorModelTest : DriverBasedTest() {
startFlowPermission<CashPaymentFlow>(), startFlowPermission<CashPaymentFlow>(),
startFlowPermission<CashExitFlow>()) startFlowPermission<CashExitFlow>())
) )
val aliceNodeFuture = startNode(ALICE.name, rpcUsers = listOf(cashUser)) val aliceNodeFuture = startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser))
val notaryNodeFuture = startNode(DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val notaryNodeFuture = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
val aliceNodeHandle = aliceNodeFuture.getOrThrow() val aliceNodeHandle = aliceNodeFuture.getOrThrow()
val notaryNodeHandle = notaryNodeFuture.getOrThrow() val notaryNodeHandle = notaryNodeFuture.getOrThrow()
aliceNode = aliceNodeHandle.nodeInfo aliceNode = aliceNodeHandle.nodeInfo
notaryNode = notaryNodeHandle.nodeInfo notaryNode = notaryNodeHandle.nodeInfo
newNode = { nodeName -> startNode(nodeName).getOrThrow().nodeInfo } newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
val monitor = NodeMonitorModel() val monitor = NodeMonitorModel()
stateMachineTransactionMapping = monitor.stateMachineTransactionMapping.bufferUntilSubscribed() stateMachineTransactionMapping = monitor.stateMachineTransactionMapping.bufferUntilSubscribed()
stateMachineUpdates = monitor.stateMachineUpdates.bufferUntilSubscribed() stateMachineUpdates = monitor.stateMachineUpdates.bufferUntilSubscribed()
@ -76,7 +76,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password, initialiseSerialization = false) monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password, initialiseSerialization = false)
rpc = monitor.proxyObservable.value!! rpc = monitor.proxyObservable.value!!
val bobNodeHandle = startNode(BOB.name, rpcUsers = listOf(cashUser)).getOrThrow() val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow()
bobNode = bobNodeHandle.nodeInfo bobNode = bobNodeHandle.nodeInfo
val monitorBob = NodeMonitorModel() val monitorBob = NodeMonitorModel()
stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed() stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed()

View File

@ -32,9 +32,9 @@ class IntegrationTestingTutorial {
startFlowPermission<CashPaymentFlow>() startFlowPermission<CashPaymentFlow>()
)) ))
val (alice, bob, notary) = listOf( val (alice, bob, notary) = listOf(
startNode(ALICE.name, rpcUsers = listOf(aliceUser)), startNode(providedName = ALICE.name, rpcUsers = listOf(aliceUser)),
startNode(BOB.name, rpcUsers = listOf(bobUser)), startNode(providedName = BOB.name, rpcUsers = listOf(bobUser)),
startNode(DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type))) startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type)))
).transpose().getOrThrow() ).transpose().getOrThrow()
// END 1 // END 1

View File

@ -49,8 +49,8 @@ fun main(args: Array<String>) {
startFlowPermission<CashExitFlow>())) startFlowPermission<CashExitFlow>()))
driver(driverDirectory = baseDirectory) { driver(driverDirectory = baseDirectory) {
startNode(DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type))) startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type)))
val node = startNode(ALICE.name, rpcUsers = listOf(user)).get() val node = startNode(providedName = ALICE.name, rpcUsers = listOf(user)).get()
// END 1 // END 1
// START 2 // START 2

View File

@ -41,12 +41,12 @@ class BootTests {
val logConfigFile = projectRootDir / "config" / "dev" / "log4j2.xml" val logConfigFile = projectRootDir / "config" / "dev" / "log4j2.xml"
assertThat(logConfigFile).isRegularFile() assertThat(logConfigFile).isRegularFile()
driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) { driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) {
val alice = startNode(ALICE.name).get() val alice = startNode(providedName = ALICE.name).get()
val logFolder = alice.configuration.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME val logFolder = alice.configuration.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
val logFile = logFolder.toFile().listFiles { _, name -> name.endsWith(".log") }.single() val logFile = logFolder.toFile().listFiles { _, name -> name.endsWith(".log") }.single()
// Start second Alice, should fail // Start second Alice, should fail
assertThatThrownBy { assertThatThrownBy {
startNode(ALICE.name).getOrThrow() startNode(providedName = ALICE.name).getOrThrow()
} }
// We count the number of nodes that wrote into the logfile by counting "Logs can be found in" // We count the number of nodes that wrote into the logfile by counting "Logs can be found in"
val numberOfNodesThatLogged = Files.lines(logFile.toPath()).filter { NodeStartup.LOGS_CAN_BE_FOUND_IN_STRING in it }.count() val numberOfNodesThatLogged = Files.lines(logFile.toPath()).filter { NodeStartup.LOGS_CAN_BE_FOUND_IN_STRING in it }.count()
@ -58,7 +58,7 @@ class BootTests {
fun `node quits on failure to register with network map`() { fun `node quits on failure to register with network map`() {
val tooManyAdvertisedServices = (1..100).map { ServiceInfo(ServiceType.regulator.getSubType("$it")) }.toSet() val tooManyAdvertisedServices = (1..100).map { ServiceInfo(ServiceType.regulator.getSubType("$it")) }.toSet()
driver(networkMapStartStrategy = NetworkMapStartStrategy.Nominated(ALICE.name)) { driver(networkMapStartStrategy = NetworkMapStartStrategy.Nominated(ALICE.name)) {
val future = startNode(ALICE.name, advertisedServices = tooManyAdvertisedServices) val future = startNode(providedName = ALICE.name, advertisedServices = tooManyAdvertisedServices)
assertFailsWith(ListenProcessDeathException::class) { future.getOrThrow() } assertFailsWith(ListenProcessDeathException::class) { future.getOrThrow() }
} }
} }

View File

@ -25,8 +25,8 @@ class CordappScanningDriverTest {
// The driver will automatically pick up the annotated flows below // The driver will automatically pick up the annotated flows below
driver { driver {
val (alice, bob) = listOf( val (alice, bob) = listOf(
startNode(ALICE.name, rpcUsers = listOf(user)), startNode(providedName = ALICE.name, rpcUsers = listOf(user)),
startNode(BOB.name)).transpose().getOrThrow() startNode(providedName = BOB.name)).transpose().getOrThrow()
val initiatedFlowClass = alice.rpcClientToNode() val initiatedFlowClass = alice.rpcClientToNode()
.start(user.username, user.password) .start(user.username, user.password)
.proxy .proxy

View File

@ -38,7 +38,7 @@ class DistributedServiceTests : DriverBasedTest() {
startFlowPermission<CashIssueFlow>(), startFlowPermission<CashIssueFlow>(),
startFlowPermission<CashPaymentFlow>()) startFlowPermission<CashPaymentFlow>())
) )
val aliceFuture = startNode(ALICE.name, rpcUsers = listOf(testUser)) val aliceFuture = startNode(providedName = ALICE.name, rpcUsers = listOf(testUser))
val notariesFuture = startNotaryCluster( val notariesFuture = startNotaryCluster(
DUMMY_NOTARY.name, DUMMY_NOTARY.name,
rpcUsers = listOf(testUser), rpcUsers = listOf(testUser),

View File

@ -20,9 +20,9 @@ class AttachmentDemoTest {
driver(dsl = { driver(dsl = {
val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission<AttachmentDemoFlow>()))) val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission<AttachmentDemoFlow>())))
val (nodeA, nodeB) = listOf( val (nodeA, nodeB) = listOf(
startNode(DUMMY_BANK_A.name, rpcUsers = demoUser), startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser),
startNode(DUMMY_BANK_B.name, rpcUsers = demoUser), startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser),
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type))) startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
).transpose().getOrThrow() ).transpose().getOrThrow()
val senderThread = CompletableFuture.supplyAsync { val senderThread = CompletableFuture.supplyAsync {

View File

@ -16,9 +16,9 @@ import net.corda.testing.driver.driver
fun main(args: Array<String>) { fun main(args: Array<String>) {
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow"))) val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
driver(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes") { driver(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes") {
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type))) startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
startNode(DUMMY_BANK_A.name, rpcUsers = demoUser) startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser)
startNode(DUMMY_BANK_B.name, rpcUsers = demoUser) startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser)
waitForAllNodesToFinish() waitForAllNodesToFinish()
} }
} }

View File

@ -16,8 +16,8 @@ class BankOfCordaHttpAPITest {
fun `issuer flow via Http`() { fun `issuer flow via Http`() {
driver(dsl = { driver(dsl = {
val (nodeBankOfCorda) = listOf( val (nodeBankOfCorda) = listOf(
startNode(BOC.name, setOf(ServiceInfo(SimpleNotaryService.type))), startNode(providedName = BOC.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))),
startNode(BIGCORP_LEGAL_NAME) startNode(providedName = BIGCORP_LEGAL_NAME)
).transpose().getOrThrow() ).transpose().getOrThrow()
val anonymous = false val anonymous = false
val nodeBankOfCordaApiAddr = startWebserver(nodeBankOfCorda).getOrThrow().listenAddress val nodeBankOfCordaApiAddr = startWebserver(nodeBankOfCorda).getOrThrow().listenAddress

View File

@ -24,8 +24,10 @@ class BankOfCordaRPCClientTest {
startFlowPermission<CashIssueAndPaymentFlow>())) startFlowPermission<CashIssueAndPaymentFlow>()))
val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet()) val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet())
val (nodeBankOfCorda, nodeBigCorporation) = listOf( val (nodeBankOfCorda, nodeBigCorporation) = listOf(
startNode(BOC.name, setOf(ServiceInfo(SimpleNotaryService.type)), listOf(bocManager)), startNode(providedName = BOC.name,
startNode(BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpCFO)) advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)),
rpcUsers = listOf(bocManager)),
startNode(providedName = BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpCFO))
).transpose().getOrThrow() ).transpose().getOrThrow()
// Bank of Corda RPC Client // Bank of Corda RPC Client

View File

@ -71,12 +71,13 @@ private class BankOfCordaDriver {
val bigCorpUser = User(BIGCORP_USERNAME, "test", val bigCorpUser = User(BIGCORP_USERNAME, "test",
permissions = setOf( permissions = setOf(
startFlowPermission<CashPaymentFlow>())) startFlowPermission<CashPaymentFlow>()))
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type))) startNode(providedName = DUMMY_NOTARY.name,
advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
val bankOfCorda = startNode( val bankOfCorda = startNode(
BOC.name, providedName = BOC.name,
rpcUsers = listOf(bankUser), rpcUsers = listOf(bankUser),
advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.USD")))) advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.USD"))))
startNode(BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpUser)) startNode(providedName = BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpUser))
startWebserver(bankOfCorda.get()) startWebserver(bankOfCorda.get())
waitForAllNodesToFinish() waitForAllNodesToFinish()
}, isDebug = true) }, isDebug = true)

View File

@ -45,9 +45,9 @@ class IRSDemoTest : IntegrationTestCategory {
fun `runs IRS demo`() { fun `runs IRS demo`() {
driver(useTestClock = true, isDebug = true) { driver(useTestClock = true, isDebug = true) {
val (controller, nodeA, nodeB) = listOf( val (controller, nodeA, nodeB) = listOf(
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.Oracle.type))), startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.Oracle.type))),
startNode(DUMMY_BANK_A.name, rpcUsers = listOf(rpcUser)), startNode(providedName = DUMMY_BANK_A.name, rpcUsers = listOf(rpcUser)),
startNode(DUMMY_BANK_B.name) startNode(providedName = DUMMY_BANK_B.name)
).transpose().getOrThrow() ).transpose().getOrThrow()
log.info("All nodes started") log.info("All nodes started")

View File

@ -17,9 +17,9 @@ import net.corda.testing.driver.driver
fun main(args: Array<String>) { fun main(args: Array<String>) {
driver(dsl = { driver(dsl = {
val (controller, nodeA, nodeB) = listOf( val (controller, nodeA, nodeB) = listOf(
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.Oracle.type))), startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.Oracle.type))),
startNode(DUMMY_BANK_A.name), startNode(providedName = DUMMY_BANK_A.name),
startNode(DUMMY_BANK_B.name) startNode(providedName = DUMMY_BANK_B.name)
).transpose().getOrThrow() ).transpose().getOrThrow()
startWebserver(controller) startWebserver(controller)

View File

@ -33,8 +33,8 @@ class SimmValuationTest : IntegrationTestCategory {
@Test @Test
fun `runs SIMM valuation demo`() { fun `runs SIMM valuation demo`() {
driver(isDebug = true) { driver(isDebug = true) {
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type))).getOrThrow() startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))).getOrThrow()
val (nodeA, nodeB) = listOf(startNode(nodeALegalName), startNode(nodeBLegalName)).transpose().getOrThrow() val (nodeA, nodeB) = listOf(startNode(providedName = nodeALegalName), startNode(providedName = nodeBLegalName)).transpose().getOrThrow()
val (nodeAApi, nodeBApi) = listOf(startWebserver(nodeA), startWebserver(nodeB)).transpose() val (nodeAApi, nodeBApi) = listOf(startWebserver(nodeA), startWebserver(nodeB)).transpose()
.getOrThrow() .getOrThrow()
.map { HttpApi.fromHostAndPort(it.listenAddress, "api/simmvaluationdemo") } .map { HttpApi.fromHostAndPort(it.listenAddress, "api/simmvaluationdemo") }

View File

@ -17,11 +17,11 @@ import net.corda.testing.driver.driver
*/ */
fun main(args: Array<String>) { fun main(args: Array<String>) {
driver(dsl = { driver(dsl = {
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type))) startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
val (nodeA, nodeB, nodeC) = listOf( val (nodeA, nodeB, nodeC) = listOf(
startNode(DUMMY_BANK_A.name), startNode(providedName = DUMMY_BANK_A.name),
startNode(DUMMY_BANK_B.name), startNode(providedName = DUMMY_BANK_B.name),
startNode(DUMMY_BANK_C.name) startNode(providedName = DUMMY_BANK_C.name)
).transpose().getOrThrow() ).transpose().getOrThrow()
startWebserver(nodeA) startWebserver(nodeA)

View File

@ -27,10 +27,10 @@ fun main(args: Array<String>) {
val user = User("user1", "test", permissions = setOf(startFlowPermission<CashIssueFlow>(), val user = User("user1", "test", permissions = setOf(startFlowPermission<CashIssueFlow>(),
startFlowPermission<CommercialPaperIssueFlow>(), startFlowPermission<CommercialPaperIssueFlow>(),
startFlowPermission<SellerFlow>())) startFlowPermission<SellerFlow>()))
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type))) startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
startNode(DUMMY_BANK_A.name, rpcUsers = demoUser) startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser)
startNode(DUMMY_BANK_B.name, rpcUsers = demoUser) startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser)
startNode(BOC.name, rpcUsers = listOf(user)) startNode(providedName = BOC.name, rpcUsers = listOf(user))
waitForAllNodesToFinish() waitForAllNodesToFinish()
} }
} }

View File

@ -41,8 +41,8 @@ class DriverTests {
@Test @Test
fun `simple node startup and shutdown`() { fun `simple node startup and shutdown`() {
val handles = driver { val handles = driver {
val notary = startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type))) val notary = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
val regulator = startNode(DUMMY_REGULATOR.name, setOf(ServiceInfo(RegulatorService.type))) val regulator = startNode(providedName = DUMMY_REGULATOR.name, advertisedServices = setOf(ServiceInfo(RegulatorService.type)))
listOf(nodeMustBeUp(notary), nodeMustBeUp(regulator)) listOf(nodeMustBeUp(notary), nodeMustBeUp(regulator))
} }
handles.map { nodeMustBeDown(it) } handles.map { nodeMustBeDown(it) }
@ -51,7 +51,7 @@ class DriverTests {
@Test @Test
fun `starting node with no services`() { fun `starting node with no services`() {
val noService = driver { val noService = driver {
val noService = startNode(DUMMY_BANK_A.name) val noService = startNode(providedName = DUMMY_BANK_A.name)
nodeMustBeUp(noService) nodeMustBeUp(noService)
} }
nodeMustBeDown(noService) nodeMustBeDown(noService)
@ -60,7 +60,7 @@ class DriverTests {
@Test @Test
fun `random free port allocation`() { fun `random free port allocation`() {
val nodeHandle = driver(portAllocation = PortAllocation.RandomFree) { val nodeHandle = driver(portAllocation = PortAllocation.RandomFree) {
val nodeInfo = startNode(DUMMY_BANK_A.name) val nodeInfo = startNode(providedName = DUMMY_BANK_A.name)
nodeMustBeUp(nodeInfo) nodeMustBeUp(nodeInfo)
} }
nodeMustBeDown(nodeHandle) nodeMustBeDown(nodeHandle)
@ -72,7 +72,7 @@ class DriverTests {
val logConfigFile = projectRootDir / "config" / "dev" / "log4j2.xml" val logConfigFile = projectRootDir / "config" / "dev" / "log4j2.xml"
assertThat(logConfigFile).isRegularFile() assertThat(logConfigFile).isRegularFile()
driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) { driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) {
val baseDirectory = startNode(DUMMY_BANK_A.name).getOrThrow().configuration.baseDirectory val baseDirectory = startNode(providedName = DUMMY_BANK_A.name).getOrThrow().configuration.baseDirectory
val logFile = (baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME).list { it.sorted().findFirst().get() } val logFile = (baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME).list { it.sorted().findFirst().get() }
val debugLinesPresent = logFile.readLines { lines -> lines.anyMatch { line -> line.startsWith("[DEBUG]") } } val debugLinesPresent = logFile.readLines { lines -> lines.anyMatch { line -> line.startsWith("[DEBUG]") } }
assertThat(debugLinesPresent).isTrue() assertThat(debugLinesPresent).isTrue()

View File

@ -93,7 +93,7 @@ val DUMMY_PARTY: Party get() = Party(X500Name("CN=Dummy,O=Dummy,L=Madrid,C=ES"),
*/ */
class PredefinedTestNode internal constructor(party: Party, driver: DriverDSLExposedInterface, services: Set<ServiceInfo>) { class PredefinedTestNode internal constructor(party: Party, driver: DriverDSLExposedInterface, services: Set<ServiceInfo>) {
val rpcUsers = listOf(User("admin", "admin", setOf("ALL"))) // TODO: Randomize? val rpcUsers = listOf(User("admin", "admin", setOf("ALL"))) // TODO: Randomize?
val nodeFuture by lazy { driver.startNode(party.name, rpcUsers = rpcUsers, advertisedServices = services) } val nodeFuture by lazy { driver.startNode(providedName = party.name, rpcUsers = rpcUsers, advertisedServices = services) }
val node by lazy { nodeFuture.get()!! } val node by lazy { nodeFuture.get()!! }
val rpc by lazy { node.rpcClientToNode() } val rpc by lazy { node.rpcClientToNode() }

View File

@ -78,6 +78,8 @@ interface DriverDSLExposedInterface : CordformContext {
/** /**
* Starts a [net.corda.node.internal.Node] in a separate process. * Starts a [net.corda.node.internal.Node] in a separate process.
* *
* @param defaultParameters The default parameters for the node. Allows the node to be configured in builder style
* when called from Java code.
* @param providedName Optional name of the node, which will be its legal name in [Party]. Defaults to something * @param providedName Optional name of the node, which will be its legal name in [Party]. Defaults to something
* random. Note that this must be unique as the driver uses it as a primary key! * random. Note that this must be unique as the driver uses it as a primary key!
* @param advertisedServices The set of services to be advertised by the node. Defaults to empty set. * @param advertisedServices The set of services to be advertised by the node. Defaults to empty set.
@ -87,12 +89,25 @@ interface DriverDSLExposedInterface : CordformContext {
* in. If null the Driver-level value will be used. * in. If null the Driver-level value will be used.
* @return The [NodeInfo] of the started up node retrieved from the network map service. * @return The [NodeInfo] of the started up node retrieved from the network map service.
*/ */
fun startNode(providedName: X500Name? = null, fun startNode(
advertisedServices: Set<ServiceInfo> = emptySet(), defaultParameters: NodeParameters = NodeParameters(),
rpcUsers: List<User> = emptyList(), providedName: X500Name? = defaultParameters.providedName,
verifierType: VerifierType = VerifierType.InMemory, advertisedServices: Set<ServiceInfo> = defaultParameters.advertisedServices,
customOverrides: Map<String, Any?> = emptyMap(), rpcUsers: List<User> = defaultParameters.rpcUsers,
startInSameProcess: Boolean? = null): CordaFuture<NodeHandle> verifierType: VerifierType = defaultParameters.verifierType,
customOverrides: Map<String, Any?> = defaultParameters.customOverrides,
startInSameProcess: Boolean? = defaultParameters.startInSameProcess): CordaFuture<NodeHandle>
/**
* Helper function for starting a [node] with custom parameters from Java.
*
* @param defaultParameters The default parameters for the driver.
* @param dsl The dsl itself.
* @return The value returned in the [dsl] closure.
*/
fun <A> startNode(parameters: NodeParameters): CordaFuture<NodeHandle> {
return startNode(defaultParameters = parameters)
}
fun startNodes( fun startNodes(
nodes: List<CordformNode>, nodes: List<CordformNode>,
@ -214,11 +229,30 @@ sealed class PortAllocation {
} }
} }
/**
* Helper builder for configuring a [node] from Java.
*/
data class NodeParameters(
val providedName: X500Name? = null,
val advertisedServices: Set<ServiceInfo> = emptySet(),
val rpcUsers: List<User> = emptyList(),
val verifierType: VerifierType = VerifierType.InMemory,
val customOverrides: Map<String, Any?> = emptyMap(),
val startInSameProcess: Boolean? = null
) {
fun setProvidedName(providedName: X500Name?) = copy(providedName = providedName)
fun setAdvertisedServices(advertisedServices: Set<ServiceInfo>) = copy(advertisedServices = advertisedServices)
fun setRpcUsers(rpcUsers: List<User>) = copy(rpcUsers = rpcUsers)
fun setVerifierType(verifierType: VerifierType) = copy(verifierType = verifierType)
fun setCustomerOverrides(customOverrides: Map<String, Any?>) = copy(customOverrides = customOverrides)
fun setStartInSameProcess(startInSameProcess: Boolean?) = copy(startInSameProcess = startInSameProcess)
}
/** /**
* [driver] allows one to start up nodes like this: * [driver] allows one to start up nodes like this:
* driver { * driver {
* val noService = startNode(DUMMY_BANK_A.name) * val noService = startNode(providedName = DUMMY_BANK_A.name)
* val notary = startNode(DUMMY_NOTARY.name) * val notary = startNode(providedName = DUMMY_NOTARY.name)
* *
* (...) * (...)
* } * }
@ -603,6 +637,7 @@ class DriverDSL(
} }
override fun startNode( override fun startNode(
defaultParameters: NodeParameters,
providedName: X500Name?, providedName: X500Name?,
advertisedServices: Set<ServiceInfo>, advertisedServices: Set<ServiceInfo>,
rpcUsers: List<User>, rpcUsers: List<User>,
@ -687,7 +722,7 @@ class DriverDSL(
val nodeAddress = portAllocation.nextHostAndPort() val nodeAddress = portAllocation.nextHostAndPort()
val configOverride = mapOf("notaryNodeAddress" to nodeAddress.toString(), "notaryClusterAddresses" to listOf(notaryClusterAddress.toString()), val configOverride = mapOf("notaryNodeAddress" to nodeAddress.toString(), "notaryClusterAddresses" to listOf(notaryClusterAddress.toString()),
"database.serverNameTablePrefix" to it.toString().replace(Regex("[^0-9A-Za-z]+"), "")) "database.serverNameTablePrefix" to it.toString().replace(Regex("[^0-9A-Za-z]+"), ""))
startNode(it, advertisedServices, rpcUsers, verifierType, configOverride) startNode(providedName = it, advertisedServices = advertisedServices, rpcUsers = rpcUsers, verifierType = verifierType, customOverrides = configOverride)
} }
return firstNotaryFuture.flatMap { firstNotary -> return firstNotaryFuture.flatMap { firstNotary ->

View File

@ -71,20 +71,20 @@ class ExplorerSimulation(val options: OptionSet) {
val portAllocation = PortAllocation.Incremental(20000) val portAllocation = PortAllocation.Incremental(20000)
driver(portAllocation = portAllocation) { driver(portAllocation = portAllocation) {
// TODO : Supported flow should be exposed somehow from the node instead of set of ServiceInfo. // TODO : Supported flow should be exposed somehow from the node instead of set of ServiceInfo.
val notary = startNode(DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)), val notary = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)),
customOverrides = mapOf("nearestCity" to "Zurich")) customOverrides = mapOf("nearestCity" to "Zurich"))
val alice = startNode(ALICE.name, rpcUsers = arrayListOf(user), val alice = startNode(providedName = ALICE.name, rpcUsers = arrayListOf(user),
advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("cash"))), advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("cash"))),
customOverrides = mapOf("nearestCity" to "Milan")) customOverrides = mapOf("nearestCity" to "Milan"))
val bob = startNode(BOB.name, rpcUsers = arrayListOf(user), val bob = startNode(providedName = BOB.name, rpcUsers = arrayListOf(user),
advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("cash"))), advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("cash"))),
customOverrides = mapOf("nearestCity" to "Madrid")) customOverrides = mapOf("nearestCity" to "Madrid"))
val ukBankName = X500Name("CN=UK Bank Plc,O=UK Bank Plc,L=London,C=GB") val ukBankName = X500Name("CN=UK Bank Plc,O=UK Bank Plc,L=London,C=GB")
val usaBankName = X500Name("CN=USA Bank Corp,O=USA Bank Corp,L=New York,C=USA") val usaBankName = X500Name("CN=USA Bank Corp,O=USA Bank Corp,L=New York,C=USA")
val issuerGBP = startNode(ukBankName, rpcUsers = arrayListOf(manager), val issuerGBP = startNode(providedName = ukBankName, rpcUsers = arrayListOf(manager),
advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.GBP"))), advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.GBP"))),
customOverrides = mapOf("nearestCity" to "London")) customOverrides = mapOf("nearestCity" to "London"))
val issuerUSD = startNode(usaBankName, rpcUsers = arrayListOf(manager), val issuerUSD = startNode(providedName = usaBankName, rpcUsers = arrayListOf(manager),
advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.USD"))), advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.USD"))),
customOverrides = mapOf("nearestCity" to "New York")) customOverrides = mapOf("nearestCity" to "New York"))

View File

@ -113,8 +113,8 @@ class VerifierTests {
@Test @Test
fun `single verifier works with a node`() { fun `single verifier works with a node`() {
verifierDriver(networkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = true)) { verifierDriver(networkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = true)) {
val aliceFuture = startNode(ALICE.name) val aliceFuture = startNode(providedName = ALICE.name)
val notaryFuture = startNode(DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type)), verifierType = VerifierType.OutOfProcess) val notaryFuture = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type)), verifierType = VerifierType.OutOfProcess)
val alice = aliceFuture.get() val alice = aliceFuture.get()
val notary = notaryFuture.get() val notary = notaryFuture.get()
startVerifier(notary) startVerifier(notary)

View File

@ -27,7 +27,7 @@ class DriverTests {
@Test @Test
fun `starting a node and independent web server works`() { fun `starting a node and independent web server works`() {
val addr = driver { val addr = driver {
val node = startNode(DUMMY_BANK_A.name).getOrThrow() val node = startNode(providedName = DUMMY_BANK_A.name).getOrThrow()
val webserverHandle = startWebserver(node).getOrThrow() val webserverHandle = startWebserver(node).getOrThrow()
webserverMustBeUp(webserverHandle) webserverMustBeUp(webserverHandle)
webserverHandle.listenAddress webserverHandle.listenAddress