mirror of
https://github.com/corda/corda.git
synced 2025-06-05 00:50:52 +00:00
Merge remote-tracking branch 'open/master' into os-merge-aefd90f
# Conflicts: # CONTRIBUTORS.md
This commit is contained in:
commit
5d55a87d70
@ -48,7 +48,6 @@ import org.junit.Before
|
|||||||
import org.junit.ClassRule
|
import org.junit.ClassRule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import rx.subjects.PublishSubject
|
import rx.subjects.PublishSubject
|
||||||
import java.io.File.pathSeparator
|
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -249,15 +248,12 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance")) {
|
|||||||
@Test
|
@Test
|
||||||
fun `additional class loader used by WireTransaction when it deserialises its components`() {
|
fun `additional class loader used by WireTransaction when it deserialises its components`() {
|
||||||
val financeLocation = Cash::class.java.location.toPath().toString()
|
val financeLocation = Cash::class.java.location.toPath().toString()
|
||||||
val classpathWithoutFinance = ProcessUtilities.defaultClassPath
|
val classPathWithoutFinance = ProcessUtilities.defaultClassPath.filter { financeLocation !in it }
|
||||||
.split(pathSeparator)
|
|
||||||
.filter { financeLocation !in it }
|
|
||||||
.joinToString(pathSeparator)
|
|
||||||
|
|
||||||
// Create a Cash.State object for the StandaloneCashRpcClient to get
|
// Create a Cash.State object for the StandaloneCashRpcClient to get
|
||||||
node.services.startFlow(CashIssueFlow(100.POUNDS, OpaqueBytes.of(1), identity), InvocationContext.shell()).flatMap { it.resultFuture }.getOrThrow()
|
node.services.startFlow(CashIssueFlow(100.POUNDS, OpaqueBytes.of(1), identity), InvocationContext.shell()).flatMap { it.resultFuture }.getOrThrow()
|
||||||
val outOfProcessRpc = ProcessUtilities.startJavaProcess<StandaloneCashRpcClient>(
|
val outOfProcessRpc = ProcessUtilities.startJavaProcess<StandaloneCashRpcClient>(
|
||||||
classpath = classpathWithoutFinance,
|
classPath = classPathWithoutFinance,
|
||||||
arguments = listOf(node.internals.configuration.rpcOptions.address.toString(), financeLocation)
|
arguments = listOf(node.internals.configuration.rpcOptions.address.toString(), financeLocation)
|
||||||
)
|
)
|
||||||
assertThat(outOfProcessRpc.waitFor()).isZero() // i.e. no exceptions were thrown
|
assertThat(outOfProcessRpc.waitFor()).isZero() // i.e. no exceptions were thrown
|
||||||
|
@ -27,11 +27,11 @@ Uploading and downloading
|
|||||||
To upload an attachment to the node, or download an attachment named by its hash, you use :doc:`clientrpc`. This
|
To upload an attachment to the node, or download an attachment named by its hash, you use :doc:`clientrpc`. This
|
||||||
is also available for interactive use via the shell. To **upload** run:
|
is also available for interactive use via the shell. To **upload** run:
|
||||||
|
|
||||||
``>>> run uploadAttachment jar: /path/to/the/file.jar``
|
``>>> run uploadAttachment jar: path/to/the/file.jar``
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
``>>> run uploadAttachmentWithMetadata jar: /path/to/the/file.jar, uploader: myself, filename: original_name.jar``
|
``>>> run uploadAttachmentWithMetadata jar: path/to/the/file.jar, uploader: myself, filename: original_name.jar``
|
||||||
|
|
||||||
to include the metadata with the attachment which can be used to find it later on. Note, that currently both uploader
|
to include the metadata with the attachment which can be used to find it later on. Note, that currently both uploader
|
||||||
and filename are just plain strings (there is no connection between uploader and the RPC users for example).
|
and filename are just plain strings (there is no connection between uploader and the RPC users for example).
|
||||||
|
@ -99,7 +99,7 @@ Let's add a ``CommercialPaper`` transaction:
|
|||||||
}
|
}
|
||||||
|
|
||||||
We can add a transaction to the ledger using the ``transaction`` primitive. The transaction in turn may be defined by
|
We can add a transaction to the ledger using the ``transaction`` primitive. The transaction in turn may be defined by
|
||||||
specifying ``input``-s, ``output``-s, ``command``-s and ``attachment``-s.
|
specifying ``input``s, ``output``s, ``command``s and ``attachment``s.
|
||||||
|
|
||||||
The above ``input`` call is a bit special; transactions don't actually contain input states, just references
|
The above ``input`` call is a bit special; transactions don't actually contain input states, just references
|
||||||
to output states of other transactions. Under the hood the above ``input`` call creates a dummy transaction in the
|
to output states of other transactions. Under the hood the above ``input`` call creates a dummy transaction in the
|
||||||
|
@ -12,4 +12,4 @@
|
|||||||
# Note: sadly, due to present limitation of IntelliJ-IDEA in processing resource files, these constants cannot be
|
# Note: sadly, due to present limitation of IntelliJ-IDEA in processing resource files, these constants cannot be
|
||||||
# imported from top-level 'constants.properties' file
|
# imported from top-level 'constants.properties' file
|
||||||
|
|
||||||
jolokiaAgentVersion=1.5.0
|
jolokiaAgentVersion=1.6.0
|
||||||
|
@ -75,20 +75,18 @@ class IRSDemoTest : IntegrationTest() {
|
|||||||
isDebug = true,
|
isDebug = true,
|
||||||
extraCordappPackagesToScan = listOf("net.corda.irs")
|
extraCordappPackagesToScan = listOf("net.corda.irs")
|
||||||
)) {
|
)) {
|
||||||
val (nodeA, nodeB) = listOf(
|
val (controller, nodeA, nodeB) = listOf(
|
||||||
|
defaultNotaryNode,
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = rpcUsers),
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = rpcUsers),
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = rpcUsers),
|
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = rpcUsers),
|
||||||
startNode(providedName = CordaX500Name("Regulator", "Moscow", "RU"))
|
startNode(providedName = CordaX500Name("Regulator", "Moscow", "RU"))
|
||||||
).map { it.getOrThrow() }
|
).map { it.getOrThrow() }
|
||||||
val controller = defaultNotaryNode.getOrThrow()
|
|
||||||
|
|
||||||
log.info("All nodes started")
|
log.info("All nodes started")
|
||||||
|
|
||||||
val controllerAddrFuture = startSpringBootWebapp(IrsDemoWebApplication::class.java, controller, "/api/irs/demodate")
|
val (controllerAddr, nodeAAddr, nodeBAddr) = listOf(controller, nodeA, nodeB).map {
|
||||||
val nodeAAddrFuture = startSpringBootWebapp(IrsDemoWebApplication::class.java, nodeA, "/api/irs/demodate")
|
startSpringBootWebapp(IrsDemoWebApplication::class.java, it, "/api/irs/demodate")
|
||||||
val nodeBAddrFuture = startSpringBootWebapp(IrsDemoWebApplication::class.java, nodeB, "/api/irs/demodate")
|
}.map { it.getOrThrow().listenAddress }
|
||||||
val (controllerAddr, nodeAAddr, nodeBAddr) =
|
|
||||||
listOf(controllerAddrFuture, nodeAAddrFuture, nodeBAddrFuture).map { it.getOrThrow().listenAddress }
|
|
||||||
|
|
||||||
log.info("All webservers started")
|
log.info("All webservers started")
|
||||||
|
|
||||||
|
@ -85,16 +85,14 @@ data class SpringBootDriverDSL(private val driverDSL: DriverDSLImpl) : InternalD
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun startApplication(handle: NodeHandle, debugPort: Int?, clazz: Class<*>): Process {
|
private fun startApplication(handle: NodeHandle, debugPort: Int?, clazz: Class<*>): Process {
|
||||||
val className = clazz.canonicalName
|
return ProcessUtilities.startJavaProcess(
|
||||||
return ProcessUtilities.startJavaProcessImpl(
|
className = clazz.canonicalName, // cannot directly get class for this, so just use string
|
||||||
className = className, // cannot directly get class for this, so just use string
|
|
||||||
jdwpPort = debugPort,
|
jdwpPort = debugPort,
|
||||||
extraJvmArguments = listOf(
|
extraJvmArguments = listOf(
|
||||||
"-Dname=node-${handle.p2pAddress}-webserver",
|
"-Dname=node-${handle.p2pAddress}-webserver",
|
||||||
"-Djava.io.tmpdir=${System.getProperty("java.io.tmpdir")}"
|
"-Djava.io.tmpdir=${System.getProperty("java.io.tmpdir")}"
|
||||||
// Inherit from parent process
|
// Inherit from parent process
|
||||||
),
|
),
|
||||||
classpath = ProcessUtilities.defaultClassPath,
|
|
||||||
workingDirectory = handle.baseDirectory,
|
workingDirectory = handle.baseDirectory,
|
||||||
arguments = listOf(
|
arguments = listOf(
|
||||||
"--base-directory", handle.baseDirectory.toString(),
|
"--base-directory", handle.baseDirectory.toString(),
|
||||||
@ -102,8 +100,7 @@ data class SpringBootDriverDSL(private val driverDSL: DriverDSLImpl) : InternalD
|
|||||||
"--corda.host=${handle.rpcAddress}",
|
"--corda.host=${handle.rpcAddress}",
|
||||||
"--corda.user=${handle.rpcUsers.first().username}",
|
"--corda.user=${handle.rpcUsers.first().username}",
|
||||||
"--corda.password=${handle.rpcUsers.first().password}"
|
"--corda.password=${handle.rpcUsers.first().password}"
|
||||||
),
|
)
|
||||||
maximumHeapSize = null
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ import net.corda.core.utilities.getOrThrow
|
|||||||
import net.corda.core.utilities.millis
|
import net.corda.core.utilities.millis
|
||||||
import net.corda.node.NodeRegistrationOption
|
import net.corda.node.NodeRegistrationOption
|
||||||
import net.corda.node.VersionInfo
|
import net.corda.node.VersionInfo
|
||||||
import net.corda.node.internal.ConfigurationException
|
|
||||||
import net.corda.node.internal.Node
|
import net.corda.node.internal.Node
|
||||||
import net.corda.node.internal.StartedNode
|
import net.corda.node.internal.StartedNode
|
||||||
import net.corda.node.services.Permissions
|
import net.corda.node.services.Permissions
|
||||||
@ -846,7 +845,7 @@ class DriverDSLImpl(
|
|||||||
it += extraCmdLineFlag
|
it += extraCmdLineFlag
|
||||||
}.toList()
|
}.toList()
|
||||||
|
|
||||||
return ProcessUtilities.startCordaProcess(
|
return ProcessUtilities.startJavaProcess(
|
||||||
className = "net.corda.node.Corda", // cannot directly get class for this, so just use string
|
className = "net.corda.node.Corda", // cannot directly get class for this, so just use string
|
||||||
arguments = arguments,
|
arguments = arguments,
|
||||||
jdwpPort = debugPort,
|
jdwpPort = debugPort,
|
||||||
@ -859,13 +858,12 @@ class DriverDSLImpl(
|
|||||||
private fun startWebserver(handle: NodeHandleInternal, debugPort: Int?, maximumHeapSize: String): Process {
|
private fun startWebserver(handle: NodeHandleInternal, debugPort: Int?, maximumHeapSize: String): Process {
|
||||||
val className = "net.corda.webserver.WebServer"
|
val className = "net.corda.webserver.WebServer"
|
||||||
writeConfig(handle.baseDirectory, "web-server.conf", handle.toWebServerConfig())
|
writeConfig(handle.baseDirectory, "web-server.conf", handle.toWebServerConfig())
|
||||||
return ProcessUtilities.startCordaProcess(
|
return ProcessUtilities.startJavaProcess(
|
||||||
className = className, // cannot directly get class for this, so just use string
|
className = className, // cannot directly get class for this, so just use string
|
||||||
arguments = listOf("--base-directory", handle.baseDirectory.toString()),
|
arguments = listOf("--base-directory", handle.baseDirectory.toString()),
|
||||||
jdwpPort = debugPort,
|
jdwpPort = debugPort,
|
||||||
extraJvmArguments = listOf("-Dname=node-${handle.p2pAddress}-webserver") +
|
extraJvmArguments = listOf("-Dname=node-${handle.p2pAddress}-webserver") +
|
||||||
inheritFromParentProcess().map { "-D${it.first}=${it.second}" },
|
inheritFromParentProcess().map { "-D${it.first}=${it.second}" },
|
||||||
workingDirectory = null,
|
|
||||||
maximumHeapSize = maximumHeapSize
|
maximumHeapSize = maximumHeapSize
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -11,40 +11,32 @@
|
|||||||
package net.corda.testing.node.internal
|
package net.corda.testing.node.internal
|
||||||
|
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
object ProcessUtilities {
|
object ProcessUtilities {
|
||||||
inline fun <reified C : Any> startJavaProcess(
|
inline fun <reified C : Any> startJavaProcess(
|
||||||
arguments: List<String>,
|
arguments: List<String>,
|
||||||
classpath: String = defaultClassPath,
|
classPath: List<String> = defaultClassPath,
|
||||||
|
workingDirectory: Path? = null,
|
||||||
jdwpPort: Int? = null,
|
jdwpPort: Int? = null,
|
||||||
extraJvmArguments: List<String> = emptyList()
|
extraJvmArguments: List<String> = emptyList(),
|
||||||
|
maximumHeapSize: String? = null
|
||||||
): Process {
|
): Process {
|
||||||
return startJavaProcessImpl(C::class.java.name, arguments, classpath, jdwpPort, extraJvmArguments, null, null)
|
return startJavaProcess(C::class.java.name, arguments, classPath, workingDirectory, jdwpPort, extraJvmArguments, maximumHeapSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startCordaProcess(
|
fun startJavaProcess(
|
||||||
className: String,
|
className: String,
|
||||||
arguments: List<String>,
|
arguments: List<String>,
|
||||||
jdwpPort: Int?,
|
classPath: List<String> = defaultClassPath,
|
||||||
extraJvmArguments: List<String>,
|
workingDirectory: Path? = null,
|
||||||
workingDirectory: Path?,
|
jdwpPort: Int? = null,
|
||||||
maximumHeapSize: String
|
extraJvmArguments: List<String> = emptyList(),
|
||||||
): Process {
|
maximumHeapSize: String? = null
|
||||||
return startJavaProcessImpl(className, arguments, defaultClassPath, jdwpPort, extraJvmArguments, workingDirectory, maximumHeapSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun startJavaProcessImpl(
|
|
||||||
className: String,
|
|
||||||
arguments: List<String>,
|
|
||||||
classpath: String,
|
|
||||||
jdwpPort: Int?,
|
|
||||||
extraJvmArguments: List<String>,
|
|
||||||
workingDirectory: Path?,
|
|
||||||
maximumHeapSize: String?
|
|
||||||
): Process {
|
): Process {
|
||||||
val command = mutableListOf<String>().apply {
|
val command = mutableListOf<String>().apply {
|
||||||
add((System.getProperty("java.home") / "bin" / "java").toString())
|
add(javaPath)
|
||||||
(jdwpPort != null) && add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$jdwpPort")
|
(jdwpPort != null) && add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$jdwpPort")
|
||||||
if (maximumHeapSize != null) add("-Xmx$maximumHeapSize")
|
if (maximumHeapSize != null) add("-Xmx$maximumHeapSize")
|
||||||
add("-XX:+UseG1GC")
|
add("-XX:+UseG1GC")
|
||||||
@ -54,7 +46,7 @@ object ProcessUtilities {
|
|||||||
}
|
}
|
||||||
return ProcessBuilder(command).apply {
|
return ProcessBuilder(command).apply {
|
||||||
inheritIO()
|
inheritIO()
|
||||||
environment()["CLASSPATH"] = classpath
|
environment()["CLASSPATH"] = classPath.joinToString(File.pathSeparator)
|
||||||
if (workingDirectory != null) {
|
if (workingDirectory != null) {
|
||||||
redirectError((workingDirectory / "$className.stderr.log").toFile())
|
redirectError((workingDirectory / "$className.stderr.log").toFile())
|
||||||
redirectOutput((workingDirectory / "$className.stdout.log").toFile())
|
redirectOutput((workingDirectory / "$className.stdout.log").toFile())
|
||||||
@ -63,5 +55,7 @@ object ProcessUtilities {
|
|||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
val defaultClassPath: String get() = System.getProperty("java.class.path")
|
private val javaPath = (System.getProperty("java.home") / "bin" / "java").toString()
|
||||||
|
|
||||||
|
val defaultClassPath: List<String> = System.getProperty("java.class.path").split(File.pathSeparator)
|
||||||
}
|
}
|
@ -7,7 +7,6 @@ import net.corda.bootstrapper.notaries.NotaryCopier
|
|||||||
import net.corda.bootstrapper.notaries.NotaryFinder
|
import net.corda.bootstrapper.notaries.NotaryFinder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
|
||||||
|
|
||||||
interface NetworkBuilder {
|
interface NetworkBuilder {
|
||||||
|
|
||||||
@ -23,7 +22,6 @@ interface NetworkBuilder {
|
|||||||
fun onNodePushed(callback: (PushedNode) -> Unit): NetworkBuilder
|
fun onNodePushed(callback: (PushedNode) -> Unit): NetworkBuilder
|
||||||
fun onNodeInstance(callback: (NodeInstance) -> Unit): NetworkBuilder
|
fun onNodeInstance(callback: (NodeInstance) -> Unit): NetworkBuilder
|
||||||
|
|
||||||
fun withNodeCounts(map: Map<String, Int>): NetworkBuilder
|
|
||||||
fun withNetworkName(networtName: String): NetworkBuilder
|
fun withNetworkName(networtName: String): NetworkBuilder
|
||||||
fun withBasedir(baseDir: File): NetworkBuilder
|
fun withBasedir(baseDir: File): NetworkBuilder
|
||||||
fun withBackend(backendType: Backend.BackendType): NetworkBuilder
|
fun withBackend(backendType: Backend.BackendType): NetworkBuilder
|
||||||
@ -104,11 +102,6 @@ private class NetworkBuilderImpl : NetworkBuilder {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun withNodeCounts(map: Map<String, Int>): NetworkBuilder {
|
|
||||||
nodeCounts = ConcurrentHashMap(map.entries.map { it.key.toLowerCase() to it.value }.toMap())
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun withNetworkName(networtName: String): NetworkBuilder {
|
override fun withNetworkName(networtName: String): NetworkBuilder {
|
||||||
this.networkName = networtName
|
this.networkName = networtName
|
||||||
return this
|
return this
|
||||||
|
@ -8,6 +8,7 @@ import net.corda.bootstrapper.context.Context
|
|||||||
import net.corda.bootstrapper.nodes.NodeAdder
|
import net.corda.bootstrapper.nodes.NodeAdder
|
||||||
import net.corda.bootstrapper.nodes.NodeInstantiator
|
import net.corda.bootstrapper.nodes.NodeInstantiator
|
||||||
import net.corda.bootstrapper.toSingleFuture
|
import net.corda.bootstrapper.toSingleFuture
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -23,7 +24,6 @@ class CommandLineInterface {
|
|||||||
val (_, context) = NetworkBuilder.instance()
|
val (_, context) = NetworkBuilder.instance()
|
||||||
.withBasedir(baseDir)
|
.withBasedir(baseDir)
|
||||||
.withNetworkName(networkName)
|
.withNetworkName(networkName)
|
||||||
.withNodeCounts(parsedArgs.nodes)
|
|
||||||
.onNodeBuild { builtNode -> println("Built node: ${builtNode.name} to image: ${builtNode.localImageId}") }
|
.onNodeBuild { builtNode -> println("Built node: ${builtNode.name} to image: ${builtNode.localImageId}") }
|
||||||
.onNodePushed { pushedNode -> println("Pushed node: ${pushedNode.name} to: ${pushedNode.remoteImageName}") }
|
.onNodePushed { pushedNode -> println("Pushed node: ${pushedNode.name} to: ${pushedNode.remoteImageName}") }
|
||||||
.onNodeInstance { instance ->
|
.onNodeInstance { instance ->
|
||||||
@ -40,7 +40,7 @@ class CommandLineInterface {
|
|||||||
val (_, instantiator, _) = Backend.fromContext(context, cacheDir)
|
val (_, instantiator, _) = Backend.fromContext(context, cacheDir)
|
||||||
val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context))
|
val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context))
|
||||||
parsedArgs.nodesToAdd.map {
|
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()
|
}.toSingleFuture().getOrThrow()
|
||||||
persistContext(contextFile, objectMapper, context)
|
persistContext(contextFile, objectMapper, context)
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,9 @@ open class CliParser {
|
|||||||
@Option(names = ["-b", "--backend"], description = ["The backend to use when instantiating nodes"])
|
@Option(names = ["-b", "--backend"], description = ["The backend to use when instantiating nodes"])
|
||||||
var backendType: Backend.BackendType = Backend.BackendType.LOCAL_DOCKER
|
var backendType: Backend.BackendType = Backend.BackendType.LOCAL_DOCKER
|
||||||
|
|
||||||
@Option(names = ["--nodes"], split = ":", description = ["The number of each node to create. NodeX:2 will create two instances of NodeX"])
|
|
||||||
var nodes: MutableMap<String, Int> = hashMapOf()
|
|
||||||
|
|
||||||
@Option(names = ["--add", "-a"])
|
@Option(names = ["--add"], split = ":", description = ["The node to add. Format is <Name>:<X500>. Eg; \"Node1:O=Bank A, L=New York, C=US, OU=Org Unit, CN=Service Name\""])
|
||||||
var nodesToAdd: MutableList<String> = arrayListOf()
|
var nodesToAdd: MutableMap<String, String> = hashMapOf()
|
||||||
|
|
||||||
fun isNew(): Boolean {
|
fun isNew(): Boolean {
|
||||||
return nodesToAdd.isEmpty()
|
return nodesToAdd.isEmpty()
|
||||||
|
@ -21,6 +21,7 @@ import net.corda.bootstrapper.baseArgs
|
|||||||
import net.corda.bootstrapper.context.Context
|
import net.corda.bootstrapper.context.Context
|
||||||
import net.corda.bootstrapper.nodes.*
|
import net.corda.bootstrapper.nodes.*
|
||||||
import net.corda.bootstrapper.notaries.NotaryFinder
|
import net.corda.bootstrapper.notaries.NotaryFinder
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
import org.apache.commons.lang3.RandomStringUtils
|
import org.apache.commons.lang3.RandomStringUtils
|
||||||
import org.controlsfx.control.SegmentedButton
|
import org.controlsfx.control.SegmentedButton
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
@ -70,7 +71,6 @@ class BootstrapperView : View("Corda Network Builder") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val nodeCount = controller.foundNodes.map { it.id to it.count }.toMap()
|
|
||||||
val result = NetworkBuilder.instance()
|
val result = NetworkBuilder.instance()
|
||||||
.withBasedir(controller.baseDir.get())
|
.withBasedir(controller.baseDir.get())
|
||||||
.withNetworkName(networkName)
|
.withNetworkName(networkName)
|
||||||
@ -81,7 +81,6 @@ class BootstrapperView : View("Corda Network Builder") {
|
|||||||
.onNodeInstancesRequested(controller::addInstanceRequests)
|
.onNodeInstancesRequested(controller::addInstanceRequests)
|
||||||
.onNodeInstance(controller::addInstance)
|
.onNodeInstance(controller::addInstance)
|
||||||
.withBackend(selectedBackEnd)
|
.withBackend(selectedBackEnd)
|
||||||
.withNodeCounts(nodeCount)
|
|
||||||
.withBackendOptions(backendParams)
|
.withBackendOptions(backendParams)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
@ -118,6 +117,10 @@ class BootstrapperView : View("Corda Network Builder") {
|
|||||||
enableWhen { controller.networkContext.isNotNull }
|
enableWhen { controller.networkContext.isNotNull }
|
||||||
action {
|
action {
|
||||||
templateChoiceBox.selectionModel.selectedItem?.let { nodeToAdd ->
|
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
|
val context = controller.networkContext.value
|
||||||
runLater {
|
runLater {
|
||||||
val (_, instantiator, _) = Backend.fromContext(
|
val (_, instantiator, _) = Backend.fromContext(
|
||||||
@ -125,7 +128,7 @@ class BootstrapperView : View("Corda Network Builder") {
|
|||||||
File(controller.baseDir.get(), Constants.BOOTSTRAPPER_DIR_NAME))
|
File(controller.baseDir.get(), Constants.BOOTSTRAPPER_DIR_NAME))
|
||||||
val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context))
|
val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context))
|
||||||
controller.addInstanceRequest(nodeToAdd)
|
controller.addInstanceRequest(nodeToAdd)
|
||||||
nodeAdder.addNode(context, nodeToAdd).handleAsync { instanceInfo, t ->
|
nodeAdder.addNode(context, nodeToAdd, x500ToUse?.let { CordaX500Name.parse(it) }).handleAsync { instanceInfo, t ->
|
||||||
t?.let {
|
t?.let {
|
||||||
GuiUtils.showException("Failed", "Failed to add node", it)
|
GuiUtils.showException("Failed", "Failed to add node", it)
|
||||||
}
|
}
|
||||||
@ -263,10 +266,6 @@ class BootstrapperView : View("Corda Network Builder") {
|
|||||||
compareValues(o1.nodeType.toString() + o1.templateId, o2.nodeType.toString() + o2.templateId) * -1
|
compareValues(o1.nodeType.toString() + o1.templateId, o2.nodeType.toString() + o2.templateId) * -1
|
||||||
})
|
})
|
||||||
|
|
||||||
fun clear() {
|
|
||||||
networkContext.set(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clearAll() {
|
fun clearAll() {
|
||||||
networkContext.set(null)
|
networkContext.set(null)
|
||||||
foundNodes.clear()
|
foundNodes.clear()
|
||||||
|
@ -2,17 +2,18 @@ package net.corda.bootstrapper.nodes
|
|||||||
|
|
||||||
import net.corda.bootstrapper.containers.instance.InstanceInfo
|
import net.corda.bootstrapper.containers.instance.InstanceInfo
|
||||||
import net.corda.bootstrapper.context.Context
|
import net.corda.bootstrapper.context.Context
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
class NodeAdder(val context: Context,
|
class NodeAdder(val context: Context,
|
||||||
val nodeInstantiator: NodeInstantiator) {
|
val nodeInstantiator: NodeInstantiator) {
|
||||||
|
|
||||||
fun addNode(context: Context, nodeGroupName: String): CompletableFuture<InstanceInfo> {
|
fun addNode(context: Context, nodeGroupName: String, x500ToAdd: CordaX500Name?): CompletableFuture<InstanceInfo> {
|
||||||
return synchronized(context) {
|
return synchronized(context) {
|
||||||
val nodeGroup = context.nodes[nodeGroupName]!!
|
val nodeGroup = context.nodes[nodeGroupName]!!
|
||||||
val nodeInfo = nodeGroup.iterator().next()
|
val nodeInfo = nodeGroup.iterator().next()
|
||||||
val currentNodeSize = nodeGroup.size
|
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 newInstanceName = nodeGroupName + (currentNodeSize)
|
||||||
val nextNodeInfo = nodeInfo.copy(
|
val nextNodeInfo = nodeInfo.copy(
|
||||||
instanceX500 = newInstanceX500,
|
instanceX500 = newInstanceX500,
|
||||||
|
@ -21,10 +21,10 @@ open class NodeBuilder {
|
|||||||
val copiedNodeConfig = copiedNode.copiedNodeConfig
|
val copiedNodeConfig = copiedNode.copiedNodeConfig
|
||||||
val nodeDir = copiedNodeConfig.parentFile
|
val nodeDir = copiedNodeConfig.parentFile
|
||||||
if (!copiedNodeConfig.exists()) {
|
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)
|
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()
|
val nodeImageId = localDockerClient.buildImageCmd()
|
||||||
.withDockerfile(File(nodeDir, "Dockerfile"))
|
.withDockerfile(File(nodeDir, "Dockerfile"))
|
||||||
.withBaseDirectory(nodeDir)
|
.withBaseDirectory(nodeDir)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user