Exposed RPC SSL settings through Cordformation (#2419)

This commit is contained in:
Michele Sollecito
2018-01-25 14:32:58 +00:00
committed by GitHub
parent 5f8af818b1
commit 9783f11ba8
25 changed files with 422 additions and 52 deletions

View File

@ -47,6 +47,7 @@ public class StandaloneCordaRPCJavaClientTest {
port.getAndIncrement(),
port.getAndIncrement(),
port.getAndIncrement(),
port.getAndIncrement(),
true,
Collections.singletonList(rpcUser)
);

View File

@ -60,6 +60,7 @@ class StandaloneCordaRPClientTest {
legalName = CordaX500Name(organisation = "Notary Service", locality = "Zurich", country = "CH"),
p2pPort = port.andIncrement,
rpcPort = port.andIncrement,
rpcAdminPort = port.andIncrement,
webPort = port.andIncrement,
isNotary = true,
users = listOf(user)

View File

@ -37,6 +37,7 @@ class NodeVersioningTest {
legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"),
p2pPort = port.andIncrement,
rpcPort = port.andIncrement,
rpcAdminPort = port.andIncrement,
webPort = port.andIncrement,
isNotary = false,
users = listOf(user)

View File

@ -33,6 +33,7 @@ class CordappSmokeTest {
legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"),
p2pPort = port.andIncrement,
rpcPort = port.andIncrement,
rpcAdminPort = port.andIncrement,
webPort = port.andIncrement,
isNotary = false,
users = listOf(user)

View File

@ -95,6 +95,9 @@ public class CordformNode implements NodeDefinition {
*/
@Nullable
public String getRpcAddress() {
if (config.hasPath("rpcSettings.address")) {
return config.getConfig("rpcSettings").getString("address");
}
return getOptionalString("rpcAddress");
}
@ -102,7 +105,9 @@ public class CordformNode implements NodeDefinition {
* Set the Artemis RPC port for this node on localhost.
*
* @param rpcPort The Artemis RPC queue port.
* @deprecated Use {@link CordformNode#rpcSettings(RpcSettings)} instead.
*/
@Deprecated
public void rpcPort(int rpcPort) {
rpcAddress(DEFAULT_HOST + ':' + rpcPort);
}
@ -111,7 +116,9 @@ public class CordformNode implements NodeDefinition {
* Set the Artemis RPC address for this node.
*
* @param rpcAddress The Artemis RPC queue host and port.
* @deprecated Use {@link CordformNode#rpcSettings(RpcSettings)} instead.
*/
@Deprecated
public void rpcAddress(String rpcAddress) {
setValue("rpcAddress", rpcAddress);
}
@ -140,6 +147,13 @@ public class CordformNode implements NodeDefinition {
setValue("webAddress", webAddress);
}
/**
* Specifies RPC settings for the node.
*/
public void rpcSettings(RpcSettings settings) {
config = settings.addTo("rpcSettings", config);
}
/**
* Set the path to a file with optional properties, which are appended to the generated node.conf file.
*

View File

@ -0,0 +1,56 @@
package net.corda.cordform;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigValueFactory;
public final class RpcSettings {
private Config config = ConfigFactory.empty();
/**
* RPC address for the node.
*/
public final void address(final String value) {
setValue("address", value);
}
/**
* RPC admin address for the node (necessary if [useSsl] is false or unset).
*/
public final void adminAddress(final String value) {
setValue("adminAddress", value);
}
/**
* Specifies whether the node RPC layer will require SSL from clients.
*/
public final void useSsl(final Boolean value) {
setValue("useSsl", value);
}
/**
* Specifies whether the RPC broker is separate from the node.
*/
public final void standAloneBroker(final Boolean value) {
setValue("standAloneBroker", value);
}
/**
* Specifies SSL certificates options for the RPC layer.
*/
public final void ssl(final SslOptions options) {
config = options.addTo("ssl", config);
}
final Config addTo(final String key, final Config config) {
if (this.config.isEmpty()) {
return config;
}
return config.withValue(key, this.config.root());
}
private void setValue(String path, Object value) {
config = config.withValue(path, ConfigValueFactory.fromAnyRef(value));
}
}

View File

@ -0,0 +1,56 @@
package net.corda.cordform;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigValueFactory;
public final class SslOptions {
private Config config = ConfigFactory.empty();
/**
* Password for the keystore.
*/
public final void keyStorePassword(final String value) {
setValue("keyStorePassword", value);
}
/**
* Password for the truststore.
*/
public final void trustStorePassword(final String value) {
setValue("trustStorePassword", value);
}
/**
* Directory under which key stores are to be placed.
*/
public final void certificatesDirectory(final String value) {
setValue("certificatesDirectory", value);
}
/**
* Absolute path to SSL keystore. Default: "[certificatesDirectory]/sslkeystore.jks"
*/
public final void sslKeystore(final String value) {
setValue("sslKeystore", value);
}
/**
* Absolute path to SSL truststore. Default: "[certificatesDirectory]/truststore.jks"
*/
public final void trustStoreFile(final String value) {
setValue("trustStoreFile", value);
}
final Config addTo(final String key, final Config config) {
if (this.config.isEmpty()) {
return config;
}
return config.withValue(key, this.config.root());
}
private void setValue(String path, Object value) {
config = config.withValue(path, ConfigValueFactory.fromAnyRef(value));
}
}

View File

@ -3,6 +3,7 @@ package net.corda.plugins
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigRenderOptions
import com.typesafe.config.ConfigValueFactory
import groovy.lang.Closure
import net.corda.cordform.CordformNode
import org.gradle.api.Project
import java.io.File
@ -54,6 +55,14 @@ class Node(private val project: Project) : CordformNode() {
config = config.withValue("useTestClock", ConfigValueFactory.fromAnyRef(useTestClock))
}
/**
* Specifies RPC settings for the node.
*/
fun rpcSettings(configureClosure: Closure<in RpcSettings>) {
val rpcSettings = project.configure(RpcSettings(project), configureClosure) as RpcSettings
config = rpcSettings.addTo("rpcSettings", config)
}
/**
* Enables SSH access on given port
*
@ -158,7 +167,7 @@ class Node(private val project: Project) : CordformNode() {
// Need to write a temporary file first to use the project.copy, which resolves directories correctly.
val tmpDir = File(project.buildDir, "tmp")
Files.createDirectories(tmpDir.toPath())
var fileName = "${nodeDir.getName()}.conf"
var fileName = "${nodeDir.name}.conf"
val tmpConfFile = File(tmpDir, fileName)
Files.write(tmpConfFile.toPath(), configFileText, StandardCharsets.UTF_8)
return tmpConfFile

View File

@ -0,0 +1,59 @@
package net.corda.plugins
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigValueFactory
import groovy.lang.Closure
import org.gradle.api.Project
class RpcSettings(private val project: Project) {
private var config: Config = ConfigFactory.empty()
/**
* RPC address for the node.
*/
fun address(value: String) {
config += "address" to value
}
/**
* RPC admin address for the node (necessary if [useSsl] is false or unset).
*/
fun adminAddress(value: String) {
config += "adminAddress" to value
}
/**
* Specifies whether the node RPC layer will require SSL from clients.
*/
fun useSsl(value: Boolean) {
config += "useSsl" to value
}
/**
* Specifies whether the RPC broker is separate from the node.
*/
fun standAloneBroker(value: Boolean) {
config += "standAloneBroker" to value
}
/**
* Specifies SSL certificates options for the RPC layer.
*/
fun ssl(configureClosure: Closure<in SslOptions>) {
val sslOptions = project.configure(SslOptions(), configureClosure) as SslOptions
config = sslOptions.addTo("ssl", config)
}
internal fun addTo(key: String, config: Config): Config {
if (this.config.isEmpty) {
return config
}
return config + (key to this.config.root())
}
}
internal operator fun Config.plus(entry: Pair<String, Any>): Config {
return withValue(entry.first, ConfigValueFactory.fromAnyRef(entry.second))
}

View File

@ -0,0 +1,50 @@
package net.corda.plugins
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
class SslOptions {
private var config: Config = ConfigFactory.empty()
/**
* Password for the keystore.
*/
fun keyStorePassword(value: String) {
config += "keyStorePassword" to value
}
/**
* Password for the truststore.
*/
fun trustStorePassword(value: String) {
config += "trustStorePassword" to value
}
/**
* Directory under which key stores are to be placed.
*/
fun certificatesDirectory(value: String) {
config += "certificatesDirectory" to value
}
/**
* Absolute path to SSL keystore. Default: "[certificatesDirectory]/sslkeystore.jks"
*/
fun sslKeystore(value: String) {
config += "sslKeystore" to value
}
/**
* Absolute path to SSL truststore. Default: "[certificatesDirectory]/truststore.jks"
*/
fun trustStoreFile(value: String) {
config += "trustStoreFile" to value
}
internal fun addTo(key: String, config: Config): Config {
if (this.config.isEmpty) {
return config
}
return config + (key to this.config.root())
}
}

View File

@ -140,8 +140,9 @@ class SSHServerTest {
val response = String(Streams.readAll(channel.inputStream))
val linesWithDoneCount = response.lines().filter { line -> line.contains("Done") }
// There are ANSI control characters involved, so we want to avoid direct byte to byte matching.
assertThat(response.lines()).filteredOn( { it.contains("Done")}).hasSize(1)
assertThat(linesWithDoneCount).hasSize(1)
}
}

View File

@ -154,7 +154,9 @@ open class Node(configuration: NodeConfiguration,
val advertisedAddress = info.addresses.single()
printBasicNodeInfo("Incoming connection address", advertisedAddress.toString())
rpcMessagingClient = RPCMessagingClient(configuration.rpcOptions.sslConfig, rpcServerAddresses.admin, networkParameters.maxMessageSize)
rpcServerAddresses?.let {
rpcMessagingClient = RPCMessagingClient(configuration.rpcOptions.sslConfig, it.admin, networkParameters.maxMessageSize)
}
verifierMessagingClient = when (configuration.verifierType) {
VerifierType.OutOfProcess -> VerifierMessagingClient(configuration, serverAddress, services.monitoringService.metrics, networkParameters.maxMessageSize)
VerifierType.InMemory -> null
@ -173,18 +175,20 @@ open class Node(configuration: NodeConfiguration,
networkParameters.maxMessageSize)
}
private fun startLocalRpcBroker(): BrokerAddresses {
private fun startLocalRpcBroker(): BrokerAddresses? {
with(configuration) {
require(rpcOptions.address != null) { "RPC address needs to be specified for local RPC broker." }
val rpcBrokerDirectory: Path = baseDirectory / "brokers" / "rpc"
with(rpcOptions) {
rpcBroker = if (useSsl) {
ArtemisRpcBroker.withSsl(this.address!!, sslConfig, securityManager, certificateChainCheckPolicies, networkParameters.maxMessageSize, exportJMXto.isNotEmpty(), rpcBrokerDirectory)
} else {
ArtemisRpcBroker.withoutSsl(this.address!!, adminAddress!!, sslConfig, securityManager, certificateChainCheckPolicies, networkParameters.maxMessageSize, exportJMXto.isNotEmpty(), rpcBrokerDirectory)
return rpcOptions.address?.let {
require(rpcOptions.address != null) { "RPC address needs to be specified for local RPC broker." }
val rpcBrokerDirectory: Path = baseDirectory / "brokers" / "rpc"
with(rpcOptions) {
rpcBroker = if (useSsl) {
ArtemisRpcBroker.withSsl(this.address!!, sslConfig, securityManager, certificateChainCheckPolicies, networkParameters.maxMessageSize, exportJMXto.isNotEmpty(), rpcBrokerDirectory)
} else {
ArtemisRpcBroker.withoutSsl(this.address!!, adminAddress!!, sslConfig, securityManager, certificateChainCheckPolicies, networkParameters.maxMessageSize, exportJMXto.isNotEmpty(), rpcBrokerDirectory)
}
}
return rpcBroker!!.addresses
}
return rpcBroker!!.addresses
}
}
@ -250,7 +254,7 @@ open class Node(configuration: NodeConfiguration,
start()
}
// Start up the MQ clients.
rpcMessagingClient.run {
rpcMessagingClient?.run {
runOnStop += this::close
start(rpcOps, securityManager)
}
@ -353,11 +357,11 @@ open class Node(configuration: NodeConfiguration,
checkpointContext = KRYO_CHECKPOINT_CONTEXT.withClassLoader(classloader))
}
private lateinit var rpcMessagingClient: RPCMessagingClient
private var rpcMessagingClient: RPCMessagingClient? = null
private var verifierMessagingClient: VerifierMessagingClient? = null
/** Starts a blocking event loop for message dispatch. */
fun run() {
rpcMessagingClient.start2(rpcBroker!!.serverControl)
rpcMessagingClient?.start2(rpcBroker!!.serverControl)
verifierMessagingClient?.start2()
(network as P2PMessagingClient).run()
}

View File

@ -47,21 +47,30 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
name "O=Notary Service,L=Zurich,C=CH"
notary = [validating : true]
p2pPort 10002
rpcPort 10003
cordapps = []
rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10003"
adminAddress "localhost:10004"
}
}
node {
name "O=Bank A,L=London,C=GB"
p2pPort 10005
rpcPort 10006
cordapps = []
rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10006"
adminAddress "localhost:10007"
}
}
node {
name "O=Bank B,L=New York,C=US"
p2pPort 10008
rpcPort 10009
rpcSettings {
address "localhost:10009"
adminAddress "localhost:10011"
}
webPort 10010
cordapps = []
rpcUsers = ext.rpcUsers

View File

@ -20,8 +20,9 @@ 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")
private val BOC_RPC_PORT = 10006
private val BOC_WEB_PORT = 10007
private const val BOC_RPC_PORT = 10006
private const val BOC_RPC_ADMIN_PORT = 10015
private const val BOC_WEB_PORT = 10007
class BankOfCordaCordform : CordformDefinition() {
init {
@ -30,20 +31,29 @@ class BankOfCordaCordform : CordformDefinition() {
name(NOTARY_NAME)
notary(NotaryConfig(validating = true))
p2pPort(10002)
rpcPort(10003)
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10004")
}
}
node {
name(BOC_NAME)
extraConfig = mapOf("issuableCurrencies" to listOf("USD"))
p2pPort(10005)
rpcPort(BOC_RPC_PORT)
rpcSettings {
address("localhost:$BOC_RPC_PORT")
adminAddress("localhost:$BOC_RPC_ADMIN_PORT")
}
webPort(BOC_WEB_PORT)
rpcUsers(User("bankUser", "test", setOf(all())))
}
node {
name(BIGCORP_NAME)
p2pPort(10008)
rpcPort(10009)
rpcSettings {
address("localhost:10009")
adminAddress("localhost:10011")
}
webPort(10010)
rpcUsers(User("bigCorpUser", "test", setOf(all())))
}

View File

@ -64,7 +64,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
name "O=Notary Service,L=Zurich,C=CH"
notary = [validating : true]
p2pPort 10002
rpcPort 10003
rpcSettings {
address "localhost:10003"
adminAddress "localhost:10023"
}
cordapps = ["${project.group}:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
useTestClock true
@ -72,7 +75,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
node {
name "O=Bank A,L=London,C=GB"
p2pPort 10005
rpcPort 10006
rpcSettings {
address "localhost:10006"
adminAddress "localhost:10026"
}
cordapps = ["${project.group}:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
useTestClock true
@ -80,7 +86,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
node {
name "O=Bank B,L=New York,C=US"
p2pPort 10008
rpcPort 10009
rpcSettings {
address "localhost:10009"
adminAddress "localhost:10029"
}
cordapps = ["${project.group}:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
useTestClock true

View File

@ -29,13 +29,19 @@ class BFTNotaryCordform : CordformDefinition() {
node {
name(ALICE_NAME)
p2pPort(10002)
rpcPort(10003)
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10103")
}
rpcUsers(notaryDemoUser)
}
node {
name(BOB_NAME)
p2pPort(10005)
rpcPort(10006)
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10106")
}
}
val clusterAddresses = (0 until clusterSize).map { NetworkHostAndPort("localhost", 11000 + it * 10) }
fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node {
@ -45,19 +51,31 @@ class BFTNotaryCordform : CordformDefinition() {
}
notaryNode(0) {
p2pPort(10009)
rpcPort(10010)
rpcSettings {
address("localhost:10010")
adminAddress("localhost:10110")
}
}
notaryNode(1) {
p2pPort(10013)
rpcPort(10014)
rpcSettings {
address("localhost:10014")
adminAddress("localhost:10114")
}
}
notaryNode(2) {
p2pPort(10017)
rpcPort(10018)
rpcSettings {
address("localhost:10018")
adminAddress("localhost:10118")
}
}
notaryNode(3) {
p2pPort(10021)
rpcPort(10022)
rpcSettings {
address("localhost:10022")
adminAddress("localhost:10122")
}
}
}

View File

@ -17,18 +17,27 @@ class CustomNotaryCordform : CordformDefinition() {
node {
name(ALICE_NAME)
p2pPort(10002)
rpcPort(10003)
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10103")
}
rpcUsers(notaryDemoUser)
}
node {
name(BOB_NAME)
p2pPort(10005)
rpcPort(10006)
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10106")
}
}
node {
name(DUMMY_NOTARY_NAME)
p2pPort(10009)
rpcPort(10010)
rpcSettings {
address("localhost:10010")
adminAddress("localhost:10110")
}
notary(NotaryConfig(validating = true, custom = true))
}
}

View File

@ -29,13 +29,19 @@ class RaftNotaryCordform : CordformDefinition() {
node {
name(ALICE_NAME)
p2pPort(10002)
rpcPort(10003)
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10103")
}
rpcUsers(notaryDemoUser)
}
node {
name(BOB_NAME)
p2pPort(10005)
rpcPort(10006)
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10106")
}
}
fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node {
name(notaryNames[index])
@ -45,15 +51,24 @@ class RaftNotaryCordform : CordformDefinition() {
}
notaryNode(0, 10008) {
p2pPort(10009)
rpcPort(10010)
rpcSettings {
address("localhost:10010")
adminAddress("localhost:10110")
}
}
notaryNode(1, 10012, 10008) {
p2pPort(10013)
rpcPort(10014)
rpcSettings {
address("localhost:10014")
adminAddress("localhost:10114")
}
}
notaryNode(2, 10016, 10008) {
p2pPort(10017)
rpcPort(10018)
rpcSettings {
address("localhost:10018")
adminAddress("localhost:10118")
}
}
}

View File

@ -23,18 +23,27 @@ class SingleNotaryCordform : CordformDefinition() {
node {
name(ALICE_NAME)
p2pPort(10002)
rpcPort(10003)
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10103")
}
rpcUsers(notaryDemoUser)
}
node {
name(BOB_NAME)
p2pPort(10005)
rpcPort(10006)
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10106")
}
}
node {
name(DUMMY_NOTARY_NAME)
p2pPort(10009)
rpcPort(10010)
rpcSettings {
address("localhost:10010")
adminAddress("localhost:10110")
}
notary(NotaryConfig(validating = true))
}
}

View File

@ -77,7 +77,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
name "O=Bank A,L=London,C=GB"
p2pPort 10004
webPort 10005
rpcPort 10006
rpcSettings {
address("localhost:10016")
adminAddress("localhost:10017")
}
cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
extraConfig = [
@ -88,7 +91,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
name "O=Bank B,L=New York,C=US"
p2pPort 10007
webPort 10008
rpcPort 10009
rpcSettings {
address("localhost:10026")
adminAddress("localhost:10027")
}
cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
extraConfig = [
@ -99,7 +105,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
name "O=Bank C,L=Tokyo,C=JP"
p2pPort 10010
webPort 10011
rpcPort 10012
rpcSettings {
address("localhost:10036")
adminAddress("localhost:10037")
}
cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
extraConfig = [

View File

@ -55,23 +55,32 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
node {
name "O=Bank A,L=London,C=GB"
p2pPort 10005
rpcPort 10006
cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10006"
adminAddress "localhost:10007"
}
}
node {
name "O=Bank B,L=New York,C=US"
p2pPort 10008
rpcPort 10009
cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10009"
adminAddress "localhost:10010"
}
}
node {
name "O=BankOfCorda,L=New York,C=US"
p2pPort 10011
rpcPort 10012
cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10012"
adminAddress "localhost:10013"
}
}
}

View File

@ -4,6 +4,8 @@ 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
@ -22,3 +24,11 @@ fun CordformNode.rpcUsers(vararg users: User) {
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)
}

View File

@ -12,6 +12,7 @@ class NodeConfig(
val legalName: CordaX500Name,
val p2pPort: Int,
val rpcPort: Int,
val rpcAdminPort: Int,
val webPort: Int,
val isNotary: Boolean,
val users: List<User>
@ -32,7 +33,10 @@ class NodeConfig(
.withValue("myLegalName", valueFor(legalName.toString()))
.withValue("p2pAddress", addressValueFor(p2pPort))
.withValue("webAddress", addressValueFor(webPort))
.withValue("rpcAddress", addressValueFor(rpcPort))
.withValue("rpcSettings", empty()
.withValue("address", addressValueFor(rpcPort))
.withValue("adminAddress", addressValueFor(rpcAdminPort))
.root())
.withValue("rpcUsers", valueFor(users.map(User::toMap).toList()))
.withValue("useTestClock", valueFor(true))
return if (isNotary) {

View File

@ -11,6 +11,7 @@ import net.corda.core.utilities.contextLogger
import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.common.internal.asContextEnv
import java.net.URL
import java.nio.file.Path
import java.nio.file.Paths
import java.time.Instant
@ -51,8 +52,13 @@ class NodeProcess(
// as a CorDapp for the nodes.
class Factory(
val buildDirectory: Path = Paths.get("build"),
val cordaJar: Path = Paths.get(this::class.java.getResource("/corda.jar").toURI())
val cordaJarUrl: URL? = this::class.java.getResource("/corda.jar")
) {
val cordaJar: Path by lazy {
require(cordaJarUrl != null, { "corda.jar could not be found in classpath" })
Paths.get(cordaJarUrl!!.toURI())
}
private companion object {
val javaPath: Path = Paths.get(System.getProperty("java.home"), "bin", "java")
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(systemDefault())

View File

@ -18,7 +18,7 @@ class WebServerConfig(override val baseDirectory: Path, val config: Config) : No
val myLegalName: String by config
val rpcAddress: NetworkHostAndPort by lazy {
if (config.hasPath("rpcSettings.address")) {
return@lazy NetworkHostAndPort.parse(config.getString("rpcSettings.address"))
return@lazy NetworkHostAndPort.parse(config.getConfig("rpcSettings").getString("address"))
}
if (config.hasPath("rpcAddress")) {
return@lazy NetworkHostAndPort.parse(config.getString("rpcAddress"))