diff --git a/build.gradle b/build.gradle index eda5774878..12d70e0312 100644 --- a/build.gradle +++ b/build.gradle @@ -210,7 +210,6 @@ allprojects { mavenCentral() jcenter() maven { url 'https://jitpack.io' } - maven { url "$artifactory_contextUrl/corda-releases" } // cordform-common } configurations { diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index e852b26f77..403b1155ba 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -6,6 +6,8 @@ release, see :doc:`upgrade-notes`. Unreleased ---------- +* Removed experimental feature `CordformDefinition` + * Vault query fix: support query by parent classes of Contract State classes (see https://github.com/corda/corda/issues/3714) * Added ``registerResponderFlow`` method to ``StartedMockNode``, to support isolated testing of responder flow behaviour. diff --git a/node-api/build.gradle b/node-api/build.gradle index 9da77eaf2e..d70b5af596 100644 --- a/node-api/build.gradle +++ b/node-api/build.gradle @@ -22,8 +22,6 @@ dependencies { // TODO: Remove this dependency and the code that requires it compile "commons-fileupload:commons-fileupload:$fileupload_version" - compile "net.corda.plugins:cordform-common:$gradle_plugins_version" - // TypeSafe Config: for simple and human friendly config files. compile "com.typesafe:config:$typesafe_config_version" diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/NodeInfoConstants.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/NodeInfoConstants.kt new file mode 100644 index 0000000000..8a75621a2b --- /dev/null +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/NodeInfoConstants.kt @@ -0,0 +1,4 @@ +package net.corda.nodeapi.internal + +// TODO: Add to Corda node.conf to allow customisation +const val NODE_INFO_DIRECTORY = "additional-node-infos" \ No newline at end of file diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt index a8bd936e68..4690b5e325 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt @@ -2,7 +2,6 @@ package net.corda.nodeapi.internal.network import com.typesafe.config.Config import com.typesafe.config.ConfigFactory -import net.corda.cordform.CordformNode import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.internal.* @@ -46,11 +45,11 @@ import kotlin.streams.toList */ // TODO Move this to tools:bootstrapper class NetworkBootstrapper - @VisibleForTesting - internal constructor(private val initSerEnv: Boolean, - private val embeddedCordaJar: () -> InputStream, - private val nodeInfosGenerator: (List) -> List, - private val contractsJarConverter: (Path) -> ContractsJar) { +@VisibleForTesting +internal constructor(private val initSerEnv: Boolean, + private val embeddedCordaJar: () -> InputStream, + private val nodeInfosGenerator: (List) -> List, + private val contractsJarConverter: (Path) -> ContractsJar) { constructor() : this( initSerEnv = true, @@ -102,7 +101,7 @@ class NetworkBootstrapper process.destroyForcibly() throw IllegalStateException("Error while generating node info file. Please check the logs in $logsDir.") } - check(process.exitValue() == 0) { "Error while generating node info file. Please check the logs in $logsDir." } + check(process.exitValue() == 0) { "Error while generating node info file. Please check the logs in $logsDir." } return nodeDir.list { paths -> paths.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }.findFirst().get() } @@ -269,7 +268,7 @@ class NetworkBootstrapper private fun distributeNodeInfos(nodeDirs: List, nodeInfoFiles: List) { for (nodeDir in nodeDirs) { - val additionalNodeInfosDir = (nodeDir / CordformNode.NODE_INFO_DIRECTORY).createDirectories() + val additionalNodeInfosDir = (nodeDir / NODE_INFO_DIRECTORY).createDirectories() for (nodeInfoFile in nodeInfoFiles) { nodeInfoFile.copyToDirectory(additionalNodeInfosDir, REPLACE_EXISTING) } @@ -364,10 +363,10 @@ class NetworkBootstrapper private fun NodeInfo.notaryIdentity(): Party { return when (legalIdentities.size) { - // Single node notaries have just one identity like all other nodes. This identity is the notary identity + // Single node notaries have just one identity like all other nodes. This identity is the notary identity 1 -> legalIdentities[0] - // Nodes which are part of a distributed notary have a second identity which is the composite identity of the - // cluster and is shared by all the other members. This is the notary identity. + // Nodes which are part of a distributed notary have a second identity which is the composite identity of the + // cluster and is shared by all the other members. This is the notary identity. 2 -> legalIdentities[1] else -> throw IllegalArgumentException("Not sure how to get the notary identity in this scenerio: $this") } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt index f4421535c9..86c3266bb6 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt @@ -1,8 +1,8 @@ package net.corda.nodeapi.internal.network -import net.corda.cordform.CordformNode import net.corda.core.internal.* import net.corda.core.utilities.contextLogger +import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY import rx.Observable import rx.Scheduler import rx.Subscription @@ -96,10 +96,11 @@ class NodeInfoFilesCopier(scheduler: Scheduler = Schedulers.io()) : AutoCloseabl private fun poll() { nodeDataMapBox.locked { for (nodeData in values) { - nodeData.nodeDir.list { paths -> paths - .filter { it.isRegularFile() } - .filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) } - .forEach { processPath(nodeData, it) } + nodeData.nodeDir.list { paths -> + paths + .filter { it.isRegularFile() } + .filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) } + .forEach { processPath(nodeData, it) } } } } @@ -149,7 +150,7 @@ class NodeInfoFilesCopier(scheduler: Scheduler = Schedulers.io()) : AutoCloseabl * Convenience holder for all the paths and files relative to a single node. */ private class NodeData(val nodeDir: Path) { - val additionalNodeInfoDirectory: Path = nodeDir.resolve(CordformNode.NODE_INFO_DIRECTORY) + val additionalNodeInfoDirectory: Path = nodeDir.resolve(NODE_INFO_DIRECTORY) // Map from Path to its lastModifiedTime. val previouslySeenFiles = mutableMapOf() diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapperTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapperTest.kt index 04744c9376..0b265171e6 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapperTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapperTest.kt @@ -1,7 +1,6 @@ package net.corda.nodeapi.internal.network import com.typesafe.config.ConfigFactory -import net.corda.cordform.CordformNode.NODE_INFO_DIRECTORY import net.corda.core.crypto.secureRandomBytes import net.corda.core.crypto.sha256 import net.corda.core.identity.CordaX500Name @@ -11,6 +10,7 @@ import net.corda.core.node.NodeInfo import net.corda.core.serialization.serialize import net.corda.node.services.config.NotaryConfig import net.corda.nodeapi.internal.DEV_ROOT_CA +import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.config.parseAs import net.corda.nodeapi.internal.config.toConfig diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt index d78f7a6bab..abacb8a0e3 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt @@ -1,10 +1,10 @@ package net.corda.nodeapi.internal.network -import net.corda.cordform.CordformNode import net.corda.core.internal.div import net.corda.core.internal.list import net.corda.core.internal.write import net.corda.nodeapi.eventually +import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Rule @@ -34,12 +34,12 @@ class NodeInfoFilesCopierTest { private val rootPath get() = folder.root.toPath() private val scheduler = TestScheduler() - private fun nodeDir(nodeBaseDir : String) = rootPath.resolve(nodeBaseDir).resolve(ORGANIZATION.toLowerCase()) + private fun nodeDir(nodeBaseDir: String) = rootPath.resolve(nodeBaseDir).resolve(ORGANIZATION.toLowerCase()) private val node1RootPath by lazy { nodeDir(NODE_1_PATH) } private val node2RootPath by lazy { nodeDir(NODE_2_PATH) } - private val node1AdditionalNodeInfoPath by lazy { node1RootPath.resolve(CordformNode.NODE_INFO_DIRECTORY) } - private val node2AdditionalNodeInfoPath by lazy { node2RootPath.resolve(CordformNode.NODE_INFO_DIRECTORY) } + private val node1AdditionalNodeInfoPath by lazy { node1RootPath.resolve(NODE_INFO_DIRECTORY) } + private val node2AdditionalNodeInfoPath by lazy { node2RootPath.resolve(NODE_INFO_DIRECTORY) } private lateinit var nodeInfoFilesCopier: NodeInfoFilesCopier diff --git a/node/build.gradle b/node/build.gradle index 1a451aef48..5ba7afdc42 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -71,7 +71,6 @@ dependencies { compile project(":confidential-identities") compile project(':client:rpc') compile project(':tools:shell') - compile "net.corda.plugins:cordform-common:$gradle_plugins_version" // Log4J: logging framework (with SLF4J bindings) compile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}" diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt index 2bf6d30eee..91d4299702 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt @@ -1,6 +1,5 @@ package net.corda.node.services.network -import net.corda.cordform.CordformNode import net.corda.core.concurrent.CordaFuture import net.corda.core.crypto.random63BitValue import net.corda.core.identity.CordaX500Name @@ -12,6 +11,7 @@ import net.corda.core.serialization.serialize import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds import net.corda.node.services.config.configureDevKeyAndTrustStores +import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY import net.corda.nodeapi.internal.config.NodeSSLConfiguration import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME @@ -235,7 +235,7 @@ class NetworkMapTest(var initFunc: (URL, NetworkMapServer) -> CompatibilityZoneP private fun NodeHandle.onlySees(vararg nodes: NodeInfo) { // Make sure the nodes aren't getting the node infos from their additional directories - val nodeInfosDir = baseDirectory / CordformNode.NODE_INFO_DIRECTORY + val nodeInfosDir = baseDirectory / NODE_INFO_DIRECTORY if (nodeInfosDir.exists()) { assertThat(nodeInfosDir.list()).isEmpty() } diff --git a/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt b/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt index dacf99bdf3..cdd370ff8f 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt @@ -1,6 +1,5 @@ package net.corda.node.services.network -import net.corda.cordform.CordformNode import net.corda.core.crypto.SecureHash import net.corda.core.internal.* import net.corda.core.node.NodeInfo @@ -11,6 +10,7 @@ import net.corda.core.utilities.contextLogger import net.corda.core.utilities.debug import net.corda.core.utilities.seconds import net.corda.node.serialization.amqp.AMQPServerSerializationScheme +import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY import net.corda.nodeapi.internal.NodeInfoAndSigned import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.network.NodeInfoFilesCopier @@ -64,7 +64,8 @@ class NodeInfoWatcher(private val nodePath: Path, } internal data class NodeInfoFromFile(val nodeInfohash: SecureHash, val lastModified: FileTime) - private val nodeInfosDir = nodePath / CordformNode.NODE_INFO_DIRECTORY + + private val nodeInfosDir = nodePath / NODE_INFO_DIRECTORY private val nodeInfoFilesMap = HashMap() val processedNodeInfoHashes: Set get() = nodeInfoFilesMap.values.map { it.nodeInfohash }.toSet() @@ -74,7 +75,7 @@ class NodeInfoWatcher(private val nodePath: Path, } /** - * Read all the files contained in [nodePath] / [CordformNode.NODE_INFO_DIRECTORY] and keep watching + * Read all the files contained in [nodePath] / [NODE_INFO_DIRECTORY] and keep watching * the folder for further updates. * * We simply list the directory content every 5 seconds, the Java implementation of WatchService has been proven to diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt index 2d3f2be0c3..ff4de39797 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt @@ -3,7 +3,6 @@ package net.corda.node.services.network import com.google.common.jimfs.Configuration.unix import com.google.common.jimfs.Jimfs import com.nhaarman.mockito_kotlin.* -import net.corda.cordform.CordformNode.NODE_INFO_DIRECTORY import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.crypto.sign @@ -15,6 +14,7 @@ import net.corda.core.node.NodeInfo import net.corda.core.serialization.serialize import net.corda.core.utilities.millis import net.corda.node.services.api.NetworkMapCacheInternal +import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY import net.corda.nodeapi.internal.NodeInfoAndSigned import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME import net.corda.nodeapi.internal.network.NodeInfoFilesCopier diff --git a/node/src/test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt index 1b7a1d8ab9..6fc7abc537 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt @@ -2,11 +2,11 @@ package net.corda.node.services.network import com.google.common.jimfs.Configuration import com.google.common.jimfs.Jimfs -import net.corda.cordform.CordformNode import net.corda.core.internal.createDirectories import net.corda.core.internal.div import net.corda.core.internal.size import net.corda.core.node.services.KeyManagementService +import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY import net.corda.nodeapi.internal.NodeInfoAndSigned import net.corda.nodeapi.internal.network.NodeInfoFilesCopier import net.corda.testing.core.ALICE_NAME @@ -51,7 +51,7 @@ class NodeInfoWatcherTest { val identityService = makeTestIdentityService() keyManagementService = MockKeyManagementService(identityService) nodeInfoWatcher = NodeInfoWatcher(tempFolder.root.toPath(), scheduler) - nodeInfoPath = tempFolder.root.toPath() / CordformNode.NODE_INFO_DIRECTORY + nodeInfoPath = tempFolder.root.toPath() / NODE_INFO_DIRECTORY } @Test diff --git a/samples/bank-of-corda-demo/build.gradle b/samples/bank-of-corda-demo/build.gradle index 56cc8172f8..c05f0172e3 100644 --- a/samples/bank-of-corda-demo/build.gradle +++ b/samples/bank-of-corda-demo/build.gradle @@ -7,21 +7,6 @@ apply plugin: 'net.corda.plugins.cordapp' apply plugin: 'net.corda.plugins.cordformation' apply plugin: 'maven-publish' -sourceSets { - integrationTest { - kotlin { - compileClasspath += main.output + test.output - runtimeClasspath += main.output + test.output - srcDir file('src/integration-test/kotlin') - } - } -} - -configurations { - integrationTestCompile.extendsFrom testCompile - integrationTestRuntime.extendsFrom testRuntime -} - dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" @@ -48,13 +33,46 @@ dependencies { } task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { - // CordformationDefinition is an experimental feature - definitionClass = 'net.corda.bank.BankOfCordaCordform' -} - -task integrationTest(type: Test, dependsOn: []) { - testClassesDirs = sourceSets.integrationTest.output.classesDirs - classpath = sourceSets.integrationTest.runtimeClasspath + nodeDefaults { + cordapp project(':finance') + } + node { + name "O=Notary Service,L=Zurich,C=CH" + notary = [validating: true] + p2pPort 10002 + rpcSettings { + address "localhost:10003" + adminAddress "localhost:10004" + } + extraConfig = [h2Settings: [address: "localhost:10016"]] + } + node { + name "O=BankOfCorda,L=London,C=GB" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10015" + } + webPort 10007 + rpcUsers = [[user: "bankUser", password: "test", permissions: ["ALL"]]] + extraConfig = [ + custom : [issuableCurrencies: ["USD"]], + h2Settings: [address: "localhost:10017"] + ] + } + node { + name "O=BigCorporation,L=New York,C=US" + p2pPort 10008 + rpcSettings { + address "localhost:10009" + adminAddress "localhost:10011" + } + webPort 10010 + rpcUsers = [[user: "bigCorpUser", password: "test", permissions: ["ALL"]]] + extraConfig = [ + h2Settings: [address: "localhost:10018"] + ] + } } idea { diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaCordformTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaCordformTest.kt deleted file mode 100644 index beefbcfc09..0000000000 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaCordformTest.kt +++ /dev/null @@ -1,32 +0,0 @@ -package net.corda.bank - -import net.corda.client.rpc.CordaRPCClient -import net.corda.core.contracts.withoutIssuer -import net.corda.core.utilities.NetworkHostAndPort -import net.corda.finance.DOLLARS -import net.corda.finance.contracts.asset.Cash -import net.corda.finance.utils.sumCash -import net.corda.testing.core.BOC_NAME -import net.corda.testing.node.internal.demorun.nodeRunner -import org.assertj.core.api.Assertions.assertThat -import org.junit.Test - -class BankOfCordaCordformTest { - @Test - fun `run demo`() { - BankOfCordaCordform().nodeRunner().scanPackages(listOf("net.corda.finance")).deployAndRunNodesAndThen { - IssueCash.requestRpcIssue(20000.DOLLARS) - CordaRPCClient(NetworkHostAndPort("localhost", BOC_RPC_PORT)).use(BOC_RPC_USER, BOC_RPC_PWD) { - assertThat(it.proxy.vaultQuery(Cash.State::class.java).states).isEmpty() // All of the issued cash is transferred - } - CordaRPCClient(NetworkHostAndPort("localhost", BIGCORP_RPC_PORT)).use(BIGCORP_RPC_USER, BIGCORP_RPC_PWD) { - val cashStates = it.proxy.vaultQuery(Cash.State::class.java).states.map { it.state.data } - val knownOwner = it.proxy.wellKnownPartyFromAnonymous(cashStates.map { it.owner }.toSet().single()) - assertThat(knownOwner?.name).isEqualTo(BIGCORP_NAME) - val totalCash = cashStates.sumCash() - assertThat(totalCash.token.issuer.party.nameOrNull()).isEqualTo(BOC_NAME) - assertThat(totalCash.withoutIssuer()).isEqualTo(20000.DOLLARS) - } - } - } -} diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaCordform.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaCordform.kt deleted file mode 100644 index 06beee5f5f..0000000000 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaCordform.kt +++ /dev/null @@ -1,149 +0,0 @@ -package net.corda.bank - -import joptsimple.OptionParser -import net.corda.bank.api.BankOfCordaClientApi -import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams -import net.corda.cordform.CordappDependency -import net.corda.cordform.CordformContext -import net.corda.cordform.CordformDefinition -import net.corda.core.contracts.Amount -import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.VisibleForTesting -import net.corda.core.transactions.SignedTransaction -import net.corda.core.utilities.NetworkHostAndPort -import net.corda.node.services.Permissions.Companion.all -import net.corda.node.services.config.NotaryConfig -import net.corda.testing.node.internal.demorun.* -import net.corda.testing.core.BOC_NAME -import net.corda.testing.node.User -import java.util.* -import kotlin.system.exitProcess - -val BIGCORP_NAME = CordaX500Name(organisation = "BigCorporation", locality = "New York", country = "US") -private val NOTARY_NAME = CordaX500Name(organisation = "Notary Service", locality = "Zurich", country = "CH") -const val BOC_RPC_PORT = 10006 -const val BIGCORP_RPC_PORT = 10009 -private const val BOC_RPC_ADMIN_PORT = 10015 -private const val BOC_WEB_PORT = 10007 - -const val BOC_RPC_USER = "bankUser" -const val BOC_RPC_PWD = "test" - -const val BIGCORP_RPC_USER = "bigCorpUser" -const val BIGCORP_RPC_PWD = "test" - -class BankOfCordaCordform : CordformDefinition() { - - init { - node { - name(NOTARY_NAME) - notary(NotaryConfig(validating = true)) - p2pPort(10002) - rpcSettings { - address("localhost:10003") - adminAddress("localhost:10004") - } - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:10016")) - } - node { - name(BOC_NAME) - extraConfig = mapOf("custom" to mapOf("issuableCurrencies" to listOf("USD")), - "h2Settings" to mapOf("address" to "localhost:10017")) - p2pPort(10005) - rpcSettings { - address("localhost:$BOC_RPC_PORT") - adminAddress("localhost:$BOC_RPC_ADMIN_PORT") - } - webPort(BOC_WEB_PORT) - rpcUsers(User(BOC_RPC_USER, BOC_RPC_PWD, setOf(all()))) - devMode(true) - } - node { - name(BIGCORP_NAME) - p2pPort(10008) - rpcSettings { - address("localhost:$BIGCORP_RPC_PORT") - adminAddress("localhost:10011") - } - webPort(10010) - rpcUsers(User(BIGCORP_RPC_USER, BIGCORP_RPC_PWD, setOf(all()))) - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:10018")) - } - } - - override fun setup(context: CordformContext) = Unit - - override fun getCordappDependencies(): List { - return listOf(CordappDependency(":finance")) - } -} - -object DeployNodes { - @JvmStatic - fun main(args: Array) { - BankOfCordaCordform().nodeRunner().scanPackages(listOf("net.corda.finance")).deployAndRunNodes() - } -} - -object IssueCash { - @JvmStatic - fun main(args: Array) { - val parser = OptionParser() - val roleArg = parser.accepts("role").withRequiredArg().ofType(Role::class.java).describedAs("[ISSUER|ISSUE_CASH_RPC|ISSUE_CASH_WEB]") - val quantity = parser.accepts("quantity").withOptionalArg().ofType(Long::class.java) - val currency = parser.accepts("currency").withOptionalArg().ofType(String::class.java).describedAs("[GBP|USD|CHF|EUR]") - val options = try { - parser.parse(*args) - } catch (e: Exception) { - println(e.message) - printHelp(parser) - exitProcess(1) - } - - val role = options.valueOf(roleArg)!! - val amount = Amount(options.valueOf(quantity), Currency.getInstance(options.valueOf(currency))) - when (role) { - Role.ISSUE_CASH_RPC -> { - println("Requesting Cash via RPC ...") - val result = requestRpcIssue(amount) - println("Success!! Your transaction receipt is ${result.tx.id}") - } - Role.ISSUE_CASH_WEB -> { - println("Requesting Cash via Web ...") - requestWebIssue(amount) - println("Successfully processed Cash Issue request") - } - } - } - - @VisibleForTesting - fun requestRpcIssue(amount: Amount): SignedTransaction { - return BankOfCordaClientApi.requestRPCIssue(NetworkHostAndPort("localhost", BOC_RPC_PORT), createParams(amount, NOTARY_NAME)) - } - - private fun requestWebIssue(amount: Amount) { - BankOfCordaClientApi.requestWebIssue(NetworkHostAndPort("localhost", BOC_WEB_PORT), createParams(amount, NOTARY_NAME)) - } - - private fun createParams(amount: Amount, notaryName: CordaX500Name): IssueRequestParams { - return IssueRequestParams(amount, BIGCORP_NAME, "1", BOC_NAME, notaryName) - } - - private fun printHelp(parser: OptionParser) { - println(""" - Usage: bank-of-corda --role ISSUER - bank-of-corda --role (ISSUE_CASH_RPC|ISSUE_CASH_WEB) --quantity --currency - - Please refer to the documentation in docs/build/index.html for more info. - - """.trimIndent()) - parser.printHelpOn(System.out) - } - - enum class Role { - ISSUE_CASH_RPC, - ISSUE_CASH_WEB, - } -} diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/IssueCash.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/IssueCash.kt new file mode 100644 index 0000000000..24ac13e1d1 --- /dev/null +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/IssueCash.kt @@ -0,0 +1,77 @@ +package net.corda.bank + +import joptsimple.OptionParser +import net.corda.bank.api.BankOfCordaClientApi +import net.corda.bank.api.BankOfCordaWebApi +import net.corda.core.contracts.Amount +import net.corda.core.identity.CordaX500Name +import net.corda.core.internal.VisibleForTesting +import net.corda.core.transactions.SignedTransaction +import net.corda.core.utilities.NetworkHostAndPort +import net.corda.testing.core.BOC_NAME +import java.util.* +import kotlin.system.exitProcess + +object IssueCash { + private val NOTARY_NAME = CordaX500Name(organisation = "Notary Service", locality = "Zurich", country = "CH") + private val BIGCORP_NAME = CordaX500Name(organisation = "BigCorporation", locality = "New York", country = "US") + private const val BOC_RPC_PORT = 10006 + private const val BOC_WEB_PORT = 10007 + + @JvmStatic + fun main(args: Array) { + val parser = OptionParser() + val roleArg = parser.accepts("role").withRequiredArg().ofType(Role::class.java).describedAs("[ISSUER|ISSUE_CASH_RPC|ISSUE_CASH_WEB]") + val quantity = parser.accepts("quantity").withOptionalArg().ofType(Long::class.java) + val currency = parser.accepts("currency").withOptionalArg().ofType(String::class.java).describedAs("[GBP|USD|CHF|EUR]") + val options = try { + parser.parse(*args) + } catch (e: Exception) { + println(e.message) + printHelp(parser) + exitProcess(1) + } + + val role = options.valueOf(roleArg)!! + val amount = Amount(options.valueOf(quantity), Currency.getInstance(options.valueOf(currency))) + when (role) { + Role.ISSUE_CASH_RPC -> { + println("Requesting Cash via RPC ...") + val result = requestRpcIssue(amount) + println("Success!! Your transaction receipt is ${result.tx.id}") + } + Role.ISSUE_CASH_WEB -> { + println("Requesting Cash via Web ...") + requestWebIssue(amount) + println("Successfully processed Cash Issue request") + } + } + } + + @VisibleForTesting + fun requestRpcIssue(amount: Amount): SignedTransaction { + return BankOfCordaClientApi.requestRPCIssue(NetworkHostAndPort("localhost", BOC_RPC_PORT), createParams(amount, NOTARY_NAME)) + } + + private fun requestWebIssue(amount: Amount) { + BankOfCordaClientApi.requestWebIssue(NetworkHostAndPort("localhost", BOC_WEB_PORT), createParams(amount, NOTARY_NAME)) + } + + private fun createParams(amount: Amount, notaryName: CordaX500Name): BankOfCordaWebApi.IssueRequestParams { + return BankOfCordaWebApi.IssueRequestParams(amount, BIGCORP_NAME, "1", BOC_NAME, notaryName) + } + + private fun printHelp(parser: OptionParser) { + println(""" + Usage: bank-of-corda --role ISSUER + bank-of-corda --role (ISSUE_CASH_RPC|ISSUE_CASH_WEB) --quantity --currency + Please refer to the documentation in docs/build/index.html for more info. + """.trimIndent()) + parser.printHelpOn(System.out) + } + + enum class Role { + ISSUE_CASH_RPC, + ISSUE_CASH_WEB, + } +} \ No newline at end of file diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt index 3daf76c8f7..dd79412e77 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt @@ -1,7 +1,5 @@ package net.corda.bank.api -import net.corda.bank.BOC_RPC_PWD -import net.corda.bank.BOC_RPC_USER import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams import net.corda.client.rpc.CordaRPCClient import net.corda.core.messaging.startFlow @@ -16,6 +14,9 @@ import net.corda.testing.http.HttpApi * Interface for communicating with Bank of Corda node */ object BankOfCordaClientApi { + const val BOC_RPC_USER = "bankUser" + const val BOC_RPC_PWD = "test" + /** * HTTP API */ @@ -40,7 +41,8 @@ object BankOfCordaClientApi { // Resolve parties via RPC val issueToParty = rpc.wellKnownPartyFromX500Name(params.issueToPartyName) ?: throw IllegalStateException("Unable to locate ${params.issueToPartyName} in Network Map Service") - val notaryLegalIdentity = rpc.notaryIdentities().firstOrNull { it.name == params.notaryName } ?: throw IllegalStateException("Couldn't locate notary ${params.notaryName} in NetworkMapCache") + val notaryLegalIdentity = rpc.notaryIdentities().firstOrNull { it.name == params.notaryName } + ?: throw IllegalStateException("Couldn't locate notary ${params.notaryName} in NetworkMapCache") val anonymous = true val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte()) diff --git a/samples/notary-demo/build.gradle b/samples/notary-demo/build.gradle index 5012912a8c..081546b3ff 100644 --- a/samples/notary-demo/build.gradle +++ b/samples/notary-demo/build.gradle @@ -49,19 +49,229 @@ publishing { task deployNodes(dependsOn: ['deployNodesSingle', 'deployNodesRaft', 'deployNodesBFT', 'deployNodesCustom']) task deployNodesSingle(type: Cordform, dependsOn: 'jar') { - definitionClass = 'net.corda.notarydemo.SingleNotaryCordform' + directory file("$buildDir/nodes/nodesSingle") + nodeDefaults { + extraConfig = [h2Settings: [address: "localhost:0"]] + } + node { + name "O=Alice Corp,L=Madrid,C=ES" + p2pPort 10002 + rpcSettings { + address "localhost:10003" + adminAddress "localhost:10103" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10106" + } + } + node { + name "O=Notary Service,L=Zurich,C=CH" + p2pPort 10009 + rpcSettings { + address "localhost:10010" + adminAddress "localhost:10110" + } + notary = [validating: true] + } } task deployNodesCustom(type: Cordform, dependsOn: 'jar') { - definitionClass = 'net.corda.notarydemo.CustomNotaryCordform' + directory file("$buildDir/nodes/nodesCustom") + nodeDefaults { + extraConfig = [h2Settings: [address: "localhost:0"]] + } + node { + name "O=Alice Corp,L=Madrid,C=ES" + p2pPort 10002 + rpcSettings { + address "localhost:10003" + adminAddress "localhost:10103" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10106" + } + } + node { + name "O=Notary Service,L=Zurich,C=CH" + p2pPort 10009 + rpcSettings { + address "localhost:10010" + adminAddress "localhost:10110" + } + notary = [validating: true, "custom": true] + } } task deployNodesRaft(type: Cordform, dependsOn: 'jar') { - definitionClass = 'net.corda.notarydemo.RaftNotaryCordform' + directory file("$buildDir/nodes/nodesRaft") + nodeDefaults { + extraConfig = [h2Settings: [address: "localhost:0"]] + } + node { + name "O=Alice Corp,L=Madrid,C=ES" + p2pPort 10002 + rpcSettings { + address "localhost:10003" + adminAddress "localhost:10103" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10106" + } + } + node { + name "O=Notary Service 0,L=Zurich,C=CH" + p2pPort 10009 + rpcSettings { + address "localhost:10010" + adminAddress "localhost:10110" + } + notary = [ + validating: true, + serviceLegalName: "O=Raft,L=Zurich,C=CH", + raft: [ + nodeAddress: "localhost:10008" + ] + ] + } + node { + name "O=Notary Service 1,L=Zurich,C=CH" + p2pPort 10013 + rpcSettings { + address "localhost:10014" + adminAddress "localhost:10114" + } + notary = [ + validating: true, + serviceLegalName: "O=Raft,L=Zurich,C=CH", + raft: [ + nodeAddress: "localhost:10012", + clusterAddresses: ["localhost:10008"] + ] + ] + } + node { + name "O=Notary Service 2,L=Zurich,C=CH" + p2pPort 10017 + rpcSettings { + address "localhost:10018" + adminAddress "localhost:10118" + } + notary = [ + validating: true, + serviceLegalName: "O=Raft,L=Zurich,C=CH", + raft: [ + nodeAddress: "localhost:10016", + clusterAddresses: ["localhost:10008"] + ] + ] + } } task deployNodesBFT(type: Cordform, dependsOn: 'jar') { - definitionClass = 'net.corda.notarydemo.BFTNotaryCordform' + def clusterAddresses = ["localhost:11000", "localhost:11010", "localhost:11020", "localhost:11030"] + directory file("$buildDir/nodes/nodesBFT") + nodeDefaults { + extraConfig = [h2Settings: [address: "localhost:0"]] + } + node { + name "O=Alice Corp,L=Madrid,C=ES" + p2pPort 10002 + rpcSettings { + address "localhost:10003" + adminAddress "localhost:10103" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10106" + } + } + node { + name "O=Notary Service 0,L=Zurich,C=CH" + p2pPort 10009 + rpcSettings { + address "localhost:10010" + adminAddress "localhost:10110" + } + notary = [ + validating: false, + serviceLegalName: "O=BFT,L=Zurich,C=CH", + bftSMaRt: [ + replicaId: 0, + clusterAddresses: clusterAddresses + ] + ] + } + node { + name "O=Notary Service 1,L=Zurich,C=CH" + p2pPort 10013 + rpcSettings { + address "localhost:10014" + adminAddress "localhost:10114" + } + notary = [ + validating: false, + serviceLegalName: "O=BFT,L=Zurich,C=CH", + bftSMaRt: [ + replicaId: 0, + clusterAddresses: clusterAddresses + ] + ] + } + node { + name "O=Notary Service 2,L=Zurich,C=CH" + p2pPort 10017 + rpcSettings { + address "localhost:10018" + adminAddress "localhost:10118" + } + notary = [ + validating: false, + serviceLegalName: "O=BFT,L=Zurich,C=CH", + bftSMaRt: [ + replicaId: 0, + clusterAddresses: clusterAddresses + ] + ] + } + node { + name "O=Notary Service 3,L=Zurich,C=CH" + p2pPort 10021 + rpcSettings { + address "localhost:10022" + adminAddress "localhost:10122" + } + notary = [ + validating: false, + serviceLegalName: "O=BFT,L=Zurich,C=CH", + bftSMaRt: [ + replicaId: 0, + clusterAddresses: clusterAddresses + ] + ] + } } task notarise(type: JavaExec) { diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt deleted file mode 100644 index 04e045c115..0000000000 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt +++ /dev/null @@ -1,93 +0,0 @@ -package net.corda.notarydemo - -import net.corda.cordform.CordformContext -import net.corda.cordform.CordformDefinition -import net.corda.cordform.CordformNode -import net.corda.core.identity.CordaX500Name -import net.corda.core.utilities.NetworkHostAndPort -import net.corda.node.services.config.BFTSMaRtConfiguration -import net.corda.node.services.config.NotaryConfig -import net.corda.node.services.transactions.minCorrectReplicas -import net.corda.nodeapi.internal.DevIdentityGenerator -import net.corda.testing.node.internal.demorun.* -import net.corda.testing.core.ALICE_NAME -import net.corda.testing.core.BOB_NAME -import java.nio.file.Paths - -fun main(args: Array) = BFTNotaryCordform().nodeRunner().deployAndRunNodes() - -private const val clusterSize = 4 // Minimum size that tolerates a faulty replica. -private val notaryNames = createNotaryNames(clusterSize) - -// This is not the intended final design for how to use CordformDefinition, please treat this as experimental and DO -// NOT use this as a design to copy. -class BFTNotaryCordform : CordformDefinition() { - private val clusterName = CordaX500Name("BFT", "Zurich", "CH") - - init { - nodesDirectory = Paths.get("build", "nodes", "nodesBFT") - node { - name(ALICE_NAME) - p2pPort(10002) - rpcSettings { - address("localhost:10003") - adminAddress("localhost:10103") - } - rpcUsers(notaryDemoUser) - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - node { - name(BOB_NAME) - p2pPort(10005) - rpcSettings { - address("localhost:10006") - adminAddress("localhost:10106") - } - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - val clusterAddresses = (0 until clusterSize).map { NetworkHostAndPort("localhost", 11000 + it * 10) } - fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node { - name(notaryNames[replicaId]) - notary(NotaryConfig(validating = false, serviceLegalName = clusterName, bftSMaRt = BFTSMaRtConfiguration(replicaId, clusterAddresses))) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - configure() - } - notaryNode(0) { - p2pPort(10009) - rpcSettings { - address("localhost:10010") - adminAddress("localhost:10110") - } - devMode(true) - } - notaryNode(1) { - p2pPort(10013) - rpcSettings { - address("localhost:10014") - adminAddress("localhost:10114") - } - devMode(true) - } - notaryNode(2) { - p2pPort(10017) - rpcSettings { - address("localhost:10018") - adminAddress("localhost:10118") - } - devMode(true) - } - notaryNode(3) { - p2pPort(10021) - rpcSettings { - address("localhost:10022") - adminAddress("localhost:10122") - } - devMode(true) - } - } - - override fun setup(context: CordformContext) { - } -} diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Clean.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Clean.kt deleted file mode 100644 index 2fbba77b26..0000000000 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Clean.kt +++ /dev/null @@ -1,9 +0,0 @@ -package net.corda.notarydemo - -import net.corda.testing.node.internal.demorun.nodeRunner - -fun main(args: Array) { - listOf(SingleNotaryCordform(), RaftNotaryCordform(), BFTNotaryCordform()).map { it.nodeRunner() }.forEach { - it.clean() - } -} diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/CustomNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/CustomNotaryCordform.kt deleted file mode 100644 index 21e87c5650..0000000000 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/CustomNotaryCordform.kt +++ /dev/null @@ -1,52 +0,0 @@ -package net.corda.notarydemo - -import net.corda.cordform.CordformContext -import net.corda.cordform.CordformDefinition -import net.corda.node.services.config.NotaryConfig -import net.corda.testing.node.internal.demorun.* -import net.corda.testing.core.ALICE_NAME -import net.corda.testing.core.BOB_NAME -import net.corda.testing.core.DUMMY_NOTARY_NAME -import java.nio.file.Paths - -fun main(args: Array) = CustomNotaryCordform().nodeRunner().deployAndRunNodes() - -class CustomNotaryCordform : CordformDefinition() { - init { - nodesDirectory = Paths.get("build", "nodes", "nodesCustom") - node { - name(ALICE_NAME) - p2pPort(10002) - rpcSettings { - address("localhost:10003") - adminAddress("localhost:10103") - } - rpcUsers(notaryDemoUser) - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - node { - name(BOB_NAME) - p2pPort(10005) - rpcSettings { - address("localhost:10006") - adminAddress("localhost:10106") - } - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - node { - name(DUMMY_NOTARY_NAME) - p2pPort(10009) - rpcSettings { - address("localhost:10010") - adminAddress("localhost:10110") - } - notary(NotaryConfig(validating = true, custom = true)) - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - } - - override fun setup(context: CordformContext) {} -} \ No newline at end of file diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt index 25a320a1a9..1de2b92219 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt @@ -17,7 +17,7 @@ import java.util.concurrent.Future fun main(args: Array) { val address = NetworkHostAndPort("localhost", 10003) println("Connecting to the recipient node ($address)") - CordaRPCClient(address).start(notaryDemoUser.username, notaryDemoUser.password).use { + CordaRPCClient(address).start("demou", "demop").use { NotaryDemoClientApi(it.proxy).notarise(10) } } diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt deleted file mode 100644 index 6de371c3e6..0000000000 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt +++ /dev/null @@ -1,86 +0,0 @@ -package net.corda.notarydemo - -import net.corda.cordform.CordformContext -import net.corda.cordform.CordformDefinition -import net.corda.cordform.CordformNode -import net.corda.core.identity.CordaX500Name -import net.corda.core.utilities.NetworkHostAndPort -import net.corda.node.services.config.NotaryConfig -import net.corda.node.services.config.RaftConfig -import net.corda.nodeapi.internal.DevIdentityGenerator -import net.corda.testing.node.internal.demorun.* -import net.corda.testing.core.ALICE_NAME -import net.corda.testing.core.BOB_NAME -import java.nio.file.Paths - -fun main(args: Array) = RaftNotaryCordform().nodeRunner().deployAndRunNodes() - -internal fun createNotaryNames(clusterSize: Int) = (0 until clusterSize).map { CordaX500Name("Notary Service $it", "Zurich", "CH") } - -private val notaryNames = createNotaryNames(3) - -// This is not the intended final design for how to use CordformDefinition, please treat this as experimental and DO -// NOT use this as a design to copy. -class RaftNotaryCordform : CordformDefinition() { - private val clusterName = CordaX500Name("Raft", "Zurich", "CH") - - init { - nodesDirectory = Paths.get("build", "nodes", "nodesRaft") - node { - name(ALICE_NAME) - p2pPort(10002) - rpcSettings { - address("localhost:10003") - adminAddress("localhost:10103") - } - rpcUsers(notaryDemoUser) - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - node { - name(BOB_NAME) - p2pPort(10005) - rpcSettings { - address("localhost:10006") - adminAddress("localhost:10106") - } - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node { - name(notaryNames[index]) - val clusterAddresses = if (clusterPort != null) listOf(NetworkHostAndPort("localhost", clusterPort)) else emptyList() - notary(NotaryConfig(validating = true, serviceLegalName = clusterName, raft = RaftConfig(NetworkHostAndPort("localhost", nodePort), clusterAddresses))) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - configure() - devMode(true) - } - notaryNode(0, 10008) { - p2pPort(10009) - rpcSettings { - address("localhost:10010") - adminAddress("localhost:10110") - } - devMode(true) - } - notaryNode(1, 10012, 10008) { - p2pPort(10013) - rpcSettings { - address("localhost:10014") - adminAddress("localhost:10114") - } - devMode(true) - } - notaryNode(2, 10016, 10008) { - p2pPort(10017) - rpcSettings { - address("localhost:10018") - adminAddress("localhost:10118") - } - devMode(true) - } - } - - override fun setup(context: CordformContext) { - } -} diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt deleted file mode 100644 index b2ebaac841..0000000000 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt +++ /dev/null @@ -1,58 +0,0 @@ -package net.corda.notarydemo - -import net.corda.cordform.CordformContext -import net.corda.cordform.CordformDefinition -import net.corda.node.services.Permissions.Companion.all -import net.corda.node.services.config.NotaryConfig -import net.corda.testing.core.ALICE_NAME -import net.corda.testing.core.BOB_NAME -import net.corda.testing.core.DUMMY_NOTARY_NAME -import net.corda.testing.node.User -import net.corda.testing.node.internal.demorun.* -import java.nio.file.Paths - -fun main(args: Array) = SingleNotaryCordform().nodeRunner().deployAndRunNodes() - -val notaryDemoUser = User("demou", "demop", setOf(all())) - -// This is not the intended final design for how to use CordformDefinition, please treat this as experimental and DO -// NOT use this as a design to copy. -class SingleNotaryCordform : CordformDefinition() { - init { - nodesDirectory = Paths.get("build", "nodes", "nodesSingle") - node { - name(ALICE_NAME) - p2pPort(10002) - rpcSettings { - address("localhost:10003") - adminAddress("localhost:10103") - } - rpcUsers(notaryDemoUser) - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - node { - name(BOB_NAME) - p2pPort(10005) - rpcSettings { - address("localhost:10006") - adminAddress("localhost:10106") - } - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - node { - name(DUMMY_NOTARY_NAME) - p2pPort(10009) - rpcSettings { - address("localhost:10010") - adminAddress("localhost:10110") - } - notary(NotaryConfig(validating = true)) - devMode(true) - extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0")) - } - } - - override fun setup(context: CordformContext) {} -} diff --git a/testing/node-driver/build.gradle b/testing/node-driver/build.gradle index 90f551c4aa..102249761e 100644 --- a/testing/node-driver/build.gradle +++ b/testing/node-driver/build.gradle @@ -26,7 +26,6 @@ sourceSets { dependencies { compile project(':test-utils') - compile "net.corda.plugins:cordform-common:$gradle_plugins_version" // Integration test helpers testCompile "org.assertj:assertj-core:$assertj_version" diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index 4d5cfce1aa..10f6392bd1 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -1,14 +1,11 @@ package net.corda.testing.node.internal -import com.google.common.collect.HashMultimap import com.google.common.util.concurrent.ThreadFactoryBuilder import com.typesafe.config.Config import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigRenderOptions import com.typesafe.config.ConfigValueFactory import net.corda.client.rpc.internal.createCordaRPCClientWithInternalSslAndClassLoader -import net.corda.cordform.CordformContext -import net.corda.cordform.CordformNode import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.firstOf import net.corda.core.identity.CordaX500Name @@ -33,7 +30,6 @@ import net.corda.node.utilities.registration.NodeRegistrationHelper import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.addShutdownHook -import net.corda.nodeapi.internal.config.parseAs import net.corda.nodeapi.internal.config.toConfig import net.corda.nodeapi.internal.crypto.X509KeyStore import net.corda.nodeapi.internal.crypto.X509Utilities @@ -52,8 +48,6 @@ import net.corda.testing.internal.setGlobalSerialization import net.corda.testing.node.ClusterSpec import net.corda.testing.node.NotarySpec import net.corda.testing.node.User -import net.corda.testing.node.internal.DriverDSLImpl.ClusterType.NON_VALIDATING_RAFT -import net.corda.testing.node.internal.DriverDSLImpl.ClusterType.VALIDATING_RAFT import net.corda.testing.node.internal.DriverDSLImpl.Companion.cordappsInCurrentAndAdditionalPackages import okhttp3.OkHttpClient import okhttp3.Request @@ -309,97 +303,6 @@ class DriverDSLImpl( NON_VALIDATING_BFT(false, CordaX500Name("BFT", "Zurich", "CH")) } - // TODO remove this - internal fun startCordformNodes(cordforms: List): CordaFuture<*> { - check(notarySpecs.isEmpty()) { "Specify notaries in the CordformDefinition" } - check(compatibilityZone == null) { "Cordform nodes cannot be run with compatibilityZoneURL" } - - val clusterNodes = HashMultimap.create() - val notaryInfos = ArrayList() - - // Go though the node definitions and pick out the notaries so that we can generate their identities to be used - // in the network parameters - for (cordform in cordforms) { - if (cordform.notary == null) continue - val name = CordaX500Name.parse(cordform.name) - val notaryConfig = ConfigFactory.parseMap(cordform.notary).parseAs() - // We need to first group the nodes that form part of a cluster. We assume for simplicity that nodes of the - // same cluster type and validating flag are part of the same cluster. - when { - notaryConfig.raft != null -> { - val key = if (notaryConfig.validating) VALIDATING_RAFT else NON_VALIDATING_RAFT - clusterNodes.put(key, name) - } - notaryConfig.bftSMaRt != null -> clusterNodes.put(ClusterType.NON_VALIDATING_BFT, name) - else -> { - // We have all we need here to generate the identity for single node notaries - val identity = DevIdentityGenerator.installKeyStoreWithNodeIdentity(baseDirectory(name), legalName = name) - notaryInfos += NotaryInfo(identity, notaryConfig.validating) - } - } - } - - clusterNodes.asMap().forEach { type, nodeNames -> - val identity = if (type == ClusterType.NON_VALIDATING_RAFT || type == ClusterType.VALIDATING_RAFT) { - DevIdentityGenerator.generateDistributedNotarySingularIdentity( - dirs = nodeNames.map { baseDirectory(it) }, - notaryName = type.clusterName - ) - } else { - DevIdentityGenerator.generateDistributedNotaryCompositeIdentity( - dirs = nodeNames.map { baseDirectory(it) }, - notaryName = type.clusterName - ) - } - notaryInfos += NotaryInfo(identity, type.validating) - } - - val localNetworkMap = LocalNetworkMap(notaryInfos) - - return cordforms.map { - val startedNode = startCordformNode(it, localNetworkMap) - if (it.webAddress != null) { - // Start a webserver if an address for it was specified - startedNode.flatMap { startWebserver(it) } - } else { - startedNode - } - }.transpose() - } - - // TODO remove this - private fun startCordformNode(cordform: CordformNode, localNetworkMap: LocalNetworkMap): CordaFuture { - val name = CordaX500Name.parse(cordform.name) - // TODO We shouldn't have to allocate an RPC or web address if they're not specified. We're having to do this because of startNodeInternal - val rpcAddress = if (cordform.rpcAddress == null) { - val overrides = mutableMapOf("rpcSettings.address" to portAllocation.nextHostAndPort().toString()) - cordform.config.apply { - overrides += "rpcSettings.adminAddress" to portAllocation.nextHostAndPort().toString() - } - overrides - } else { - val overrides = mutableMapOf() - cordform.config.apply { - overrides += "rpcSettings.adminAddress" to portAllocation.nextHostAndPort().toString() - } - overrides - } - val webAddress = cordform.webAddress?.let { NetworkHostAndPort.parse(it) } ?: portAllocation.nextHostAndPort() - val notary = if (cordform.notary != null) mapOf("notary" to cordform.notary) else emptyMap() - val rpcUsers = cordform.rpcUsers - - val rawConfig = cordform.config + rpcAddress + notary + mapOf( - "rpcUsers" to if (rpcUsers.isEmpty()) defaultRpcUserList else rpcUsers - ) - val typesafe = ConfigHelper.loadConfig( - baseDirectory = baseDirectory(name), - allowMissingConfig = true, - configOverrides = rawConfig.toNodeOnly() - ) - val config = NodeConfig(typesafe).checkAndOverrideForInMemoryDB() - return startNodeInternal(config, webAddress, null, "512m", localNetworkMap, emptySet()) - } - @Suppress("DEPRECATION") private fun queryWebserver(handle: NodeHandle, process: Process): WebserverHandle { val protocol = if ((handle as NodeHandleInternal).useHTTPS) "https://" else "http://" @@ -993,7 +896,7 @@ private class NetworkVisibilityController { } } -interface InternalDriverDSL : DriverDSL, CordformContext { +interface InternalDriverDSL : DriverDSL { private companion object { private val DEFAULT_POLL_INTERVAL = 500.millis private const val DEFAULT_WARN_COUNT = 120 @@ -1001,7 +904,7 @@ interface InternalDriverDSL : DriverDSL, CordformContext { val shutdownManager: ShutdownManager - override fun baseDirectory(nodeName: String): Path = baseDirectory(CordaX500Name.parse(nodeName)) + fun baseDirectory(nodeName: String): Path = baseDirectory(CordaX500Name.parse(nodeName)) /** * Polls a function until it returns a non-null value. Note that there is no timeout on the polling. @@ -1205,4 +1108,5 @@ private fun Config.toNodeOnly(): Config { return if (hasPath("webAddress")) withoutPath("webAddress").withoutPath("useHTTPS") else this } -internal fun DriverParameters.cordappsForAllNodes(): Set = cordappsForAllNodes ?: cordappsInCurrentAndAdditionalPackages(extraCordappPackagesToScan) \ No newline at end of file +internal fun DriverParameters.cordappsForAllNodes(): Set = cordappsForAllNodes + ?: cordappsInCurrentAndAdditionalPackages(extraCordappPackagesToScan) \ No newline at end of file diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformNodeRunner.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformNodeRunner.kt deleted file mode 100644 index c023e7cf46..0000000000 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformNodeRunner.kt +++ /dev/null @@ -1,78 +0,0 @@ -package net.corda.testing.node.internal.demorun - -import net.corda.cordform.CordformDefinition -import net.corda.cordform.CordformNode -import net.corda.core.internal.deleteRecursively -import net.corda.core.utilities.NetworkHostAndPort -import net.corda.core.utilities.getOrThrow -import net.corda.testing.driver.JmxPolicy -import net.corda.testing.driver.PortAllocation -import net.corda.testing.node.internal.DriverDSLImpl.Companion.cordappsInCurrentAndAdditionalPackages -import net.corda.testing.node.internal.internalDriver - -/** - * Creates a demo runner for this cordform definition - */ -fun CordformDefinition.nodeRunner() = CordformNodeRunner(this) - -/** - * A node runner creates and runs nodes for a given [[CordformDefinition]]. - */ -class CordformNodeRunner(private val cordformDefinition: CordformDefinition) { - private var extraPackagesToScan = emptyList() - - /** - * Builder method to sets the extra cordapp scan packages - */ - fun scanPackages(packages: List): CordformNodeRunner { - extraPackagesToScan = packages - return this - } - - fun clean() { - System.err.println("Deleting: ${cordformDefinition.nodesDirectory}") - cordformDefinition.nodesDirectory.deleteRecursively() - } - - /** - * Deploy the nodes specified in the given [CordformDefinition]. This will block until all the nodes and webservers - * have terminated. - */ - fun deployAndRunNodes() { - runNodes(waitForAllNodesToFinish = true) { } - } - - /** - * Deploy the nodes specified in the given [CordformDefinition] and then execute the given [block] once all the nodes - * and webservers are up. After execution all these processes will be terminated. - */ - fun deployAndRunNodesAndThen(block: () -> Unit) { - runNodes(waitForAllNodesToFinish = false, block = block) - } - - private fun runNodes(waitForAllNodesToFinish: Boolean, block: () -> Unit) { - clean() - val nodes = cordformDefinition.nodeConfigurers.map { configurer -> CordformNode().also { configurer.accept(it) } } - val maxPort = nodes - .flatMap { listOf(it.p2pAddress, it.rpcAddress, it.webAddress) } - .mapNotNull { address -> address?.let { NetworkHostAndPort.parse(it).port } } - .max()!! - internalDriver( - jmxPolicy = JmxPolicy(true), - driverDirectory = cordformDefinition.nodesDirectory, - // Notaries are manually specified in Cordform so we don't want the driver automatically starting any - notarySpecs = emptyList(), - // Start from after the largest port used to prevent port clash - portAllocation = PortAllocation.Incremental(maxPort + 1), - waitForAllNodesToFinish = waitForAllNodesToFinish, - cordappsForAllNodes = cordappsInCurrentAndAdditionalPackages(extraPackagesToScan) - ) { - cordformDefinition.setup(this) - startCordformNodes(nodes).getOrThrow() // Only proceed once everything is up and running - println("All nodes and webservers are ready...") - block() - } - } -} - - diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformUtils.kt deleted file mode 100644 index b40b1695e2..0000000000 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformUtils.kt +++ /dev/null @@ -1,34 +0,0 @@ -@file:JvmName("CordformUtils") - -package net.corda.testing.node.internal.demorun - -import net.corda.cordform.CordformDefinition -import net.corda.cordform.CordformNode -import net.corda.cordform.RpcSettings -import net.corda.cordform.SslOptions -import net.corda.core.identity.CordaX500Name -import net.corda.node.services.config.NotaryConfig -import net.corda.nodeapi.internal.config.toConfig -import net.corda.testing.node.User - -fun CordformDefinition.node(configure: CordformNode.() -> Unit) { - addNode { cordformNode -> cordformNode.configure() } -} - -fun CordformNode.name(name: CordaX500Name) = name(name.toString()) - -fun CordformNode.rpcUsers(vararg users: User) { - rpcUsers = users.map { it.toConfig().root().unwrapped() } -} - -fun CordformNode.notary(notaryConfig: NotaryConfig) { - notary = notaryConfig.toConfig().root().unwrapped() -} - -fun CordformNode.rpcSettings(configure: RpcSettings.() -> Unit) { - RpcSettings().also(configure).also(this::rpcSettings) -} - -fun RpcSettings.ssl(configure: SslOptions.() -> Unit) { - SslOptions().also(configure).also(this::ssl) -} \ No newline at end of file diff --git a/tools/demobench/build.gradle b/tools/demobench/build.gradle index 9083d042b0..d62249294a 100644 --- a/tools/demobench/build.gradle +++ b/tools/demobench/build.gradle @@ -56,8 +56,6 @@ dependencies { // Controls FX: more java FX components http://fxexperience.com/controlsfx/ compile "org.controlsfx:controlsfx:$controlsfx_version" - compile "net.corda.plugins:cordform-common:$gradle_plugins_version" - compile project(':client:rpc') compile project(':finance')