Skip to content

Commit

Permalink
[CORDA-879] Generate node directories as part of bootstrapping (corda…
Browse files Browse the repository at this point in the history
…#2285)

* Generate node directories as part of bootstrapping

* Include latest corda.jar in bootstrapper package
Remove SLF4J warnings on startup

* Changes post review

* More review changes

* Review changes

* Making docs clearer
  • Loading branch information
anthonykeenan authored Dec 23, 2017
1 parent ce4a640 commit 1d66fe9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
13 changes: 12 additions & 1 deletion docs/source/setting-up-a-corda-network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,21 @@ The bootstrapper tool can be built with the command:

The resulting jar can be found in ``tools/bootstrapper/build/libs/``.

To use it, run the following command, specifying the root directory which hosts all the node directories as the argument:
To use it, create a directory containing a ``node.conf`` file for each node you want to create. Then run the following command:

``java -jar network-bootstrapper.jar <nodes-root-dir>``

For example running the command on a directory containing these files :

.. sourcecode:: none

.
├── notary.conf // The notary's node.conf file
├── partya.conf // Party A's node.conf file
└── partyb.conf // Party B's node.conf file

Would generate directories containing three nodes: notary, partya and partyb.

Starting the nodes
~~~~~~~~~~~~~~~~~~

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
import net.corda.nodeapi.internal.serialization.kryo.AbstractKryoSerializationScheme
import net.corda.nodeapi.internal.serialization.kryo.KryoHeaderV0_1
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.StandardCopyOption
Expand Down Expand Up @@ -52,6 +53,7 @@ class NetworkBootstrapper {
fun bootstrap(directory: Path) {
directory.createDirectories()
println("Bootstrapping local network in $directory")
generateDirectoriesIfNeeded(directory)
val nodeDirs = directory.list { paths -> paths.filter { (it / "corda.jar").exists() }.toList() }
require(nodeDirs.isNotEmpty()) { "No nodes found" }
println("Nodes found in the following sub-directories: ${nodeDirs.map { it.fileName }}")
Expand All @@ -73,6 +75,27 @@ class NetworkBootstrapper {
}
}

private fun generateDirectoriesIfNeeded(directory: Path) {
val confFiles = directory.list { it.filter { it.toString().endsWith(".conf") }.toList() }
if (confFiles.isEmpty()) return
println("Node config files found in the root directory - generating node directories")
val cordaJar = extractCordaJarTo(directory)
for (confFile in confFiles) {
val nodeName = confFile.fileName.toString().removeSuffix(".conf")
println("Generating directory for $nodeName")
val nodeDir = (directory / nodeName).createDirectory()
confFile.moveTo(nodeDir / "node.conf")
Files.copy(cordaJar, (nodeDir / "corda.jar"))
}
Files.delete(cordaJar)
}

private fun extractCordaJarTo(directory: Path): Path {
val cordaJarPath = (directory / "corda.jar")
Thread.currentThread().contextClassLoader.getResourceAsStream("corda.jar").copyTo(cordaJarPath)
return cordaJarPath
}

private fun startNodeInfoGeneration(nodeDirs: List<Path>): List<Process> {
return nodeDirs.map { nodeDir ->
val logsDir = (nodeDir / LOGS_DIR_NAME).createDirectories()
Expand Down Expand Up @@ -147,10 +170,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")
}
Expand All @@ -172,6 +195,7 @@ class NetworkBootstrapper {
override fun canDeserializeVersion(byteSequence: ByteSequence, target: SerializationContext.UseCase): Boolean {
return byteSequence == KryoHeaderV0_1 && target == SerializationContext.UseCase.P2P
}

override fun rpcClientKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
override fun rpcServerKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
}
Expand Down
8 changes: 7 additions & 1 deletion tools/bootstrapper/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ configurations {
runtimeArtifacts
}

// TODO Fix SLF4J warnings that occur when running the bootstrapper
dependencies {
compile "org.slf4j:slf4j-nop:$slf4j_version"
}

task buildBootstrapperJar(type: FatCapsule, dependsOn: project(':node-api').compileJava) {
applicationClass 'net.corda.nodeapi.internal.network.NetworkBootstrapper'
archiveName "network-bootstrapper.jar"
Expand All @@ -16,6 +19,9 @@ task buildBootstrapperJar(type: FatCapsule, dependsOn: project(':node-api').comp
minJavaVersion = '1.8.0'
jvmArgs = ['-XX:+UseG1GC']
}
from(project(':node:capsule').tasks['buildCordaJAR']) {
rename 'corda-(.*)', 'corda.jar'
}
applicationSource = files(
project(':node-api').configurations.runtime,
project(':node-api').jar
Expand Down

0 comments on commit 1d66fe9

Please sign in to comment.