node-driver: Write node.conf explicitly

This commit is contained in:
Andras Slemmer 2016-08-10 14:35:23 +01:00
parent 1b98c32579
commit 00b439802b
2 changed files with 65 additions and 54 deletions

View File

@ -7,15 +7,16 @@ import com.r3corda.core.messaging.MessagingService
import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.core.node.services.NetworkMapCache
import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.ServiceType
import com.r3corda.node.services.config.NodeConfiguration
import com.r3corda.node.services.messaging.ArtemisMessagingClient import com.r3corda.node.services.messaging.ArtemisMessagingClient
import com.r3corda.node.services.config.NodeConfigurationFromConfig import com.r3corda.node.services.config.NodeConfigurationFromConfig
import com.r3corda.node.services.config.copy
import com.r3corda.node.services.network.InMemoryNetworkMapCache import com.r3corda.node.services.network.InMemoryNetworkMapCache
import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.network.NetworkMapService
import com.typesafe.config.ConfigFactory import com.typesafe.config.Config
import com.typesafe.config.ConfigParseOptions import com.typesafe.config.ConfigRenderOptions
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.File
import java.net.ServerSocket import java.net.ServerSocket
import java.net.Socket import java.net.Socket
import java.net.SocketException import java.net.SocketException
@ -82,7 +83,6 @@ sealed class PortAllocation {
* @param baseDirectory The base directory node directories go into, defaults to "build/<timestamp>/". The node * @param baseDirectory The base directory node directories go into, defaults to "build/<timestamp>/". The node
* directories themselves are "<baseDirectory>/<legalName>/", where legalName defaults to "<randomName>-<messagingPort>" * directories themselves are "<baseDirectory>/<legalName>/", where legalName defaults to "<randomName>-<messagingPort>"
* and may be specified in [DriverDSL.startNode]. * and may be specified in [DriverDSL.startNode].
* @param nodeConfigurationPath The path to the node's .conf, defaults to "reference.conf".
* @param quasarJarPath The path to quasar.jar, relative to cwd. Defaults to "lib/quasar.jar". TODO remove this once we can bundle quasar properly. * @param quasarJarPath The path to quasar.jar, relative to cwd. Defaults to "lib/quasar.jar". TODO remove this once we can bundle quasar properly.
* @param portAllocation The port allocation strategy to use for the messaging and the web server addresses. Defaults to incremental. * @param portAllocation The port allocation strategy to use for the messaging and the web server addresses. Defaults to incremental.
* @param debugPortAllocation The port allocation strategy to use for jvm debugging. Defaults to incremental. * @param debugPortAllocation The port allocation strategy to use for jvm debugging. Defaults to incremental.
@ -91,7 +91,6 @@ sealed class PortAllocation {
*/ */
fun <A> driver( fun <A> driver(
baseDirectory: String = "build/${getTimestampAsDirectoryName()}", baseDirectory: String = "build/${getTimestampAsDirectoryName()}",
nodeConfigurationPath: String = "reference.conf",
quasarJarPath: String = "lib/quasar.jar", quasarJarPath: String = "lib/quasar.jar",
portAllocation: PortAllocation = PortAllocation.Incremental(10000), portAllocation: PortAllocation = PortAllocation.Incremental(10000),
debugPortAllocation: PortAllocation = PortAllocation.Incremental(5005), debugPortAllocation: PortAllocation = PortAllocation.Incremental(5005),
@ -101,7 +100,6 @@ fun <A> driver(
portAllocation = portAllocation, portAllocation = portAllocation,
debugPortAllocation = debugPortAllocation, debugPortAllocation = debugPortAllocation,
baseDirectory = baseDirectory, baseDirectory = baseDirectory,
nodeConfigurationPath = nodeConfigurationPath,
quasarJarPath = quasarJarPath quasarJarPath = quasarJarPath
), ),
coerce = { it }, coerce = { it },
@ -186,7 +184,6 @@ class DriverDSL(
val portAllocation: PortAllocation, val portAllocation: PortAllocation,
val debugPortAllocation: PortAllocation, val debugPortAllocation: PortAllocation,
val baseDirectory: String, val baseDirectory: String,
val nodeConfigurationPath: String,
val quasarJarPath: String val quasarJarPath: String
) : DriverDSLInternalInterface { ) : DriverDSLInternalInterface {
@ -196,19 +193,19 @@ class DriverDSL(
private var networkMapNodeInfo: NodeInfo? = null private var networkMapNodeInfo: NodeInfo? = null
private val registeredProcesses = LinkedList<Process>() private val registeredProcesses = LinkedList<Process>()
val nodeConfiguration = val driverNodeConfiguration = NodeConfigurationFromConfig(
NodeConfigurationFromConfig( NodeConfiguration.loadConfig(
ConfigFactory.parseResources( baseDirectoryPath = Paths.get(baseDirectory, "driver-artemis"),
nodeConfigurationPath, allowMissingConfig = true,
ConfigParseOptions.defaults().setAllowMissing(false) configOverrides = mapOf(
"myLegalName" to "driver-artemis"
)
) )
).copy(
myLegalName = "driver-artemis"
) )
override val messagingService = ArtemisMessagingClient( override val messagingService = ArtemisMessagingClient(
Paths.get(baseDirectory, "driver-artemis"), Paths.get(baseDirectory, "driver-artemis"),
nodeConfiguration, driverNodeConfiguration,
serverHostPort = networkMapAddress, serverHostPort = networkMapAddress,
myHostPort = portAllocation.nextHostAndPort() myHostPort = portAllocation.nextHostAndPort()
) )
@ -261,6 +258,16 @@ class DriverDSL(
val debugPort = debugPortAllocation.nextPort() val debugPort = debugPortAllocation.nextPort()
val name = providedName ?: "${pickA(name)}-${messagingAddress.port}" val name = providedName ?: "${pickA(name)}-${messagingAddress.port}"
val nodeDirectory = "$baseDirectory/$name"
val config = NodeConfiguration.loadConfig(
baseDirectoryPath = Paths.get(nodeDirectory),
allowMissingConfig = true,
configOverrides = mapOf(
"myLegalName" to name
)
)
val driverCliParams = NodeRunner.CliParams( val driverCliParams = NodeRunner.CliParams(
services = advertisedServices, services = advertisedServices,
networkMapName = networkMapNodeInfo!!.identity.name, networkMapName = networkMapNodeInfo!!.identity.name,
@ -268,11 +275,9 @@ class DriverDSL(
networkMapAddress = networkMapAddress, networkMapAddress = networkMapAddress,
messagingAddress = messagingAddress, messagingAddress = messagingAddress,
apiAddress = apiAddress, apiAddress = apiAddress,
baseDirectory = baseDirectory, baseDirectory = nodeDirectory
nodeConfigurationPath = nodeConfigurationPath,
legalName = name
) )
registerProcess(startNode(driverCliParams, quasarJarPath, debugPort)) registerProcess(DriverDSL.startNode(config, driverCliParams, name, quasarJarPath, debugPort))
return poll { return poll {
networkMapCache.partyNodes.forEach { networkMapCache.partyNodes.forEach {
@ -313,6 +318,17 @@ class DriverDSL(
private fun startNetworkMapService() { private fun startNetworkMapService() {
val apiAddress = portAllocation.nextHostAndPort() val apiAddress = portAllocation.nextHostAndPort()
val debugPort = debugPortAllocation.nextPort() val debugPort = debugPortAllocation.nextPort()
val nodeDirectory = "$baseDirectory/$networkMapName"
val config = NodeConfiguration.loadConfig(
baseDirectoryPath = Paths.get(nodeDirectory),
allowMissingConfig = true,
configOverrides = mapOf(
"myLegalName" to networkMapName
)
)
val driverCliParams = NodeRunner.CliParams( val driverCliParams = NodeRunner.CliParams(
services = setOf(NetworkMapService.Type), services = setOf(NetworkMapService.Type),
networkMapName = null, networkMapName = null,
@ -320,12 +336,10 @@ class DriverDSL(
networkMapAddress = null, networkMapAddress = null,
messagingAddress = networkMapAddress, messagingAddress = networkMapAddress,
apiAddress = apiAddress, apiAddress = apiAddress,
baseDirectory = baseDirectory, baseDirectory = nodeDirectory
nodeConfigurationPath = nodeConfigurationPath,
legalName = networkMapName
) )
log.info("Starting network-map-service") log.info("Starting network-map-service")
registerProcess(startNode(driverCliParams, quasarJarPath, debugPort)) registerProcess(startNode(config, driverCliParams, networkMapName, quasarJarPath, debugPort))
} }
companion object { companion object {
@ -338,13 +352,23 @@ class DriverDSL(
) )
fun <A> pickA(array: Array<A>): A = array[Math.abs(Random().nextInt()) % array.size] fun <A> pickA(array: Array<A>): A = array[Math.abs(Random().nextInt()) % array.size]
private fun startNode(cliParams: NodeRunner.CliParams, quasarJarPath: String, debugPort: Int): Process { private fun startNode(
config: Config,
cliParams: NodeRunner.CliParams,
legalName: String,
quasarJarPath: String,
debugPort: Int
): Process {
// Write node.conf
writeConfig("${cliParams.baseDirectory}", "node.conf", config)
val className = NodeRunner::class.java.canonicalName val className = NodeRunner::class.java.canonicalName
val separator = System.getProperty("file.separator") val separator = System.getProperty("file.separator")
val classpath = System.getProperty("java.class.path") val classpath = System.getProperty("java.class.path")
val path = System.getProperty("java.home") + separator + "bin" + separator + "java" val path = System.getProperty("java.home") + separator + "bin" + separator + "java"
val javaArgs = listOf(path) + val javaArgs = listOf(path) +
listOf("-Dname=${cliParams.legalName}", "-javaagent:$quasarJarPath", listOf("-Dname=$legalName", "-javaagent:$quasarJarPath",
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$debugPort", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$debugPort",
"-cp", classpath, className) + "-cp", classpath, className) +
cliParams.toCliArguments() cliParams.toCliArguments()
@ -362,3 +386,9 @@ class DriverDSL(
} }
} }
} }
fun writeConfig(path: String, filename: String, config: Config) {
File(path).mkdirs()
File("$path/$filename").writeText(config.root().render(ConfigRenderOptions.concise()))
}

View File

@ -7,12 +7,10 @@ import com.r3corda.core.crypto.toBase58String
import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.ServiceType
import com.r3corda.node.internal.Node import com.r3corda.node.internal.Node
import com.r3corda.node.services.config.NodeConfiguration
import com.r3corda.node.services.messaging.ArtemisMessagingClient import com.r3corda.node.services.messaging.ArtemisMessagingClient
import com.r3corda.node.services.config.NodeConfigurationFromConfig import com.r3corda.node.services.config.NodeConfigurationFromConfig
import com.r3corda.node.services.config.copy
import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.network.NetworkMapService
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigParseOptions
import joptsimple.ArgumentAcceptingOptionSpec import joptsimple.ArgumentAcceptingOptionSpec
import joptsimple.OptionParser import joptsimple.OptionParser
import joptsimple.OptionSet import joptsimple.OptionSet
@ -30,7 +28,7 @@ class NodeRunner {
@JvmStatic fun main(arguments: Array<String>) { @JvmStatic fun main(arguments: Array<String>) {
val cliParams = CliParams.parse(CliParams.parser.parse(*arguments)) val cliParams = CliParams.parse(CliParams.parser.parse(*arguments))
val nodeDirectory = Paths.get(cliParams.baseDirectory, cliParams.legalName) val nodeDirectory = Paths.get(cliParams.baseDirectory)
createNodeRunDirectory(nodeDirectory) createNodeRunDirectory(nodeDirectory)
with(cliParams) { with(cliParams) {
@ -48,14 +46,11 @@ class NodeRunner {
} else { } else {
null null
} }
val nodeConfiguration = val nodeConfiguration = NodeConfigurationFromConfig(
NodeConfigurationFromConfig( NodeConfiguration.loadConfig(
ConfigFactory.parseResources( baseDirectoryPath = nodeDirectory,
nodeConfigurationPath, allowMissingConfig = false
ConfigParseOptions.defaults().setAllowMissing(false)
) )
).copy(
myLegalName = legalName
) )
val node = Node( val node = Node(
@ -67,7 +62,7 @@ class NodeRunner {
advertisedServices = services.toSet() advertisedServices = services.toSet()
) )
log.info("Starting $legalName with services $services on addresses $messagingAddress and $apiAddress") log.info("Starting ${nodeConfiguration.myLegalName} with services $services on addresses $messagingAddress and $apiAddress")
node.start() node.start()
} }
} }
@ -80,9 +75,7 @@ class NodeRunner {
val networkMapAddress: HostAndPort?, val networkMapAddress: HostAndPort?,
val messagingAddress: HostAndPort, val messagingAddress: HostAndPort,
val apiAddress: HostAndPort, val apiAddress: HostAndPort,
val baseDirectory: String, val baseDirectory: String
val nodeConfigurationPath: String,
val legalName: String
) { ) {
companion object { companion object {
@ -101,10 +94,6 @@ class NodeRunner {
parser.accepts("api-address").withRequiredArg().ofType(String::class.java) parser.accepts("api-address").withRequiredArg().ofType(String::class.java)
val baseDirectory = val baseDirectory =
parser.accepts("base-directory").withRequiredArg().ofType(String::class.java) parser.accepts("base-directory").withRequiredArg().ofType(String::class.java)
val nodeConfigurationPath =
parser.accepts("node-configuration-path").withRequiredArg().ofType(String::class.java)
val legalName =
parser.accepts("legal-name").withRequiredArg().ofType(String::class.java)
private fun <T> requiredArgument(optionSet: OptionSet, spec: ArgumentAcceptingOptionSpec<T>) = private fun <T> requiredArgument(optionSet: OptionSet, spec: ArgumentAcceptingOptionSpec<T>) =
optionSet.valueOf(spec) ?: throw IllegalArgumentException("Must provide $spec") optionSet.valueOf(spec) ?: throw IllegalArgumentException("Must provide $spec")
@ -117,8 +106,6 @@ class NodeRunner {
val messagingAddress = requiredArgument(optionSet, messagingAddress) val messagingAddress = requiredArgument(optionSet, messagingAddress)
val apiAddress = requiredArgument(optionSet, apiAddress) val apiAddress = requiredArgument(optionSet, apiAddress)
val baseDirectory = requiredArgument(optionSet, baseDirectory) val baseDirectory = requiredArgument(optionSet, baseDirectory)
val nodeConfigurationPath = requiredArgument(optionSet, nodeConfigurationPath)
val legalName = requiredArgument(optionSet, legalName)
return CliParams( return CliParams(
services = services.map { object : ServiceType(it) {} }.toSet(), services = services.map { object : ServiceType(it) {} }.toSet(),
@ -127,9 +114,7 @@ class NodeRunner {
baseDirectory = baseDirectory, baseDirectory = baseDirectory,
networkMapName = networkMapName, networkMapName = networkMapName,
networkMapPublicKey = networkMapPublicKey, networkMapPublicKey = networkMapPublicKey,
networkMapAddress = networkMapAddress?.let { HostAndPort.fromString(it) }, networkMapAddress = networkMapAddress?.let { HostAndPort.fromString(it) }
nodeConfigurationPath = nodeConfigurationPath,
legalName = legalName
) )
} }
} }
@ -158,10 +143,6 @@ class NodeRunner {
cliArguments.add(apiAddress.toString()) cliArguments.add(apiAddress.toString())
cliArguments.add("--base-directory") cliArguments.add("--base-directory")
cliArguments.add(baseDirectory.toString()) cliArguments.add(baseDirectory.toString())
cliArguments.add("--node-configuration-path")
cliArguments.add(nodeConfigurationPath)
cliArguments.add("--legal-name")
cliArguments.add(legalName)
return cliArguments return cliArguments
} }
} }