From 8585ade59986240059a4bb866dd56b1724be0f8e Mon Sep 17 00:00:00 2001 From: Stefano Franz Date: Wed, 18 Jul 2018 15:26:49 +0100 Subject: [PATCH] Netowrk Bootstrapper CLI enhancements (#3634) --- .../src/main/kotlin/net/corda/bootstrapper/Main.kt | 9 ++++++++- .../kotlin/net/corda/bootstrapper/NetworkBuilder.kt | 7 ------- .../corda/bootstrapper/cli/CommandLineInterface.kt | 4 ++-- .../net/corda/bootstrapper/cli/CommandParsers.kt | 9 +++++---- .../net/corda/bootstrapper/gui/BootstrapperView.kt | 13 ++++++------- .../net/corda/bootstrapper/nodes/NodeAdder.kt | 5 +++-- .../net/corda/bootstrapper/nodes/NodeBuilder.kt | 4 ++-- 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/Main.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/Main.kt index eb38bf11cb..9869d74523 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/Main.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/Main.kt @@ -1,4 +1,5 @@ @file:JvmName("Main") + package net.corda.bootstrapper import javafx.application.Application @@ -15,7 +16,13 @@ val baseArgs = CliParser() fun main(args: Array) { SerializationEngine.init() - CommandLine(baseArgs).parse(*args) + val commandLine = CommandLine(baseArgs) + commandLine.parse(*args) + + if (commandLine.isUsageHelpRequested) { + commandLine.usage(System.out) + return + } if (baseArgs.gui) { Application.launch(Gui::class.java) diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkBuilder.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkBuilder.kt index 6b4ee0220f..054a058c18 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkBuilder.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkBuilder.kt @@ -7,7 +7,6 @@ import net.corda.bootstrapper.notaries.NotaryCopier import net.corda.bootstrapper.notaries.NotaryFinder import java.io.File import java.util.concurrent.CompletableFuture -import java.util.concurrent.ConcurrentHashMap interface NetworkBuilder { @@ -23,7 +22,6 @@ interface NetworkBuilder { fun onNodePushed(callback: (PushedNode) -> Unit): NetworkBuilder fun onNodeInstance(callback: (NodeInstance) -> Unit): NetworkBuilder - fun withNodeCounts(map: Map): NetworkBuilder fun withNetworkName(networtName: String): NetworkBuilder fun withBasedir(baseDir: File): NetworkBuilder fun withBackend(backendType: Backend.BackendType): NetworkBuilder @@ -104,11 +102,6 @@ private class NetworkBuilderImpl : NetworkBuilder { return this } - override fun withNodeCounts(map: Map): NetworkBuilder { - nodeCounts = ConcurrentHashMap(map.entries.map { it.key.toLowerCase() to it.value }.toMap()) - return this - } - override fun withNetworkName(networtName: String): NetworkBuilder { this.networkName = networtName return this diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandLineInterface.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandLineInterface.kt index 2f0f6e2080..da5c682bf4 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandLineInterface.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandLineInterface.kt @@ -9,6 +9,7 @@ import net.corda.bootstrapper.nodes.NodeAdder import net.corda.bootstrapper.nodes.NodeInstantiator import net.corda.bootstrapper.toSingleFuture import net.corda.bootstrapper.useAndClose +import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.getOrThrow import java.io.File @@ -25,7 +26,6 @@ class CommandLineInterface { val (_, context) = NetworkBuilder.instance() .withBasedir(baseDir) .withNetworkName(networkName) - .withNodeCounts(parsedArgs.nodes) .onNodeBuild { builtNode -> println("Built node: ${builtNode.name} to image: ${builtNode.localImageId}") } .onNodePushed { pushedNode -> println("Pushed node: ${pushedNode.name} to: ${pushedNode.remoteImageName}") } .onNodeInstance { instance -> @@ -42,7 +42,7 @@ class CommandLineInterface { val (_, instantiator, _) = Backend.fromContext(context, cacheDir) val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context)) parsedArgs.nodesToAdd.map { - nodeAdder.addNode(context, Constants.ALPHA_NUMERIC_ONLY_REGEX.replace(it.toLowerCase(), "")) + nodeAdder.addNode(context, Constants.ALPHA_NUMERIC_ONLY_REGEX.replace(it.key.toLowerCase(), ""), CordaX500Name.parse(it.value)) }.toSingleFuture().getOrThrow() persistContext(contextFile, objectMapper, context) } diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandParsers.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandParsers.kt index 982e8146ae..31ce7b8c11 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandParsers.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/cli/CommandParsers.kt @@ -8,6 +8,7 @@ import picocli.CommandLine.Option import java.io.File open class CliParser { + @Option(names = arrayOf("-n", "--network-name"), description = arrayOf("The resource grouping to use")) var name: String? = null @@ -20,11 +21,11 @@ open class CliParser { @Option(names = arrayOf("-b", "--backend"), description = arrayOf("The backend to use when instantiating nodes")) var backendType: Backend.BackendType = Backend.BackendType.LOCAL_DOCKER - @Option(names = arrayOf("--nodes"), split = ":", description = arrayOf("The number of each node to create. NodeX:2 will create two instances of NodeX")) - var nodes: MutableMap = hashMapOf() + @Option(names = arrayOf("--add"), split = ":", description = arrayOf("The node to add. Format is :. Eg; \"Node1:O=Bank A, L=New York, C=US, OU=Org Unit, CN=Service Name\"")) + var nodesToAdd: MutableMap = hashMapOf() - @Option(names = arrayOf("--add", "-a")) - var nodesToAdd: MutableList = arrayListOf() + @Option(names = arrayOf("-h", "--help"), usageHelp = true, description = arrayOf("display a help message")) + var helpRequested = false fun isNew(): Boolean { return nodesToAdd.isEmpty() diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/gui/BootstrapperView.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/gui/BootstrapperView.kt index c353047c66..3b6ec2b211 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/gui/BootstrapperView.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/gui/BootstrapperView.kt @@ -20,6 +20,7 @@ import net.corda.bootstrapper.backends.Backend import net.corda.bootstrapper.context.Context import net.corda.bootstrapper.nodes.* import net.corda.bootstrapper.notaries.NotaryFinder +import net.corda.core.identity.CordaX500Name import org.apache.commons.lang3.RandomStringUtils import org.controlsfx.control.SegmentedButton import tornadofx.* @@ -69,7 +70,6 @@ class BootstrapperView : View("Corda Network Builder") { } } - val nodeCount = controller.foundNodes.map { it.id to it.count }.toMap() val result = NetworkBuilder.instance() .withBasedir(controller.baseDir.get()) .withNetworkName(networkName) @@ -80,7 +80,6 @@ class BootstrapperView : View("Corda Network Builder") { .onNodeInstancesRequested(controller::addInstanceRequests) .onNodeInstance(controller::addInstance) .withBackend(selectedBackEnd) - .withNodeCounts(nodeCount) .withBackendOptions(backendParams) .build() @@ -117,6 +116,10 @@ class BootstrapperView : View("Corda Network Builder") { enableWhen { controller.networkContext.isNotNull } action { templateChoiceBox.selectionModel.selectedItem?.let { nodeToAdd -> + + val textInputDialog = TextInputDialog("O=Bank A, L=New York, C=US, OU=Org Unit, CN=Service Name") + textInputDialog.title = "X500 of node to add" + val x500ToUse = textInputDialog.showAndWait().orElseGet { null } val context = controller.networkContext.value runLater { val (_, instantiator, _) = Backend.fromContext( @@ -124,7 +127,7 @@ class BootstrapperView : View("Corda Network Builder") { File(controller.baseDir.get(), Constants.BOOTSTRAPPER_DIR_NAME)) val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context)) controller.addInstanceRequest(nodeToAdd) - nodeAdder.addNode(context, nodeToAdd).handleAsync { instanceInfo, t -> + nodeAdder.addNode(context, nodeToAdd, x500ToUse?.let { CordaX500Name.parse(it) }).handleAsync { instanceInfo, t -> t?.let { GuiUtils.showException("Failed", "Failed to add node", it) } @@ -256,10 +259,6 @@ class BootstrapperView : View("Corda Network Builder") { compareValues(o1.nodeType.toString() + o1.templateId, o2.nodeType.toString() + o2.templateId) * -1 }) - fun clear() { - networkContext.set(null) - } - fun clearAll() { networkContext.set(null) foundNodes.clear() diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeAdder.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeAdder.kt index 4de0d53ebe..c90ea6e3ac 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeAdder.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeAdder.kt @@ -2,17 +2,18 @@ package net.corda.bootstrapper.nodes import net.corda.bootstrapper.containers.instance.InstanceInfo import net.corda.bootstrapper.context.Context +import net.corda.core.identity.CordaX500Name import java.util.concurrent.CompletableFuture class NodeAdder(val context: Context, val nodeInstantiator: NodeInstantiator) { - fun addNode(context: Context, nodeGroupName: String): CompletableFuture { + fun addNode(context: Context, nodeGroupName: String, x500ToAdd: CordaX500Name?): CompletableFuture { return synchronized(context) { val nodeGroup = context.nodes[nodeGroupName]!! val nodeInfo = nodeGroup.iterator().next() val currentNodeSize = nodeGroup.size - val newInstanceX500 = nodeInfo.groupX500!!.copy(commonName = nodeInfo.groupX500.commonName + (currentNodeSize)).toString() + val newInstanceX500 = x500ToAdd?.toString() ?: nodeInfo.groupX500!!.copy(commonName = nodeInfo.groupX500.commonName + (currentNodeSize)).toString() val newInstanceName = nodeGroupName + (currentNodeSize) val nextNodeInfo = nodeInfo.copy( instanceX500 = newInstanceX500, diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeBuilder.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeBuilder.kt index 9b55321cdd..bf67ee336a 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeBuilder.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/nodes/NodeBuilder.kt @@ -21,10 +21,10 @@ open class NodeBuilder { val copiedNodeConfig = copiedNode.copiedNodeConfig val nodeDir = copiedNodeConfig.parentFile if (!copiedNodeConfig.exists()) { - throw IllegalStateException("There is no nodeConfig for dir: " + copiedNodeConfig) + throw IllegalStateException("There is no nodeConfig for dir: $copiedNodeConfig") } val nodeConfig = ConfigFactory.parseFile(copiedNodeConfig) - LOG.info("starting to build docker image for: " + nodeDir) + LOG.info("starting to build docker image for: $nodeDir") val nodeImageId = localDockerClient.buildImageCmd() .withDockerfile(File(nodeDir, "Dockerfile")) .withBaseDirectory(nodeDir)