From 59456cb6b1b819007cd3eadec13b3b4553bfb0fa Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Fri, 6 Jan 2017 11:33:00 +0000 Subject: [PATCH] Added a method to NodeHandle to simplify using RPC in the Driver --- .../net/corda/client/CordaRPCClientTest.kt | 17 +++---- .../html/_sources/tutorial-clientrpc-api.txt | 24 +++++---- .../corda/docs/IntegrationTestingTutorial.kt | 31 +++++------- .../net/corda/docs/ClientRpcTutorial.kt | 15 +----- docs/source/tutorial-integration-testing.rst | 5 +- .../net/corda/node/driver/DriverTests.kt | 2 +- .../node/services/DistributedServiceTests.kt | 49 +++++++++++-------- .../kotlin/net/corda/node/driver/Driver.kt | 17 ++++--- .../node/services/config/NodeConfiguration.kt | 2 + .../attachmentdemo/AttachmentDemoTest.kt | 17 +++---- .../net/corda/bank/BankOfCordaHttpAPITest.kt | 14 ++++-- .../corda/bank/BankOfCordaRPCClientTest.kt | 45 ++++++++++------- .../kotlin/net/corda/irs/IRSDemoTest.kt | 23 ++++----- .../net/corda/vega/SimmValuationTest.kt | 3 +- .../net/corda/traderdemo/TraderDemoTest.kt | 17 ++++--- .../kotlin/net/corda/testing/CoreTestUtils.kt | 3 -- .../main/kotlin/net/corda/explorer/Main.kt | 10 ++-- 17 files changed, 146 insertions(+), 148 deletions(-) diff --git a/client/src/integration-test/kotlin/net/corda/client/CordaRPCClientTest.kt b/client/src/integration-test/kotlin/net/corda/client/CordaRPCClientTest.kt index 0725bf8dfc..db5092e396 100644 --- a/client/src/integration-test/kotlin/net/corda/client/CordaRPCClientTest.kt +++ b/client/src/integration-test/kotlin/net/corda/client/CordaRPCClientTest.kt @@ -12,28 +12,21 @@ import net.corda.node.driver.DriverBasedTest import net.corda.node.driver.NodeHandle import net.corda.node.driver.driver import net.corda.node.services.User -import net.corda.node.services.config.configureTestSSL -import net.corda.node.services.messaging.ArtemisMessagingComponent.Companion.toHostAndPort import net.corda.node.services.messaging.CordaRPCClient import net.corda.node.services.startFlowPermission import net.corda.node.services.transactions.ValidatingNotaryService import org.apache.activemq.artemis.api.core.ActiveMQSecurityException import org.assertj.core.api.Assertions.assertThatExceptionOfType -import org.junit.After -import org.junit.Before import org.junit.Test -import java.util.concurrent.CountDownLatch -import kotlin.concurrent.thread class CordaRPCClientTest : DriverBasedTest() { - private val rpcUser = User("user1", "test", permissions = setOf(startFlowPermission())) + private lateinit var node: NodeHandle private lateinit var client: CordaRPCClient - private lateinit var driverInfo: NodeHandle override fun setup() = driver(isDebug = true) { - driverInfo = startNode(rpcUsers = listOf(rpcUser), advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type))).getOrThrow() - client = CordaRPCClient(toHostAndPort(driverInfo.nodeInfo.address), configureTestSSL()) + node = startNode(rpcUsers = listOf(rpcUser), advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type))).getOrThrow() + client = node.rpcClientToNode() runTest() } @@ -63,7 +56,9 @@ class CordaRPCClientTest : DriverBasedTest() { println("Creating proxy") val proxy = client.proxy() println("Starting flow") - val flowHandle = proxy.startFlow(::CashFlow, CashCommand.IssueCash(20.DOLLARS, OpaqueBytes.of(0), driverInfo.nodeInfo.legalIdentity, driverInfo.nodeInfo.legalIdentity)) + val flowHandle = proxy.startFlow( + ::CashFlow, + CashCommand.IssueCash(20.DOLLARS, OpaqueBytes.of(0), node.nodeInfo.legalIdentity, node.nodeInfo.legalIdentity)) println("Started flow, waiting on result") flowHandle.progress.subscribe { println("PROGRESS $it") diff --git a/docs/build/html/_sources/tutorial-clientrpc-api.txt b/docs/build/html/_sources/tutorial-clientrpc-api.txt index a4cdcd85bd..09338713a3 100644 --- a/docs/build/html/_sources/tutorial-clientrpc-api.txt +++ b/docs/build/html/_sources/tutorial-clientrpc-api.txt @@ -3,13 +3,12 @@ Client RPC API tutorial ======================= -In this tutorial we will build a simple command line utility that -connects to a node, creates some Cash transactions and meanwhile dumps -the transaction graph to the standard output. We will then put some -simple visualisation on top. For an explanation on how the RPC works -see :doc:`clientrpc`. +In this tutorial we will build a simple command line utility that connects to a node, creates some Cash transactions and +meanwhile dumps the transaction graph to the standard output. We will then put some simple visualisation on top. For an +explanation on how the RPC works see :doc:`clientrpc`. -We start off by connecting to the node itself. For the purposes of the tutorial we will use the Driver to start up a notary and a node that issues/exits and moves Cash around for herself. To authenticate we will use the certificates of the nodes directly. +We start off by connecting to the node itself. For the purposes of the tutorial we will use the Driver to start up a notary +and a node that issues/exits and moves Cash around for herself. Note how we configure the node to create a user that has permission to start the CashFlow. @@ -25,14 +24,16 @@ Now we can connect to the node itself using a valid RPC login. We login using th :start-after: START 2 :end-before: END 2 -We start generating transactions in a different thread (``generateTransactions`` to be defined later) using ``proxy``, which exposes the full RPC interface of the node: +We start generating transactions in a different thread (``generateTransactions`` to be defined later) using ``proxy``, +which exposes the full RPC interface of the node: .. literalinclude:: ../../node/src/main/kotlin/net/corda/node/services/messaging/CordaRPCOps.kt :language: kotlin :start-after: interface CordaRPCOps :end-before: } -.. warning:: This API is evolving and will continue to grow as new functionality and features added to Corda are made available to RPC clients. +.. warning:: This API is evolving and will continue to grow as new functionality and features added to Corda are made + available to RPC clients. The one we need in order to dump the transaction graph is ``verifiedTransactions``. The type signature tells us that the RPC will return a list of transactions and an Observable stream. This is a general pattern, we query some data and the @@ -65,9 +66,12 @@ We utilise several RPC functions here to query things like the notaries in the n Then in a loop we generate randomly either an Issue, a Pay or an Exit transaction. -The RPC we need to initiate a Cash transaction is ``startFlowDynamic`` which may start an arbitrary flow, given sufficient permissions to do so. We won't use this function directly, but rather a type-safe wrapper around it ``startFlow`` that type-checks the arguments for us. +The RPC we need to initiate a Cash transaction is ``startFlowDynamic`` which may start an arbitrary flow, given sufficient +permissions to do so. We won't use this function directly, but rather a type-safe wrapper around it ``startFlow`` that +type-checks the arguments for us. -Finally we have everything in place: we start a couple of nodes, connect to them, and start creating transactions while listening on successfully created ones, which are dumped to the console. We just need to run it!: +Finally we have everything in place: we start a couple of nodes, connect to them, and start creating transactions while +listening on successfully created ones, which are dumped to the console. We just need to run it!: .. code-block:: text diff --git a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt index fd551faf71..d02b9b33b2 100644 --- a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt +++ b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt @@ -1,8 +1,10 @@ package net.corda.docs +import com.google.common.util.concurrent.Futures import net.corda.contracts.asset.Cash import net.corda.core.contracts.DOLLARS import net.corda.core.contracts.issuedBy +import net.corda.core.getOrThrow import net.corda.core.messaging.startFlow import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault @@ -12,9 +14,6 @@ import net.corda.flows.CashFlow import net.corda.flows.CashFlowResult import net.corda.node.driver.driver import net.corda.node.services.User -import net.corda.node.services.config.configureTestSSL -import net.corda.node.services.messaging.ArtemisMessagingComponent -import net.corda.node.services.messaging.CordaRPCClient import net.corda.node.services.startFlowPermission import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.testing.expect @@ -26,31 +25,25 @@ import kotlin.concurrent.thread import kotlin.test.assertEquals class IntegrationTestingTutorial { - @Test - fun aliceBobCashExchangeExample() { + fun `alice bob cash exchange example`() { // START 1 driver { val testUser = User("testUser", "testPassword", permissions = setOf(startFlowPermission())) - val aliceFuture = startNode("Alice", rpcUsers = listOf(testUser)) - val bobFuture = startNode("Bob", rpcUsers = listOf(testUser)) - val notaryFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type))) - val alice = aliceFuture.get() - val bob = bobFuture.get() - val notary = notaryFuture.get() + val (alice, bob, notary) = Futures.allAsList( + startNode("Alice", rpcUsers = listOf(testUser)), + startNode("Bob", rpcUsers = listOf(testUser)), + startNode("Notary", advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type))) + ).getOrThrow() // END 1 // START 2 - val aliceClient = CordaRPCClient( - host = ArtemisMessagingComponent.toHostAndPort(alice.nodeInfo.address), - config = configureTestSSL() - ) + val aliceClient = alice.rpcClientToNode() + aliceClient.start("testUser", "testPassword") val aliceProxy = aliceClient.proxy() - val bobClient = CordaRPCClient( - host = ArtemisMessagingComponent.toHostAndPort(bob.nodeInfo.address), - config = configureTestSSL() - ) + val bobClient = bob.rpcClientToNode() + bobClient.start("testUser", "testPassword") val bobProxy = bobClient.proxy() // END 2 diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt index 04fc07e226..b7e2430e54 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt @@ -6,7 +6,6 @@ import net.corda.core.contracts.Amount import net.corda.core.contracts.Issued import net.corda.core.contracts.PartyAndReference import net.corda.core.contracts.USD -import net.corda.core.div import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow import net.corda.core.node.CordaPluginRegistry @@ -17,9 +16,6 @@ import net.corda.flows.CashCommand import net.corda.flows.CashFlow import net.corda.node.driver.driver import net.corda.node.services.User -import net.corda.node.services.config.FullNodeConfiguration -import net.corda.node.services.config.NodeSSLConfiguration -import net.corda.node.services.messaging.CordaRPCClient import net.corda.node.services.startFlowPermission import net.corda.node.services.transactions.ValidatingNotaryService import org.graphstream.graph.Edge @@ -41,9 +37,7 @@ enum class PrintOrVisualise { } fun main(args: Array) { - if (args.size < 1) { - throw IllegalArgumentException("Usage: [Print|Visualise]") - } + require(args.isNotEmpty()) { "Usage: [Print|Visualise]" } val printOrVisualise = PrintOrVisualise.valueOf(args[0]) val baseDirectory = Paths.get("build/rpc-api-tutorial") @@ -52,15 +46,10 @@ fun main(args: Array) { driver(driverDirectory = baseDirectory) { startNode("Notary", advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type))) val node = startNode("Alice", rpcUsers = listOf(user)).get() - val sslConfig = object : NodeSSLConfiguration { - override val certificatesPath = baseDirectory / "Alice" / "certificates" - override val keyStorePassword = "cordacadevpass" - override val trustStorePassword = "trustpass" - } // END 1 // START 2 - val client = CordaRPCClient(FullNodeConfiguration(node.config).artemisAddress, sslConfig) + val client = node.rpcClientToNode() client.start("user", "password") val proxy = client.proxy() diff --git a/docs/source/tutorial-integration-testing.rst b/docs/source/tutorial-integration-testing.rst index 3c332c74cc..3ab804b7b8 100644 --- a/docs/source/tutorial-integration-testing.rst +++ b/docs/source/tutorial-integration-testing.rst @@ -35,7 +35,7 @@ notary directly, so there's no need to pass in the test ``User``. The ``startNode`` function returns a future that completes once the node is fully started. This allows starting of the nodes to be parallel. We wait on these futures as we need the information -returned; their respective ``NodeInfo`` s. +returned; their respective ``NodeHandles`` s. .. literalinclude:: example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt :language: kotlin @@ -46,9 +46,6 @@ Next we connect to Alice and Bob respectively from the test process using the test user we created. Then we establish RPC links that allow us to start flows and query state. -Note that Driver nodes start up with test server certificates, so -it's enough to pass in ``configureTestSSL()`` for the clients. - .. literalinclude:: example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt :language: kotlin :start-after: START 3 diff --git a/node/src/integration-test/kotlin/net/corda/node/driver/DriverTests.kt b/node/src/integration-test/kotlin/net/corda/node/driver/DriverTests.kt index 5cce89db62..7ac9736f9d 100644 --- a/node/src/integration-test/kotlin/net/corda/node/driver/DriverTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/driver/DriverTests.kt @@ -53,7 +53,7 @@ class DriverTests { @Test fun randomFreePortAllocationWorks() { - val nodeInfo = driver(portAllocation = PortAllocation.RandomFree()) { + val nodeInfo = driver(portAllocation = PortAllocation.RandomFree) { val nodeInfo = startNode("NoService") nodeMustBeUp(nodeInfo.getOrThrow().nodeInfo) nodeInfo.getOrThrow() diff --git a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt index 3144456d1c..2455a0a696 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt @@ -1,6 +1,7 @@ package net.corda.node.services import net.corda.core.bufferUntilSubscribed +import net.corda.core.contracts.Amount import net.corda.core.contracts.POUNDS import net.corda.core.contracts.issuedBy import net.corda.core.crypto.Party @@ -15,9 +16,6 @@ import net.corda.flows.CashFlowResult import net.corda.node.driver.DriverBasedTest import net.corda.node.driver.NodeHandle import net.corda.node.driver.driver -import net.corda.node.services.config.configureTestSSL -import net.corda.node.services.messaging.ArtemisMessagingComponent -import net.corda.node.services.messaging.CordaRPCClient import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.testing.expect import net.corda.testing.expectEvents @@ -28,14 +26,14 @@ import java.util.* import kotlin.test.assertEquals class DistributedServiceTests : DriverBasedTest() { - lateinit var alice: NodeInfo + lateinit var alice: NodeHandle lateinit var notaries: List lateinit var aliceProxy: CordaRPCOps lateinit var raftNotaryIdentity: Party lateinit var notaryStateMachines: Observable> override fun setup() = driver { - // Start Alice and 3 raft notaries + // Start Alice and 3 notaries in a RAFT cluster val clusterSize = 3 val testUser = User("test", "test", permissions = setOf(startFlowPermission())) val aliceFuture = startNode("Alice", rpcUsers = listOf(testUser)) @@ -46,7 +44,7 @@ class DistributedServiceTests : DriverBasedTest() { type = RaftValidatingNotaryService.type ) - alice = aliceFuture.get().nodeInfo + alice = aliceFuture.get() val (notaryIdentity, notaryNodes) = notariesFuture.get() raftNotaryIdentity = notaryIdentity notaries = notaryNodes @@ -55,14 +53,14 @@ class DistributedServiceTests : DriverBasedTest() { assertEquals(notaries.size, notaries.map { it.nodeInfo.legalIdentity }.toSet().size) // Connect to Alice and the notaries - fun connectRpc(node: NodeInfo): CordaRPCOps { - val client = CordaRPCClient(ArtemisMessagingComponent.toHostAndPort(node.address), configureTestSSL()) + fun connectRpc(node: NodeHandle): CordaRPCOps { + val client = node.rpcClientToNode() client.start("test", "test") return client.proxy() } aliceProxy = connectRpc(alice) - val notaryProxies = notaries.map { connectRpc(it.nodeInfo) } - notaryStateMachines = Observable.from(notaryProxies.map { proxy -> + val rpcClientsToNotaries = notaries.map(::connectRpc) + notaryStateMachines = Observable.from(rpcClientsToNotaries.map { proxy -> proxy.stateMachinesAndUpdates().second.map { Pair(proxy.nodeIdentity(), it) } }).flatMap { it.onErrorResumeNext(Observable.empty()) }.bufferUntilSubscribed() @@ -74,11 +72,10 @@ class DistributedServiceTests : DriverBasedTest() { @Test fun `requests are distributed evenly amongst the nodes`() { // Issue 100 pounds, then pay ourselves 50x2 pounds - val issueHandle = aliceProxy.startFlow(::CashFlow, CashCommand.IssueCash(100.POUNDS, OpaqueBytes.of(0), alice.legalIdentity, raftNotaryIdentity)) - require(issueHandle.returnValue.toBlocking().first() is CashFlowResult.Success) + issueCash(100.POUNDS) + for (i in 1..50) { - val payHandle = aliceProxy.startFlow(::CashFlow, CashCommand.PayCash(2.POUNDS.issuedBy(alice.legalIdentity.ref(0)), alice.legalIdentity)) - require(payHandle.returnValue.toBlocking().first() is CashFlowResult.Success) + paySelf(2.POUNDS) } // The state machines added in the notaries should map one-to-one to notarisation requests @@ -104,11 +101,10 @@ class DistributedServiceTests : DriverBasedTest() { @Test fun `cluster survives if a notary is killed`() { // Issue 100 pounds, then pay ourselves 10x5 pounds - val issueHandle = aliceProxy.startFlow(::CashFlow, CashCommand.IssueCash(100.POUNDS, OpaqueBytes.of(0), alice.legalIdentity, raftNotaryIdentity)) - require(issueHandle.returnValue.toBlocking().first() is CashFlowResult.Success) + issueCash(100.POUNDS) + for (i in 1..10) { - val payHandle = aliceProxy.startFlow(::CashFlow, CashCommand.PayCash(5.POUNDS.issuedBy(alice.legalIdentity.ref(0)), alice.legalIdentity)) - require(payHandle.returnValue.toBlocking().first() is CashFlowResult.Success) + paySelf(5.POUNDS) } // Now kill a notary @@ -119,8 +115,7 @@ class DistributedServiceTests : DriverBasedTest() { // Pay ourselves another 20x5 pounds for (i in 1..20) { - val payHandle = aliceProxy.startFlow(::CashFlow, CashCommand.PayCash(5.POUNDS.issuedBy(alice.legalIdentity.ref(0)), alice.legalIdentity)) - require(payHandle.returnValue.toBlocking().first() is CashFlowResult.Success) + paySelf(5.POUNDS) } val notarisationsPerNotary = HashMap() @@ -137,4 +132,18 @@ class DistributedServiceTests : DriverBasedTest() { println("Notarisation distribution: $notarisationsPerNotary") require(notarisationsPerNotary.size == 3) } + + private fun issueCash(amount: Amount) { + val issueHandle = aliceProxy.startFlow( + ::CashFlow, + CashCommand.IssueCash(amount, OpaqueBytes.of(0), alice.nodeInfo.legalIdentity, raftNotaryIdentity)) + require(issueHandle.returnValue.toBlocking().first() is CashFlowResult.Success) + } + + private fun paySelf(amount: Amount) { + val payHandle = aliceProxy.startFlow( + ::CashFlow, + CashCommand.PayCash(amount.issuedBy(alice.nodeInfo.legalIdentity.ref(0)), alice.nodeInfo.legalIdentity)) + require(payHandle.returnValue.toBlocking().first() is CashFlowResult.Success) + } } \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/driver/Driver.kt b/node/src/main/kotlin/net/corda/node/driver/Driver.kt index c8fab91057..3cb992a56a 100644 --- a/node/src/main/kotlin/net/corda/node/driver/Driver.kt +++ b/node/src/main/kotlin/net/corda/node/driver/Driver.kt @@ -19,6 +19,7 @@ import net.corda.core.utilities.loggerFor import net.corda.node.services.User import net.corda.node.services.config.ConfigHelper import net.corda.node.services.config.FullNodeConfiguration +import net.corda.node.services.messaging.CordaRPCClient import net.corda.node.services.messaging.NodeMessagingClient import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.RaftValidatingNotaryService @@ -93,9 +94,11 @@ interface DriverDSLInternalInterface : DriverDSLExposedInterface { data class NodeHandle( val nodeInfo: NodeInfo, - val config: Config, + val configuration: FullNodeConfiguration, val process: Process -) +) { + fun rpcClientToNode(): CordaRPCClient = CordaRPCClient(configuration.artemisAddress, configuration) +} sealed class PortAllocation { abstract fun nextPort(): Int @@ -106,7 +109,7 @@ sealed class PortAllocation { override fun nextPort() = portCounter.andIncrement } - class RandomFree() : PortAllocation() { + object RandomFree : PortAllocation() { override fun nextPort(): Int { return ServerSocket().use { it.bind(InetSocketAddress(0)) @@ -364,16 +367,16 @@ open class DriverDSL( } ) + customOverrides - val config = ConfigHelper.loadConfig( + val configuration = FullNodeConfiguration(ConfigHelper.loadConfig( baseDirectoryPath = baseDirectory, allowMissingConfig = true, configOverrides = configOverrides - ) + )) - val startNode = startNode(executorService, FullNodeConfiguration(config), quasarJarPath, debugPort) + val startNode = startNode(executorService, configuration, quasarJarPath, debugPort) registerProcess(startNode) return startNode.map { - NodeHandle(queryNodeInfo(apiAddress)!!, config, it) + NodeHandle(queryNodeInfo(apiAddress)!!, configuration, it) } } diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt index 463c485a26..97de5de4a0 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt @@ -61,6 +61,8 @@ class FullNodeConfiguration(val config: Config) : NodeConfiguration { val useHTTPS: Boolean by config val artemisAddress: HostAndPort by config val webAddress: HostAndPort by config + // TODO This field is slightly redundant as artemisAddress is sufficient to hold the address of the node's MQ broker. + // Instead this should be a Boolean indicating whether that broker is an internal one started by the node or an external one val messagingServerAddress: HostAndPort? by config.getOrElse { null } val extraAdvertisedServiceIds: String by config val useTestClock: Boolean by config.getOrElse { false } diff --git a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt index 35e8fb701b..a61ea32d42 100644 --- a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt +++ b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt @@ -1,31 +1,30 @@ package net.corda.attachmentdemo +import com.google.common.util.concurrent.Futures import net.corda.core.getOrThrow import net.corda.core.node.services.ServiceInfo import net.corda.node.driver.driver import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.testing.getHostAndPort import org.junit.Test import kotlin.concurrent.thread class AttachmentDemoTest { @Test fun `runs attachment demo`() { driver(dsl = { - startNode("Notary", setOf(ServiceInfo(SimpleNotaryService.Companion.type))) - val nodeAFuture = startNode("Bank A") - val nodeBApiAddr = startNode("Bank B").getOrThrow().config.getHostAndPort("webAddress") - - val nodeA = nodeAFuture.getOrThrow() - val nodeAApiAddr = nodeA.config.getHostAndPort("webAddress") + val (nodeA, nodeB) = Futures.allAsList( + startNode("Bank A"), + startNode("Bank B"), + startNode("Notary", setOf(ServiceInfo(SimpleNotaryService.Companion.type))) + ).getOrThrow() var recipientReturn: Boolean? = null var senderReturn: Boolean? = null val recipientThread = thread { - recipientReturn = AttachmentDemoClientApi(nodeAApiAddr).runRecipient() + recipientReturn = AttachmentDemoClientApi(nodeA.configuration.webAddress).runRecipient() } val senderThread = thread { val counterpartyKey = nodeA.nodeInfo.legalIdentity.owningKey.toBase58String() - senderReturn = AttachmentDemoClientApi(nodeBApiAddr).runSender(counterpartyKey) + senderReturn = AttachmentDemoClientApi(nodeB.configuration.webAddress).runSender(counterpartyKey) } recipientThread.join() senderThread.join() diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt index 035d80b26f..50e36588d4 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt @@ -1,19 +1,23 @@ package net.corda.bank +import com.google.common.util.concurrent.Futures import net.corda.bank.api.BankOfCordaClientApi import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams +import net.corda.core.getOrThrow import net.corda.core.node.services.ServiceInfo import net.corda.node.driver.driver import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.testing.getHostAndPort import org.junit.Test class BankOfCordaHttpAPITest { - @Test fun `test issuer flow via Http`() { + @Test + fun `issuer flow via Http`() { driver(dsl = { - val nodeBankOfCorda = startNode("BankOfCorda", setOf(ServiceInfo(SimpleNotaryService.type))).get() - val nodeBankOfCordaApiAddr = nodeBankOfCorda.config.getHostAndPort("webAddress") - startNode("BigCorporation").get() + val (nodeBankOfCorda) = Futures.allAsList( + startNode("BankOfCorda", setOf(ServiceInfo(SimpleNotaryService.type))), + startNode("BigCorporation") + ).getOrThrow() + val nodeBankOfCordaApiAddr = nodeBankOfCorda.configuration.webAddress assert(BankOfCordaClientApi(nodeBankOfCordaApiAddr).requestWebIssue(IssueRequestParams(1000, "USD", "BigCorporation", "1", "BankOfCorda"))) }, isDebug = true) } diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt index cfc80e2631..f66d53717c 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt @@ -1,39 +1,41 @@ package net.corda.bank +import com.google.common.util.concurrent.Futures import net.corda.core.contracts.DOLLARS +import net.corda.core.getOrThrow import net.corda.core.messaging.startFlow import net.corda.core.node.services.ServiceInfo import net.corda.core.transactions.SignedTransaction import net.corda.flows.IssuerFlow.IssuanceRequester import net.corda.node.driver.driver import net.corda.node.services.User -import net.corda.node.services.config.configureTestSSL -import net.corda.node.services.messaging.CordaRPCClient import net.corda.node.services.startFlowPermission import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.testing.* +import net.corda.testing.BOC_PARTY_REF +import net.corda.testing.expect +import net.corda.testing.expectEvents +import net.corda.testing.sequence import org.junit.Test import kotlin.test.assertTrue class BankOfCordaRPCClientTest { - - @Test fun `test issuer flow via RPC`() { + @Test + fun `issuer flow via RPC`() { driver(dsl = { val user = User("user1", "test", permissions = setOf(startFlowPermission())) - val nodeBankOfCorda = startNode("BankOfCorda", setOf(ServiceInfo(SimpleNotaryService.type)), arrayListOf(user)).get() - val nodeBankOfCordaApiAddr = nodeBankOfCorda.config.getHostAndPort("artemisAddress") - val bankOfCordaParty = nodeBankOfCorda.nodeInfo.legalIdentity - val nodeBigCorporation = startNode("BigCorporation", rpcUsers = arrayListOf(user)).get() - val bigCorporationParty = nodeBigCorporation.nodeInfo.legalIdentity + val (nodeBankOfCorda, nodeBigCorporation) = Futures.allAsList( + startNode("BankOfCorda", setOf(ServiceInfo(SimpleNotaryService.type)), listOf(user)), + startNode("BigCorporation", rpcUsers = listOf(user)) + ).getOrThrow() // Bank of Corda RPC Client - val bocClient = CordaRPCClient(nodeBankOfCordaApiAddr, configureTestSSL()) - bocClient.start("user1","test") + val bocClient = nodeBankOfCorda.rpcClientToNode() + bocClient.start("user1", "test") val bocProxy = bocClient.proxy() // Big Corporation RPC Client - val bigCorpClient = CordaRPCClient(nodeBankOfCordaApiAddr, configureTestSSL()) - bigCorpClient.start("user1","test") + val bigCorpClient = nodeBankOfCorda.rpcClientToNode() // TODO This test is broken as this should be nodeBigCorporation + bigCorpClient.start("user1", "test") val bigCorpProxy = bigCorpClient.proxy() // Register for Bank of Corda Vault updates @@ -43,7 +45,12 @@ class BankOfCordaRPCClientTest { val vaultUpdatesBigCorp = bigCorpProxy.vaultAndUpdates().second // Kick-off actual Issuer Flow - val result = bocProxy.startFlow(::IssuanceRequester, 1000.DOLLARS, bigCorporationParty, BOC_PARTY_REF, bankOfCordaParty).returnValue.toBlocking().first() + val result = bocProxy.startFlow( + ::IssuanceRequester, + 1000.DOLLARS, + nodeBigCorporation.nodeInfo.legalIdentity, + BOC_PARTY_REF, + nodeBankOfCorda.nodeInfo.legalIdentity).returnValue.toBlocking().first() assertTrue { result is SignedTransaction } // Check Bank of Corda Vault Updates @@ -51,13 +58,13 @@ class BankOfCordaRPCClientTest { sequence( // ISSUE expect { update -> - require(update.consumed.size == 0) { update.consumed.size } + require(update.consumed.isEmpty()) { update.consumed.size } require(update.produced.size == 1) { update.produced.size } }, // MOVE expect { update -> require(update.consumed.size == 1) { update.consumed.size } - require(update.produced.size == 0) { update.produced.size } + require(update.produced.isEmpty()) { update.produced.size } } ) } @@ -67,13 +74,13 @@ class BankOfCordaRPCClientTest { sequence( // ISSUE expect { update -> - require(update.consumed.size == 0) { update.consumed.size } + require(update.consumed.isEmpty()) { update.consumed.size } require(update.produced.size == 1) { update.produced.size } }, // MOVE expect { update -> require(update.consumed.size == 1) { update.consumed.size } - require(update.produced.size == 0) { update.produced.size } + require(update.produced.isEmpty()) { update.produced.size } } ) } diff --git a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt index 33f9ce351f..13d1d64fe6 100644 --- a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt +++ b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt @@ -1,7 +1,7 @@ package net.corda.irs import com.google.common.net.HostAndPort -import com.typesafe.config.Config +import com.google.common.util.concurrent.Futures import net.corda.core.getOrThrow import net.corda.core.node.services.ServiceInfo import net.corda.irs.api.NodeInterestRates @@ -15,17 +15,18 @@ import org.apache.commons.io.IOUtils import org.junit.Test import java.net.URL -class IRSDemoTest: IntegrationTestCategory { - fun Config.getHostAndPort(name: String): HostAndPort = HostAndPort.fromString(getString(name))!! - - @Test fun `runs IRS demo`() { +class IRSDemoTest : IntegrationTestCategory { + @Test + fun `runs IRS demo`() { driver(dsl = { - val controller = startNode("Notary", setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.type))).getOrThrow() - val nodeA = startNode("Bank A").getOrThrow() - val nodeB = startNode("Bank B").getOrThrow() - runUploadRates(controller.config.getHostAndPort("webAddress")) - runTrade(nodeA.config.getHostAndPort("webAddress")) - runDateChange(nodeB.config.getHostAndPort("webAddress")) + val (controller, nodeA, nodeB) = Futures.allAsList( + startNode("Notary", setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.type))), + startNode("Bank A"), + startNode("Bank B") + ).getOrThrow() + runUploadRates(controller.configuration.webAddress) + runTrade(nodeA.configuration.webAddress) + runDateChange(nodeB.configuration.webAddress) }, useTestClock = true, isDebug = true) } } diff --git a/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt b/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt index a5b1dd093c..b8a9acf55f 100644 --- a/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt +++ b/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt @@ -7,7 +7,6 @@ import net.corda.node.driver.NodeHandle import net.corda.node.driver.driver import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.IntegrationTestCategory -import net.corda.testing.getHostAndPort import net.corda.testing.http.HttpApi import net.corda.vega.api.PortfolioApi import net.corda.vega.api.PortfolioApiUtils @@ -45,7 +44,7 @@ class SimmValuationTest: IntegrationTestCategory { } private fun getSimmNodeApi(futureNode: Future): HttpApi { - val nodeAddr = futureNode.getOrThrow().config.getHostAndPort("webAddress") + val nodeAddr = futureNode.getOrThrow().configuration.webAddress return HttpApi.fromHostAndPort(nodeAddr, "api/simmvaluationdemo") } diff --git a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt index 1982d4066e..c7fa9ae56e 100644 --- a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt +++ b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt @@ -1,5 +1,6 @@ package net.corda.traderdemo +import com.google.common.util.concurrent.Futures import net.corda.core.getOrThrow import net.corda.core.node.services.ServiceInfo import net.corda.flows.IssuerFlow @@ -7,21 +8,21 @@ import net.corda.node.driver.driver import net.corda.node.services.User import net.corda.node.services.startFlowPermission import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.testing.getHostAndPort import org.junit.Test class TraderDemoTest { @Test fun `runs trader demo`() { driver(dsl = { - startNode("Notary", setOf(ServiceInfo(SimpleNotaryService.type))) - val nodeA = startNode("Bank A").getOrThrow() - val nodeAApiAddr = nodeA.config.getHostAndPort("webAddress") - val nodeBApiAddr = startNode("Bank B").getOrThrow().config.getHostAndPort("webAddress") val user = User("user1", "test", permissions = setOf(startFlowPermission())) - startNode("BankOfCorda", rpcUsers = listOf(user)).getOrThrow() + val (nodeA, nodeB) = Futures.allAsList( + startNode("Bank A"), + startNode("Bank B"), + startNode("BankOfCorda", rpcUsers = listOf(user)), + startNode("Notary", setOf(ServiceInfo(SimpleNotaryService.type))) + ).getOrThrow() - assert(TraderDemoClientApi(nodeAApiAddr).runBuyer()) - assert(TraderDemoClientApi(nodeBApiAddr).runSeller(counterparty = nodeA.nodeInfo.legalIdentity.name)) + assert(TraderDemoClientApi(nodeA.configuration.webAddress).runBuyer()) + assert(TraderDemoClientApi(nodeB.configuration.webAddress).runSeller(counterparty = nodeA.nodeInfo.legalIdentity.name)) }, isDebug = true) } } diff --git a/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt b/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt index f39f26db2e..8d81b2d456 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt @@ -5,7 +5,6 @@ package net.corda.testing import com.google.common.net.HostAndPort import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.SettableFuture -import com.typesafe.config.Config import net.corda.core.contracts.StateRef import net.corda.core.crypto.* import net.corda.core.flows.FlowLogic @@ -165,8 +164,6 @@ inline fun > AbstractNode.initiateSingleShotFlow( return future } -fun Config.getHostAndPort(name: String) = HostAndPort.fromString(getString(name)) - inline fun elapsedTime(block: () -> Unit): Duration { val start = System.nanoTime() block() diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt index b5ca71278e..130b09b933 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt @@ -26,9 +26,7 @@ import net.corda.flows.IssuerFlow.IssuanceRequester import net.corda.node.driver.PortAllocation import net.corda.node.driver.driver import net.corda.node.services.User -import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.messaging.ArtemisMessagingComponent -import net.corda.node.services.messaging.CordaRPCClient import net.corda.node.services.startFlowPermission import net.corda.node.services.transactions.SimpleNotaryService import org.apache.commons.lang.SystemUtils @@ -143,19 +141,19 @@ fun main(args: Array) { println("Running simulation mode ...") // Register with alice to use alice's RPC proxy to create random events. - val aliceClient = CordaRPCClient(ArtemisMessagingComponent.toHostAndPort(aliceNode.nodeInfo.address), FullNodeConfiguration(aliceNode.config)) + val aliceClient = aliceNode.rpcClientToNode() aliceClient.start(user.username, user.password) val aliceRPC = aliceClient.proxy() - val bobClient = CordaRPCClient(ArtemisMessagingComponent.toHostAndPort(bobNode.nodeInfo.address), FullNodeConfiguration(bobNode.config)) + val bobClient = bobNode.rpcClientToNode() bobClient.start(user.username, user.password) val bobRPC = bobClient.proxy() - val issuerClientGBP = CordaRPCClient(ArtemisMessagingComponent.toHostAndPort(issuerNodeGBP.nodeInfo.address), FullNodeConfiguration(issuerNodeGBP.config)) + val issuerClientGBP = issuerNodeGBP.rpcClientToNode() issuerClientGBP.start(manager.username, manager.password) val issuerRPCGBP = issuerClientGBP.proxy() - val issuerClientUSD = CordaRPCClient(ArtemisMessagingComponent.toHostAndPort(issuerNodeGBP.nodeInfo.address), FullNodeConfiguration(issuerNodeUSD.config)) + val issuerClientUSD = issuerNodeGBP.rpcClientToNode() // TODO This should be issuerNodeUSD issuerClientUSD.start(manager.username, manager.password) val issuerRPCUSD = issuerClientUSD.proxy()