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(),
port.getAndIncrement(), port.getAndIncrement(),
port.getAndIncrement(),
true, true,
Collections.singletonList(rpcUser) Collections.singletonList(rpcUser)
); );

View File

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

View File

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

View File

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

View File

@ -95,6 +95,9 @@ public class CordformNode implements NodeDefinition {
*/ */
@Nullable @Nullable
public String getRpcAddress() { public String getRpcAddress() {
if (config.hasPath("rpcSettings.address")) {
return config.getConfig("rpcSettings").getString("address");
}
return getOptionalString("rpcAddress"); return getOptionalString("rpcAddress");
} }
@ -102,7 +105,9 @@ public class CordformNode implements NodeDefinition {
* Set the Artemis RPC port for this node on localhost. * Set the Artemis RPC port for this node on localhost.
* *
* @param rpcPort The Artemis RPC queue port. * @param rpcPort The Artemis RPC queue port.
* @deprecated Use {@link CordformNode#rpcSettings(RpcSettings)} instead.
*/ */
@Deprecated
public void rpcPort(int rpcPort) { public void rpcPort(int rpcPort) {
rpcAddress(DEFAULT_HOST + ':' + rpcPort); rpcAddress(DEFAULT_HOST + ':' + rpcPort);
} }
@ -111,7 +116,9 @@ public class CordformNode implements NodeDefinition {
* Set the Artemis RPC address for this node. * Set the Artemis RPC address for this node.
* *
* @param rpcAddress The Artemis RPC queue host and port. * @param rpcAddress The Artemis RPC queue host and port.
* @deprecated Use {@link CordformNode#rpcSettings(RpcSettings)} instead.
*/ */
@Deprecated
public void rpcAddress(String rpcAddress) { public void rpcAddress(String rpcAddress) {
setValue("rpcAddress", rpcAddress); setValue("rpcAddress", rpcAddress);
} }
@ -140,6 +147,13 @@ public class CordformNode implements NodeDefinition {
setValue("webAddress", webAddress); 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. * 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.ConfigFactory
import com.typesafe.config.ConfigRenderOptions import com.typesafe.config.ConfigRenderOptions
import com.typesafe.config.ConfigValueFactory import com.typesafe.config.ConfigValueFactory
import groovy.lang.Closure
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import org.gradle.api.Project import org.gradle.api.Project
import java.io.File import java.io.File
@ -54,6 +55,14 @@ class Node(private val project: Project) : CordformNode() {
config = config.withValue("useTestClock", ConfigValueFactory.fromAnyRef(useTestClock)) 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 * 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. // Need to write a temporary file first to use the project.copy, which resolves directories correctly.
val tmpDir = File(project.buildDir, "tmp") val tmpDir = File(project.buildDir, "tmp")
Files.createDirectories(tmpDir.toPath()) Files.createDirectories(tmpDir.toPath())
var fileName = "${nodeDir.getName()}.conf" var fileName = "${nodeDir.name}.conf"
val tmpConfFile = File(tmpDir, fileName) val tmpConfFile = File(tmpDir, fileName)
Files.write(tmpConfFile.toPath(), configFileText, StandardCharsets.UTF_8) Files.write(tmpConfFile.toPath(), configFileText, StandardCharsets.UTF_8)
return tmpConfFile 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 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. // 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() val advertisedAddress = info.addresses.single()
printBasicNodeInfo("Incoming connection address", advertisedAddress.toString()) 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) { verifierMessagingClient = when (configuration.verifierType) {
VerifierType.OutOfProcess -> VerifierMessagingClient(configuration, serverAddress, services.monitoringService.metrics, networkParameters.maxMessageSize) VerifierType.OutOfProcess -> VerifierMessagingClient(configuration, serverAddress, services.monitoringService.metrics, networkParameters.maxMessageSize)
VerifierType.InMemory -> null VerifierType.InMemory -> null
@ -173,8 +175,9 @@ open class Node(configuration: NodeConfiguration,
networkParameters.maxMessageSize) networkParameters.maxMessageSize)
} }
private fun startLocalRpcBroker(): BrokerAddresses { private fun startLocalRpcBroker(): BrokerAddresses? {
with(configuration) { with(configuration) {
return rpcOptions.address?.let {
require(rpcOptions.address != null) { "RPC address needs to be specified for local RPC broker." } require(rpcOptions.address != null) { "RPC address needs to be specified for local RPC broker." }
val rpcBrokerDirectory: Path = baseDirectory / "brokers" / "rpc" val rpcBrokerDirectory: Path = baseDirectory / "brokers" / "rpc"
with(rpcOptions) { with(rpcOptions) {
@ -187,6 +190,7 @@ open class Node(configuration: NodeConfiguration,
return rpcBroker!!.addresses return rpcBroker!!.addresses
} }
} }
}
private fun makeLocalMessageBroker(): NetworkHostAndPort { private fun makeLocalMessageBroker(): NetworkHostAndPort {
with(configuration) { with(configuration) {
@ -250,7 +254,7 @@ open class Node(configuration: NodeConfiguration,
start() start()
} }
// Start up the MQ clients. // Start up the MQ clients.
rpcMessagingClient.run { rpcMessagingClient?.run {
runOnStop += this::close runOnStop += this::close
start(rpcOps, securityManager) start(rpcOps, securityManager)
} }
@ -353,11 +357,11 @@ open class Node(configuration: NodeConfiguration,
checkpointContext = KRYO_CHECKPOINT_CONTEXT.withClassLoader(classloader)) checkpointContext = KRYO_CHECKPOINT_CONTEXT.withClassLoader(classloader))
} }
private lateinit var rpcMessagingClient: RPCMessagingClient private var rpcMessagingClient: RPCMessagingClient? = null
private var verifierMessagingClient: VerifierMessagingClient? = null private var verifierMessagingClient: VerifierMessagingClient? = null
/** Starts a blocking event loop for message dispatch. */ /** Starts a blocking event loop for message dispatch. */
fun run() { fun run() {
rpcMessagingClient.start2(rpcBroker!!.serverControl) rpcMessagingClient?.start2(rpcBroker!!.serverControl)
verifierMessagingClient?.start2() verifierMessagingClient?.start2()
(network as P2PMessagingClient).run() (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" name "O=Notary Service,L=Zurich,C=CH"
notary = [validating : true] notary = [validating : true]
p2pPort 10002 p2pPort 10002
rpcPort 10003
cordapps = [] cordapps = []
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10003"
adminAddress "localhost:10004"
}
} }
node { node {
name "O=Bank A,L=London,C=GB" name "O=Bank A,L=London,C=GB"
p2pPort 10005 p2pPort 10005
rpcPort 10006
cordapps = [] cordapps = []
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10006"
adminAddress "localhost:10007"
}
} }
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
p2pPort 10008 p2pPort 10008
rpcPort 10009 rpcSettings {
address "localhost:10009"
adminAddress "localhost:10011"
}
webPort 10010 webPort 10010
cordapps = [] cordapps = []
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers

View File

@ -20,8 +20,9 @@ import kotlin.system.exitProcess
val BIGCORP_NAME = CordaX500Name(organisation = "BigCorporation", locality = "New York", country = "US") 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 NOTARY_NAME = CordaX500Name(organisation = "Notary Service", locality = "Zurich", country = "CH")
private val BOC_RPC_PORT = 10006 private const val BOC_RPC_PORT = 10006
private val BOC_WEB_PORT = 10007 private const val BOC_RPC_ADMIN_PORT = 10015
private const val BOC_WEB_PORT = 10007
class BankOfCordaCordform : CordformDefinition() { class BankOfCordaCordform : CordformDefinition() {
init { init {
@ -30,20 +31,29 @@ class BankOfCordaCordform : CordformDefinition() {
name(NOTARY_NAME) name(NOTARY_NAME)
notary(NotaryConfig(validating = true)) notary(NotaryConfig(validating = true))
p2pPort(10002) p2pPort(10002)
rpcPort(10003) rpcSettings {
address("localhost:10003")
adminAddress("localhost:10004")
}
} }
node { node {
name(BOC_NAME) name(BOC_NAME)
extraConfig = mapOf("issuableCurrencies" to listOf("USD")) extraConfig = mapOf("issuableCurrencies" to listOf("USD"))
p2pPort(10005) p2pPort(10005)
rpcPort(BOC_RPC_PORT) rpcSettings {
address("localhost:$BOC_RPC_PORT")
adminAddress("localhost:$BOC_RPC_ADMIN_PORT")
}
webPort(BOC_WEB_PORT) webPort(BOC_WEB_PORT)
rpcUsers(User("bankUser", "test", setOf(all()))) rpcUsers(User("bankUser", "test", setOf(all())))
} }
node { node {
name(BIGCORP_NAME) name(BIGCORP_NAME)
p2pPort(10008) p2pPort(10008)
rpcPort(10009) rpcSettings {
address("localhost:10009")
adminAddress("localhost:10011")
}
webPort(10010) webPort(10010)
rpcUsers(User("bigCorpUser", "test", setOf(all()))) 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" name "O=Notary Service,L=Zurich,C=CH"
notary = [validating : true] notary = [validating : true]
p2pPort 10002 p2pPort 10002
rpcPort 10003 rpcSettings {
address "localhost:10003"
adminAddress "localhost:10023"
}
cordapps = ["${project.group}:finance:$corda_release_version"] cordapps = ["${project.group}:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
useTestClock true useTestClock true
@ -72,7 +75,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
node { node {
name "O=Bank A,L=London,C=GB" name "O=Bank A,L=London,C=GB"
p2pPort 10005 p2pPort 10005
rpcPort 10006 rpcSettings {
address "localhost:10006"
adminAddress "localhost:10026"
}
cordapps = ["${project.group}:finance:$corda_release_version"] cordapps = ["${project.group}:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
useTestClock true useTestClock true
@ -80,7 +86,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
p2pPort 10008 p2pPort 10008
rpcPort 10009 rpcSettings {
address "localhost:10009"
adminAddress "localhost:10029"
}
cordapps = ["${project.group}:finance:$corda_release_version"] cordapps = ["${project.group}:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
useTestClock true useTestClock true

View File

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

View File

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

View File

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

View File

@ -23,18 +23,27 @@ class SingleNotaryCordform : CordformDefinition() {
node { node {
name(ALICE_NAME) name(ALICE_NAME)
p2pPort(10002) p2pPort(10002)
rpcPort(10003) rpcSettings {
address("localhost:10003")
adminAddress("localhost:10103")
}
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
p2pPort(10005) p2pPort(10005)
rpcPort(10006) rpcSettings {
address("localhost:10006")
adminAddress("localhost:10106")
}
} }
node { node {
name(DUMMY_NOTARY_NAME) name(DUMMY_NOTARY_NAME)
p2pPort(10009) p2pPort(10009)
rpcPort(10010) rpcSettings {
address("localhost:10010")
adminAddress("localhost:10110")
}
notary(NotaryConfig(validating = true)) 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" name "O=Bank A,L=London,C=GB"
p2pPort 10004 p2pPort 10004
webPort 10005 webPort 10005
rpcPort 10006 rpcSettings {
address("localhost:10016")
adminAddress("localhost:10017")
}
cordapps = ["$project.group:finance:$corda_release_version"] cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
extraConfig = [ extraConfig = [
@ -88,7 +91,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
p2pPort 10007 p2pPort 10007
webPort 10008 webPort 10008
rpcPort 10009 rpcSettings {
address("localhost:10026")
adminAddress("localhost:10027")
}
cordapps = ["$project.group:finance:$corda_release_version"] cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
extraConfig = [ extraConfig = [
@ -99,7 +105,10 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
name "O=Bank C,L=Tokyo,C=JP" name "O=Bank C,L=Tokyo,C=JP"
p2pPort 10010 p2pPort 10010
webPort 10011 webPort 10011
rpcPort 10012 rpcSettings {
address("localhost:10036")
adminAddress("localhost:10037")
}
cordapps = ["$project.group:finance:$corda_release_version"] cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
extraConfig = [ extraConfig = [

View File

@ -55,23 +55,32 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
node { node {
name "O=Bank A,L=London,C=GB" name "O=Bank A,L=London,C=GB"
p2pPort 10005 p2pPort 10005
rpcPort 10006
cordapps = ["$project.group:finance:$corda_release_version"] cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10006"
adminAddress "localhost:10007"
}
} }
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
p2pPort 10008 p2pPort 10008
rpcPort 10009
cordapps = ["$project.group:finance:$corda_release_version"] cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
rpcSettings {
address "localhost:10009"
adminAddress "localhost:10010"
}
} }
node { node {
name "O=BankOfCorda,L=New York,C=US" name "O=BankOfCorda,L=New York,C=US"
p2pPort 10011 p2pPort 10011
rpcPort 10012
cordapps = ["$project.group:finance:$corda_release_version"] cordapps = ["$project.group:finance:$corda_release_version"]
rpcUsers = ext.rpcUsers 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.CordformDefinition
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.cordform.RpcSettings
import net.corda.cordform.SslOptions
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.node.services.config.NotaryConfig import net.corda.node.services.config.NotaryConfig
import net.corda.nodeapi.internal.config.toConfig import net.corda.nodeapi.internal.config.toConfig
@ -22,3 +24,11 @@ fun CordformNode.rpcUsers(vararg users: User) {
fun CordformNode.notary(notaryConfig: NotaryConfig) { fun CordformNode.notary(notaryConfig: NotaryConfig) {
notary = notaryConfig.toConfig().root().unwrapped() 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 legalName: CordaX500Name,
val p2pPort: Int, val p2pPort: Int,
val rpcPort: Int, val rpcPort: Int,
val rpcAdminPort: Int,
val webPort: Int, val webPort: Int,
val isNotary: Boolean, val isNotary: Boolean,
val users: List<User> val users: List<User>
@ -32,7 +33,10 @@ class NodeConfig(
.withValue("myLegalName", valueFor(legalName.toString())) .withValue("myLegalName", valueFor(legalName.toString()))
.withValue("p2pAddress", addressValueFor(p2pPort)) .withValue("p2pAddress", addressValueFor(p2pPort))
.withValue("webAddress", addressValueFor(webPort)) .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("rpcUsers", valueFor(users.map(User::toMap).toList()))
.withValue("useTestClock", valueFor(true)) .withValue("useTestClock", valueFor(true))
return if (isNotary) { 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.nodeapi.internal.network.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.common.internal.asContextEnv import net.corda.testing.common.internal.asContextEnv
import java.net.URL
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.time.Instant import java.time.Instant
@ -51,8 +52,13 @@ class NodeProcess(
// as a CorDapp for the nodes. // as a CorDapp for the nodes.
class Factory( class Factory(
val buildDirectory: Path = Paths.get("build"), 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 { private companion object {
val javaPath: Path = Paths.get(System.getProperty("java.home"), "bin", "java") val javaPath: Path = Paths.get(System.getProperty("java.home"), "bin", "java")
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(systemDefault()) 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 myLegalName: String by config
val rpcAddress: NetworkHostAndPort by lazy { val rpcAddress: NetworkHostAndPort by lazy {
if (config.hasPath("rpcSettings.address")) { 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")) { if (config.hasPath("rpcAddress")) {
return@lazy NetworkHostAndPort.parse(config.getString("rpcAddress")) return@lazy NetworkHostAndPort.parse(config.getString("rpcAddress"))