From eee18b55f53f8801681f768507b363028cf59cb8 Mon Sep 17 00:00:00 2001 From: Patrick Kuo Date: Thu, 22 Sep 2016 13:11:49 +0100 Subject: [PATCH] Moved certificates path to node configuration --- .../com/r3corda/client/CordaRPCClient.kt | 5 ++- .../kotlin/com/r3corda/node/driver/Driver.kt | 10 ++--- .../com/r3corda/node/internal/AbstractNode.kt | 8 ++-- .../kotlin/com/r3corda/node/internal/Node.kt | 23 +++++------ .../node/services/config/NodeConfiguration.kt | 14 ++++--- .../messaging/ArtemisMessagingComponent.kt | 22 +++++------ .../messaging/ArtemisMessagingServer.kt | 9 ++--- .../services/messaging/NodeMessagingClient.kt | 10 ++--- .../certsigning/CertificateSigner.kt | 24 ++++++------ .../r3corda/node/messaging/AttachmentTests.kt | 4 +- .../messaging/TwoPartyTradeProtocolTests.kt | 8 ++-- .../node/services/ArtemisMessagingTests.kt | 39 +++++++++++-------- .../PersistentNetworkMapServiceTest.kt | 4 +- .../certsigning/CertificateSignerTest.kt | 22 +++++------ src/main/kotlin/com/r3corda/demos/IRSDemo.kt | 8 ++-- .../kotlin/com/r3corda/demos/RateFixDemo.kt | 5 ++- .../kotlin/com/r3corda/demos/TraderDemo.kt | 2 +- .../com/r3corda/simulation/Simulation.kt | 30 +++++++------- .../com/r3corda/testing/node/MockNode.kt | 15 +++---- 19 files changed, 132 insertions(+), 130 deletions(-) diff --git a/client/src/main/kotlin/com/r3corda/client/CordaRPCClient.kt b/client/src/main/kotlin/com/r3corda/client/CordaRPCClient.kt index 7a214379dd..ba6ba5ae96 100644 --- a/client/src/main/kotlin/com/r3corda/client/CordaRPCClient.kt +++ b/client/src/main/kotlin/com/r3corda/client/CordaRPCClient.kt @@ -24,11 +24,12 @@ import kotlin.concurrent.thread * useful tasks. See the documentation for [proxy] or review the docsite to learn more about how this API works. */ @ThreadSafe -class CordaRPCClient(val host: HostAndPort, certificatesPath: Path) : Closeable, ArtemisMessagingComponent(certificatesPath, sslConfig()) { +class CordaRPCClient(val host: HostAndPort, certificatesPath: Path) : Closeable, ArtemisMessagingComponent(sslConfig(certificatesPath)) { companion object { private val rpcLog = LoggerFactory.getLogger("com.r3corda.rpc") - private fun sslConfig(): NodeSSLConfiguration = object : NodeSSLConfiguration { + private fun sslConfig(certificatesPath: Path): NodeSSLConfiguration = object : NodeSSLConfiguration { + override val certificatesPath: Path = certificatesPath override val keyStorePassword = "cordacadevpass" override val trustStorePassword = "trustpass" } diff --git a/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt b/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt index df353c760d..058511a13b 100644 --- a/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt +++ b/node/src/main/kotlin/com/r3corda/node/driver/Driver.kt @@ -10,9 +10,9 @@ import com.r3corda.core.node.services.ServiceType import com.r3corda.node.services.config.FullNodeConfiguration import com.r3corda.node.services.config.NodeConfiguration import com.r3corda.node.services.config.NodeConfigurationFromConfig -import com.r3corda.node.services.messaging.NodeMessagingClient import com.r3corda.node.services.messaging.ArtemisMessagingComponent import com.r3corda.node.services.messaging.ArtemisMessagingServer +import com.r3corda.node.services.messaging.NodeMessagingClient import com.r3corda.node.services.network.InMemoryNetworkMapCache import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.transactions.NotaryService @@ -335,9 +335,7 @@ class DriverDSL( ) ) ) - val client = NodeMessagingClient( - Paths.get(baseDirectory, providedName), - nodeConfiguration, + val client = NodeMessagingClient(nodeConfiguration, serverHostPort = serverAddress, myIdentity = identity.public, executor = AffinityExecutor.ServiceAffinityExecutor(providedName, 1), @@ -366,9 +364,7 @@ class DriverDSL( ) ) ) - val server = ArtemisMessagingServer( - Paths.get(baseDirectory, name), - config, + val server = ArtemisMessagingServer(config, portAllocation.nextHostAndPort(), networkMapCache ) diff --git a/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt index a242005294..72ff00b1f3 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt @@ -66,7 +66,7 @@ import java.util.concurrent.TimeUnit // TODO: Where this node is the initial network map service, currently no networkMapService is provided. // In theory the NodeInfo for the node should be passed in, instead, however currently this is constructed by the // AbstractNode. It should be possible to generate the NodeInfo outside of AbstractNode, so it can be passed in. -abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, val networkMapService: SingleMessageRecipient?, +abstract class AbstractNode(val configuration: NodeConfiguration, val networkMapService: SingleMessageRecipient?, val advertisedServices: Set, val platformClock: Clock): SingletonSerializeAsToken() { companion object { val PRIVATE_KEY_FILE_NAME = "identity-private-key" @@ -162,7 +162,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, // Do all of this in a database transaction so anything that might need a connection has one. initialiseDatabasePersistence() { - val storageServices = initialiseStorageService(dir) + val storageServices = initialiseStorageService(configuration.basedir) storage = storageServices.first checkpointStorage = storageServices.second netMapCache = InMemoryNetworkMapCache() @@ -453,8 +453,8 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, } protected fun createNodeDir() { - if (!Files.exists(dir)) { - Files.createDirectories(dir) + if (!Files.exists(configuration.basedir)) { + Files.createDirectories(configuration.basedir) } } } diff --git a/node/src/main/kotlin/com/r3corda/node/internal/Node.kt b/node/src/main/kotlin/com/r3corda/node/internal/Node.kt index b1e784b699..fcf64a50d2 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/Node.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/Node.kt @@ -10,8 +10,8 @@ import com.r3corda.node.serialization.NodeClock import com.r3corda.node.services.api.MessagingServiceInternal import com.r3corda.node.services.config.FullNodeConfiguration import com.r3corda.node.services.config.NodeConfiguration -import com.r3corda.node.services.messaging.NodeMessagingClient import com.r3corda.node.services.messaging.ArtemisMessagingServer +import com.r3corda.node.services.messaging.NodeMessagingClient import com.r3corda.node.services.transactions.PersistentUniquenessProvider import com.r3corda.node.servlets.AttachmentDownloadServlet import com.r3corda.node.servlets.Config @@ -38,7 +38,6 @@ import java.time.Clock import java.util.* import javax.management.ObjectName import javax.servlet.* -import javax.servlet.http.HttpServletResponse import kotlin.concurrent.thread class ConfigurationException(message: String) : Exception(message) @@ -58,10 +57,10 @@ class ConfigurationException(message: String) : Exception(message) * @param clock The clock used within the node and by all protocols etc. * @param messagingServerAddr The address of the Artemis broker instance. If not provided the node will run one locally. */ -class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, +class Node(val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, configuration: NodeConfiguration, networkMapAddress: SingleMessageRecipient?, advertisedServices: Set, clock: Clock = NodeClock(), - val messagingServerAddr: HostAndPort? = null) : AbstractNode(dir, configuration, networkMapAddress, advertisedServices, clock) { + val messagingServerAddr: HostAndPort? = null) : AbstractNode(configuration, networkMapAddress, advertisedServices, clock) { companion object { /** The port that is used by default if none is specified. As you know, 31337 is the most elite number. */ @JvmField @@ -120,14 +119,14 @@ class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, override fun makeMessagingService(): MessagingServiceInternal { val serverAddr = messagingServerAddr ?: { - messageBroker = ArtemisMessagingServer(dir, configuration, p2pAddr, services.networkMapCache) + messageBroker = ArtemisMessagingServer(configuration, p2pAddr, services.networkMapCache) p2pAddr }() val ops = ServerRPCOps(services) if (networkMapService != null) { - return NodeMessagingClient(dir, configuration, serverAddr, services.storageService.myLegalIdentityKey.public, serverThread, rpcOps = ops) + return NodeMessagingClient(configuration, serverAddr, services.storageService.myLegalIdentityKey.public, serverThread, rpcOps = ops) } else { - return NodeMessagingClient(dir, configuration, serverAddr, null, serverThread, rpcOps = ops) + return NodeMessagingClient(configuration, serverAddr, null, serverThread, rpcOps = ops) } } @@ -172,12 +171,10 @@ class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, httpsConfiguration.outputBufferSize = 32768 httpsConfiguration.addCustomizer(SecureRequestCustomizer()) val sslContextFactory = SslContextFactory() - val keyStorePath = dir.resolve("certificates").resolve("sslkeystore.jks") - val trustStorePath = dir.resolve("certificates").resolve("truststore.jks") - sslContextFactory.setKeyStorePath(keyStorePath.toString()) + sslContextFactory.setKeyStorePath(configuration.keyStorePath.toString()) sslContextFactory.setKeyStorePassword(configuration.keyStorePassword) sslContextFactory.setKeyManagerPassword(configuration.keyStorePassword) - sslContextFactory.setTrustStorePath(trustStorePath.toString()) + sslContextFactory.setTrustStorePath(configuration.trustStorePath.toString()) sslContextFactory.setTrustStorePassword(configuration.trustStorePassword) sslContextFactory.setExcludeProtocols("SSL.*", "TLSv1", "TLSv1.1") sslContextFactory.setIncludeProtocols("TLSv1.2") @@ -316,7 +313,7 @@ class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, // file that we'll do our best to delete on exit. But if we don't, it'll be overwritten next time. If it already // exists, we try to take the file lock first before replacing it and if that fails it means we're being started // twice with the same directory: that's a user error and we should bail out. - val pidPath = dir.resolve("process-id") + val pidPath = configuration.basedir.resolve("process-id") val file = pidPath.toFile() if (!file.exists()) { file.createNewFile() @@ -325,7 +322,7 @@ class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, val f = RandomAccessFile(file, "rw") val l = f.channel.tryLock() if (l == null) { - log.error("It appears there is already a node running with the specified data directory $dir") + log.error("It appears there is already a node running with the specified data directory ${configuration.basedir}") log.error("Shut that other node down and try again. It may have process ID ${file.readText()}") System.exit(1) } diff --git a/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt index c7c64ade8d..0257ad964d 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/config/NodeConfiguration.kt @@ -1,6 +1,7 @@ package com.r3corda.node.services.config import com.google.common.net.HostAndPort +import com.r3corda.core.div import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.services.ServiceType import com.r3corda.node.internal.Node @@ -25,11 +26,14 @@ import kotlin.reflect.jvm.javaType interface NodeSSLConfiguration { val keyStorePassword: String val trustStorePassword: String - - // TODO: Move cert paths into this interface as well. + val certificatesPath: Path + val keyStorePath: Path get() = certificatesPath / "sslkeystore.jks" + val trustStorePath: Path get() = certificatesPath / "truststore.jks" } interface NodeConfiguration : NodeSSLConfiguration { + val basedir: Path + override val certificatesPath: Path get() = basedir / "certificates" val myLegalName: String val nearestCity: String val emailAddress: String @@ -100,6 +104,7 @@ fun Config.getProperties(path: String): Properties { } class NodeConfigurationFromConfig(val config: Config = ConfigFactory.load()) : NodeConfiguration { + override val basedir: Path by config override val myLegalName: String by config override val nearestCity: String by config override val emailAddress: String by config @@ -112,7 +117,7 @@ class NodeConfigurationFromConfig(val config: Config = ConfigFactory.load()) : N } class FullNodeConfiguration(conf: Config) : NodeConfiguration { - val basedir: Path by conf + override val basedir: Path by conf override val myLegalName: String by conf override val nearestCity: String by conf override val emailAddress: String by conf @@ -141,8 +146,7 @@ class FullNodeConfiguration(conf: Config) : NodeConfiguration { } if (networkMapAddress == null) advertisedServices.add(NetworkMapService.Type) val networkMapMessageAddress: SingleMessageRecipient? = if (networkMapAddress == null) null else NodeMessagingClient.makeNetworkMapAddress(networkMapAddress) - return Node(basedir.toAbsolutePath().normalize(), - artemisAddress, + return Node(artemisAddress, webAddress, this, networkMapMessageAddress, diff --git a/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingComponent.kt b/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingComponent.kt index 4502b089b1..aa973ec1ac 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingComponent.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingComponent.kt @@ -27,9 +27,7 @@ import java.security.PublicKey * @param certificatePath A place where Artemis can stash its message journal and other files. * @param config The config object is used to pass in the passwords for the certificate KeyStore and TrustStore */ -abstract class ArtemisMessagingComponent(val certificatePath: Path, val config: NodeSSLConfiguration) : SingletonSerializeAsToken() { - val keyStorePath: Path = certificatePath / "sslkeystore.jks" - val trustStorePath: Path = certificatePath / "truststore.jks" +abstract class ArtemisMessagingComponent(val config: NodeSSLConfiguration) : SingletonSerializeAsToken() { companion object { init { @@ -116,10 +114,10 @@ abstract class ArtemisMessagingComponent(val certificatePath: Path, val config: * unfortunately Artemis tends to bury the exception when the password is wrong. */ fun checkStorePasswords() { - keyStorePath.use { + config.keyStorePath.use { KeyStore.getInstance("JKS").load(it, config.keyStorePassword.toCharArray()) } - trustStorePath.use { + config.trustStorePath.use { KeyStore.getInstance("JKS").load(it, config.trustStorePassword.toCharArray()) } } @@ -145,10 +143,10 @@ abstract class ArtemisMessagingComponent(val certificatePath: Path, val config: // and AES encryption TransportConstants.SSL_ENABLED_PROP_NAME to true, TransportConstants.KEYSTORE_PROVIDER_PROP_NAME to "JKS", - TransportConstants.KEYSTORE_PATH_PROP_NAME to keyStorePath, + TransportConstants.KEYSTORE_PATH_PROP_NAME to config.keyStorePath, TransportConstants.KEYSTORE_PASSWORD_PROP_NAME to config.keyStorePassword, // TODO proper management of keystores and password TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME to "JKS", - TransportConstants.TRUSTSTORE_PATH_PROP_NAME to trustStorePath, + TransportConstants.TRUSTSTORE_PATH_PROP_NAME to config.trustStorePath, TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME to config.trustStorePassword, TransportConstants.ENABLED_CIPHER_SUITES_PROP_NAME to CIPHER_SUITES.joinToString(","), TransportConstants.ENABLED_PROTOCOLS_PROP_NAME to "TLSv1.2", @@ -161,16 +159,16 @@ abstract class ArtemisMessagingComponent(val certificatePath: Path, val config: * the CA certs in Node resources. Then provision KeyStores into certificates folder under node path. */ fun configureWithDevSSLCertificate() { - Files.createDirectories(certificatePath) - if (!Files.exists(trustStorePath)) { + Files.createDirectories(config.certificatesPath) + if (!Files.exists(config.trustStorePath)) { Files.copy(javaClass.classLoader.getResourceAsStream("com/r3corda/node/internal/certificates/cordatruststore.jks"), - trustStorePath) + config.trustStorePath) } - if (!Files.exists(keyStorePath)) { + if (!Files.exists(config.keyStorePath)) { val caKeyStore = X509Utilities.loadKeyStore( javaClass.classLoader.getResourceAsStream("com/r3corda/node/internal/certificates/cordadevcakeys.jks"), "cordacadevpass") - X509Utilities.createKeystoreForSSL(keyStorePath, config.keyStorePassword, config.keyStorePassword, caKeyStore, "cordacadevkeypass") + X509Utilities.createKeystoreForSSL(config.keyStorePath, config.keyStorePassword, config.keyStorePassword, caKeyStore, "cordacadevkeypass") } } } diff --git a/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingServer.kt b/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingServer.kt index a8e0da6a8e..1a582fb038 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingServer.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/messaging/ArtemisMessagingServer.kt @@ -4,9 +4,7 @@ import com.google.common.net.HostAndPort import com.r3corda.core.ThreadBox import com.r3corda.core.crypto.AddressFormatException import com.r3corda.core.crypto.newSecureRandom -import com.r3corda.core.div import com.r3corda.core.messaging.SingleMessageRecipient -import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.core.utilities.loggerFor import com.r3corda.node.services.config.NodeConfiguration @@ -39,10 +37,9 @@ import javax.annotation.concurrent.ThreadSafe * a fully connected network, trusted network or on localhost. */ @ThreadSafe -class ArtemisMessagingServer(directory: Path, - config: NodeConfiguration, +class ArtemisMessagingServer(config: NodeConfiguration, val myHostPort: HostAndPort, - val networkMapCache: NetworkMapCache) : ArtemisMessagingComponent(directory / "certificates", config) { + val networkMapCache: NetworkMapCache) : ArtemisMessagingComponent(config) { companion object { val log = loggerFor() } @@ -119,7 +116,7 @@ class ArtemisMessagingServer(directory: Path, } private fun configureAndStartServer() { - val config = createArtemisConfig(certificatePath, myHostPort).apply { + val config = createArtemisConfig(config.certificatesPath, myHostPort).apply { securityRoles = mapOf( "#" to setOf(Role("internal", true, true, true, true, true, true, true)) ) diff --git a/node/src/main/kotlin/com/r3corda/node/services/messaging/NodeMessagingClient.kt b/node/src/main/kotlin/com/r3corda/node/services/messaging/NodeMessagingClient.kt index 102ea4d5eb..beb4d5d52c 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/messaging/NodeMessagingClient.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/messaging/NodeMessagingClient.kt @@ -2,7 +2,6 @@ package com.r3corda.node.services.messaging import com.google.common.net.HostAndPort import com.r3corda.core.ThreadBox -import com.r3corda.core.div import com.r3corda.core.messaging.* import com.r3corda.core.serialization.SerializedBytes import com.r3corda.core.serialization.opaque @@ -15,7 +14,6 @@ import org.apache.activemq.artemis.api.core.ActiveMQObjectClosedException import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.client.* import java.nio.file.FileSystems -import java.nio.file.Path import java.security.PublicKey import java.time.Instant import java.util.concurrent.CopyOnWriteArrayList @@ -46,14 +44,12 @@ import javax.annotation.concurrent.ThreadSafe * If false the inbox queue will be transient, which is appropriate for UI clients for example. */ @ThreadSafe -class NodeMessagingClient(directory: Path, - config: NodeConfiguration, +class NodeMessagingClient(config: NodeConfiguration, val serverHostPort: HostAndPort, val myIdentity: PublicKey?, val executor: AffinityExecutor, val persistentInbox: Boolean = true, - private val rpcOps: CordaRPCOps? = null) -: ArtemisMessagingComponent(directory / "certificates", config), MessagingServiceInternal { + private val rpcOps: CordaRPCOps? = null) : ArtemisMessagingComponent(config), MessagingServiceInternal { companion object { val log = loggerFor() @@ -103,7 +99,7 @@ class NodeMessagingClient(directory: Path, private val handlers = CopyOnWriteArrayList() init { - require(directory.fileSystem == FileSystems.getDefault()) { "Artemis only uses the default file system" } + require(config.basedir.fileSystem == FileSystems.getDefault()) { "Artemis only uses the default file system" } } fun start() { diff --git a/node/src/main/kotlin/com/r3corda/node/utilities/certsigning/CertificateSigner.kt b/node/src/main/kotlin/com/r3corda/node/utilities/certsigning/CertificateSigner.kt index b73c6011c1..52437e07b7 100644 --- a/node/src/main/kotlin/com/r3corda/node/utilities/certsigning/CertificateSigner.kt +++ b/node/src/main/kotlin/com/r3corda/node/utilities/certsigning/CertificateSigner.kt @@ -11,10 +11,8 @@ import com.r3corda.core.minutes import com.r3corda.core.utilities.loggerFor import com.r3corda.node.services.config.FullNodeConfiguration import com.r3corda.node.services.config.NodeConfiguration -import com.r3corda.node.services.messaging.ArtemisMessagingComponent import joptsimple.OptionParser import java.nio.file.Files -import java.nio.file.Path import java.nio.file.Paths import java.security.KeyPair import java.security.cert.Certificate @@ -26,23 +24,25 @@ import kotlin.system.exitProcess * This process will enter a slow polling loop until the request has been approved, and then * the certificate chain will be downloaded and stored in [KeyStore] reside in [certificatePath]. */ -class CertificateSigner(certificatePath: Path, val nodeConfig: NodeConfiguration, val certService: CertificateSigningService) : ArtemisMessagingComponent(certificatePath, nodeConfig) { +class CertificateSigner(val config: NodeConfiguration, val certService: CertificateSigningService) { companion object { val pollInterval = 1.minutes val log = loggerFor() } fun buildKeyStore() { - val caKeyStore = X509Utilities.loadOrCreateKeyStore(keyStorePath, config.keyStorePassword) + Files.createDirectories(config.certificatesPath) + + val caKeyStore = X509Utilities.loadOrCreateKeyStore(config.keyStorePath, config.keyStorePassword) if (!caKeyStore.containsAlias(CORDA_CLIENT_CA)) { // No certificate found in key store, create certificate signing request and post request to signing server. log.info("No certificate found in key store, creating certificate signing request...") // Create or load key pair from the key store. - val keyPair = X509Utilities.loadOrCreateKeyPairFromKeyStore(keyStorePath, config.keyStorePassword, + val keyPair = X509Utilities.loadOrCreateKeyPairFromKeyStore(config.keyStorePath, config.keyStorePassword, config.keyStorePassword, CORDA_CLIENT_CA_PRIVATE_KEY) { - X509Utilities.createSelfSignedCACert(nodeConfig.myLegalName) + X509Utilities.createSelfSignedCACert(config.myLegalName) } log.info("Submitting certificate signing request to Corda certificate signing server.") val requestId = submitCertificateSigningRequest(keyPair) @@ -58,15 +58,15 @@ class CertificateSigner(certificatePath: Path, val nodeConfig: NodeConfiguration // Assumes certificate chain always starts with client certificate and end with root certificate. caKeyStore.addOrReplaceCertificate(CORDA_CLIENT_CA, certificates.first()) - X509Utilities.saveKeyStore(caKeyStore, keyStorePath, config.keyStorePassword) + X509Utilities.saveKeyStore(caKeyStore, config.keyStorePath, config.keyStorePassword) // Save certificates to trust store. - val trustStore = X509Utilities.loadOrCreateKeyStore(trustStorePath, config.trustStorePassword) + val trustStore = X509Utilities.loadOrCreateKeyStore(config.trustStorePath, config.trustStorePassword) // Assumes certificate chain always starts with client certificate and end with root certificate. trustStore.addOrReplaceCertificate(CORDA_ROOT_CA, certificates.last()) - X509Utilities.saveKeyStore(trustStore, trustStorePath, config.trustStorePassword) + X509Utilities.saveKeyStore(trustStore, config.trustStorePath, config.trustStorePassword) } else { log.trace("Certificate already exists, exiting certificate signer...") } @@ -96,10 +96,10 @@ class CertificateSigner(certificatePath: Path, val nodeConfig: NodeConfiguration * @return Request ID return from the server. */ private fun submitCertificateSigningRequest(keyPair: KeyPair): String { - val requestIdStore = certificatePath / "certificate-request-id.txt" + val requestIdStore = config.certificatesPath / "certificate-request-id.txt" // Retrieve request id from file if exists, else post a request to server. return if (!Files.exists(requestIdStore)) { - val request = X509Utilities.createCertificateSigningRequest(nodeConfig.myLegalName, nodeConfig.nearestCity, nodeConfig.emailAddress, keyPair) + val request = X509Utilities.createCertificateSigningRequest(config.myLegalName, config.nearestCity, config.emailAddress, keyPair) // Post request to signing server via http. val requestId = certService.submitRequest(request) // Persists request ID to file in case of node shutdown. @@ -128,6 +128,6 @@ fun main(args: Array) { val configFile = if (cmdlineOptions.has(ParamsSpec.configFileArg)) Paths.get(cmdlineOptions.valueOf(ParamsSpec.configFileArg)) else null val conf = FullNodeConfiguration(NodeConfiguration.loadConfig(baseDirectoryPath, configFile, allowMissingConfig = true)) // TODO: Use HTTPS instead - CertificateSigner(baseDirectoryPath / "certificate", conf, HTTPCertificateSigningService(conf.certificateSigningService)).buildKeyStore() + CertificateSigner(conf, HTTPCertificateSigningService(conf.certificateSigningService)).buildKeyStore() } diff --git a/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt b/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt index 85ea8e0341..421057c651 100644 --- a/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt @@ -88,9 +88,9 @@ class AttachmentTests { fun `malicious response`() { // Make a node that doesn't do sanity checking at load time. val n0 = network.createNode(null, -1, object : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { - return object : MockNetwork.MockNode(dir, config, network, networkMapAddr, advertisedServices, id, keyPair) { + return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, keyPair) { override fun start(): MockNetwork.MockNode { super.start() (storage.attachments as NodeAttachmentService).checkAttachmentsOnLoad = false diff --git a/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt b/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt index 229d8aabc5..4ac574c4bb 100644 --- a/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt @@ -154,9 +154,9 @@ class TwoPartyTradeProtocolTests { // ... bring the node back up ... the act of constructing the SMM will re-register the message handlers // that Bob was waiting on before the reboot occurred. bobNode = net.createNode(networkMapAddr, bobAddr.id, object : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { - return MockNetwork.MockNode(dir, config, network, networkMapAddr, advertisedServices, bobAddr.id, BOB_KEY) + return MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, bobAddr.id, BOB_KEY) } }, true, BOB.name, BOB_KEY) @@ -184,9 +184,9 @@ class TwoPartyTradeProtocolTests { private fun makeNodeWithTracking(networkMapAddr: SingleMessageRecipient?, name: String, keyPair: KeyPair): MockNetwork.MockNode { // Create a node in the mock network ... return net.createNode(networkMapAddr, -1, object : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { - return object : MockNetwork.MockNode(dir, config, network, networkMapAddr, advertisedServices, id, keyPair) { + return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, keyPair) { // That constructs the storage service object in a customised way ... override fun constructStorageService(attachments: NodeAttachmentService, transactionStorage: TransactionStorage, diff --git a/node/src/test/kotlin/com/r3corda/node/services/ArtemisMessagingTests.kt b/node/src/test/kotlin/com/r3corda/node/services/ArtemisMessagingTests.kt index 2af75215ec..0b31a42f9c 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/ArtemisMessagingTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/ArtemisMessagingTests.kt @@ -5,17 +5,19 @@ import com.r3corda.core.crypto.generateKeyPair import com.r3corda.core.messaging.Message import com.r3corda.core.node.services.DEFAULT_SESSION_ID import com.r3corda.node.services.config.NodeConfiguration -import com.r3corda.node.services.messaging.NodeMessagingClient import com.r3corda.node.services.messaging.ArtemisMessagingServer +import com.r3corda.node.services.messaging.NodeMessagingClient import com.r3corda.node.services.network.InMemoryNetworkMapCache import com.r3corda.node.utilities.AffinityExecutor import com.r3corda.testing.freeLocalHostAndPort import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.After +import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder import java.net.ServerSocket +import java.nio.file.Path import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.TimeUnit.MILLISECONDS import kotlin.concurrent.thread @@ -29,25 +31,30 @@ class ArtemisMessagingTests { val topic = "platform.self" val identity = generateKeyPair() - // TODO: create a base class that provides a default implementation - val config = object : NodeConfiguration { - - override val myLegalName: String = "me" - override val nearestCity: String = "London" - override val emailAddress: String = "" - override val devMode: Boolean = true - override val exportJMXto: String = "" - override val keyStorePassword: String = "testpass" - override val trustStorePassword: String = "trustpass" - override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) - - } + lateinit var config: NodeConfiguration var messagingClient: NodeMessagingClient? = null var messagingServer: ArtemisMessagingServer? = null val networkMapCache = InMemoryNetworkMapCache() + @Before + fun setUp() { + // TODO: create a base class that provides a default implementation + config = object : NodeConfiguration { + override val basedir: Path = temporaryFolder.newFolder().toPath() + override val myLegalName: String = "me" + override val nearestCity: String = "London" + override val emailAddress: String = "" + override val devMode: Boolean = true + override val exportJMXto: String = "" + override val keyStorePassword: String = "testpass" + override val trustStorePassword: String = "trustpass" + override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) + + } + } + @After fun cleanUp() { messagingClient?.stop() @@ -111,14 +118,14 @@ class ArtemisMessagingTests { } private fun createMessagingClient(server: HostAndPort = hostAndPort): NodeMessagingClient { - return NodeMessagingClient(temporaryFolder.newFolder().toPath(), config, server, identity.public, AffinityExecutor.SAME_THREAD).apply { + return NodeMessagingClient(config, server, identity.public, AffinityExecutor.SAME_THREAD).apply { configureWithDevSSLCertificate() messagingClient = this } } private fun createMessagingServer(local: HostAndPort = hostAndPort): ArtemisMessagingServer { - return ArtemisMessagingServer(temporaryFolder.newFolder().toPath(), config, local, networkMapCache).apply { + return ArtemisMessagingServer(config, local, networkMapCache).apply { configureWithDevSSLCertificate() messagingServer = this } diff --git a/node/src/test/kotlin/com/r3corda/node/services/PersistentNetworkMapServiceTest.kt b/node/src/test/kotlin/com/r3corda/node/services/PersistentNetworkMapServiceTest.kt index 1d96815e31..7e9a815a98 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/PersistentNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/PersistentNetworkMapServiceTest.kt @@ -59,9 +59,9 @@ class PersistentNetworkMapServiceTest : AbstractNetworkMapServiceTest() { } private object NodeFactory : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { - return object : MockNetwork.MockNode(dir, config, network, networkMapAddr, advertisedServices, id, keyPair) { + return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, keyPair) { override fun makeNetworkMapService() { inNodeNetworkMapService = SwizzleNetworkMapService(services) diff --git a/node/src/test/kotlin/com/r3corda/node/utilities/certsigning/CertificateSignerTest.kt b/node/src/test/kotlin/com/r3corda/node/utilities/certsigning/CertificateSignerTest.kt index 1b23defabc..606dc15073 100644 --- a/node/src/test/kotlin/com/r3corda/node/utilities/certsigning/CertificateSignerTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/utilities/certsigning/CertificateSignerTest.kt @@ -12,6 +12,7 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder import java.nio.file.Files +import java.nio.file.Path import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -35,13 +36,9 @@ class CertificateSignerTest { on { retrieveCertificates(eq(id)) }.then { certs } } - val keyStore = tempFolder.root.toPath().resolve("sslkeystore.jks") - val tmpTrustStore = tempFolder.root.toPath().resolve("truststore.jks") - - assertFalse(Files.exists(keyStore)) - assertFalse(Files.exists(tmpTrustStore)) val config = object : NodeConfiguration { + override val basedir: Path = tempFolder.root.toPath() override val myLegalName: String = "me" override val nearestCity: String = "London" override val emailAddress: String = "" @@ -52,12 +49,15 @@ class CertificateSignerTest { override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) } - CertificateSigner(tempFolder.root.toPath(), config, certService).buildKeyStore() + assertFalse(Files.exists(config.keyStorePath)) + assertFalse(Files.exists(config.trustStorePath)) - assertTrue(Files.exists(keyStore)) - assertTrue(Files.exists(tmpTrustStore)) + CertificateSigner(config, certService).buildKeyStore() - X509Utilities.loadKeyStore(keyStore, config.keyStorePassword).run { + assertTrue(Files.exists(config.keyStorePath)) + assertTrue(Files.exists(config.trustStorePath)) + + X509Utilities.loadKeyStore(config.keyStorePath, config.keyStorePassword).run { assertTrue(containsAlias(X509Utilities.CORDA_CLIENT_CA_PRIVATE_KEY)) assertTrue(containsAlias(X509Utilities.CORDA_CLIENT_CA)) assertFalse(containsAlias(X509Utilities.CORDA_INTERMEDIATE_CA)) @@ -66,7 +66,7 @@ class CertificateSignerTest { assertFalse(containsAlias(X509Utilities.CORDA_ROOT_CA_PRIVATE_KEY)) } - X509Utilities.loadKeyStore(tmpTrustStore, config.trustStorePassword).run { + X509Utilities.loadKeyStore(config.trustStorePath, config.trustStorePassword).run { assertFalse(containsAlias(X509Utilities.CORDA_CLIENT_CA_PRIVATE_KEY)) assertFalse(containsAlias(X509Utilities.CORDA_CLIENT_CA)) assertFalse(containsAlias(X509Utilities.CORDA_INTERMEDIATE_CA)) @@ -75,7 +75,7 @@ class CertificateSignerTest { assertFalse(containsAlias(X509Utilities.CORDA_ROOT_CA_PRIVATE_KEY)) } - assertEquals(id, Files.readAllLines(tempFolder.root.toPath() / "certificate-request-id.txt").first()) + assertEquals(id, Files.readAllLines(config.certificatesPath / "certificate-request-id.txt").first()) } } \ No newline at end of file diff --git a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt index 16d2f5ab27..8d6167aeab 100644 --- a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt @@ -321,7 +321,7 @@ private fun setup(params: CliParams.SetupNode): Int { val configFile = params.dir.resolve("config") val config = loadConfigFile(params.dir, configFile, params.defaultLegalName) if (!Files.exists(params.dir.resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME))) { - createIdentities(params, config) + createIdentities(config) } return 0 } @@ -407,7 +407,7 @@ private fun startNode(params: CliParams.RunNode, networkMap: SingleMessageRecipi } val node = logElapsedTime("Node startup", log) { - Node(params.dir, params.networkAddress, params.apiAddress, config, networkMapId, advertisedServices, DemoClock()).setup().start() + Node(params.networkAddress, params.apiAddress, config, networkMapId, advertisedServices, DemoClock()).setup().start() } return node @@ -459,9 +459,9 @@ private fun loadConfigFile(baseDir: Path, configFile: Path, defaultLegalName: St return NodeConfigurationFromConfig(NodeConfiguration.loadConfig(baseDir, configFileOverride = configFile)) } -private fun createIdentities(params: CliParams.SetupNode, nodeConf: NodeConfiguration) { +private fun createIdentities(nodeConf: NodeConfiguration) { val mockNetwork = MockNetwork(false) - val node = MockNetwork.MockNode(params.dir, nodeConf, mockNetwork, null, setOf(NetworkMapService.Type, SimpleNotaryService.Type), 0, null) + val node = MockNetwork.MockNode(nodeConf, mockNetwork, null, setOf(NetworkMapService.Type, SimpleNotaryService.Type), 0, null) node.start() node.stop() } diff --git a/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt b/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt index d9c153be26..1dffdebb63 100644 --- a/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt @@ -18,6 +18,7 @@ import joptsimple.OptionParser import org.slf4j.Logger import org.slf4j.LoggerFactory import java.math.BigDecimal +import java.nio.file.Path import java.nio.file.Paths import java.util.* import kotlin.system.exitProcess @@ -61,7 +62,7 @@ fun main(args: Array) { // TODO: create a base class that provides a default implementation val config = object : NodeConfiguration { - + override val basedir: Path = dir override val myLegalName: String = "Rate fix demo node" override val nearestCity: String = "Atlantis" override val emailAddress: String = "" @@ -76,7 +77,7 @@ fun main(args: Array) { val apiAddr = HostAndPort.fromParts(myNetAddr.hostText, myNetAddr.port + 1) - val node = logElapsedTime("Node startup") { Node(dir, myNetAddr, apiAddr, config, networkMapAddr, + val node = logElapsedTime("Node startup") { Node(myNetAddr, apiAddr, config, networkMapAddr, advertisedServices, DemoClock()).setup().start() } node.networkMapRegistrationFuture.get() val notaryNode = node.services.networkMapCache.notaryNodes[0] diff --git a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt index 7dc1f1f41a..bb05506203 100644 --- a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt @@ -140,7 +140,7 @@ fun main(args: Array) { // And now construct then start the node object. It takes a little while. val node = logElapsedTime("Node startup", log) { - Node(directory, myNetAddr, apiNetAddr, config, networkMapId, advertisedServices).setup().start() + Node(myNetAddr, apiNetAddr, config, networkMapId, advertisedServices).setup().start() } // What happens next depends on the role. The buyer sits around waiting for a trade to start. The seller role diff --git a/src/main/kotlin/com/r3corda/simulation/Simulation.kt b/src/main/kotlin/com/r3corda/simulation/Simulation.kt index 2e8fa0f9fd..e00d2da435 100644 --- a/src/main/kotlin/com/r3corda/simulation/Simulation.kt +++ b/src/main/kotlin/com/r3corda/simulation/Simulation.kt @@ -45,22 +45,22 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, // This puts together a mock network of SimulatedNodes. - open class SimulatedNode(dir: Path, config: NodeConfiguration, mockNet: MockNetwork, networkMapAddress: SingleMessageRecipient?, - advertisedServices: Set, id: Int, keyPair: KeyPair?) : MockNetwork.MockNode(dir, config, mockNet, networkMapAddress, advertisedServices, id, keyPair) { + open class SimulatedNode(config: NodeConfiguration, mockNet: MockNetwork, networkMapAddress: SingleMessageRecipient?, + advertisedServices: Set, id: Int, keyPair: KeyPair?) : MockNetwork.MockNode(config, mockNet, networkMapAddress, advertisedServices, id, keyPair) { override fun findMyLocation(): PhysicalLocation? = CityDatabase[configuration.nearestCity] } inner class BankFactory : MockNetwork.Factory { var counter = 0 - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { val letter = 'A' + counter val city = bankLocations[counter++ % bankLocations.size] // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { - + override val basedir: Path = config.basedir // TODO: Set this back to "Bank of $city" after video day. override val myLegalName: String = "Bank $letter" override val nearestCity: String = city @@ -71,7 +71,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, override val trustStorePassword: String = "trustpass" override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) } - return SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) + return SimulatedNode(cfg, network, networkMapAddr, advertisedServices, id, keyPair) } fun createAll(): List = bankLocations. @@ -81,12 +81,13 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val bankFactory = BankFactory() object NetworkMapNodeFactory : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { require(advertisedServices.contains(NetworkMapService.Type)) // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { + override val basedir: Path = config.basedir override val myLegalName: String = "Network coordination center" override val nearestCity: String = "Amsterdam" override val emailAddress: String = "" @@ -97,17 +98,18 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) } - return object : SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) {} + return object : SimulatedNode(cfg, network, networkMapAddr, advertisedServices, id, keyPair) {} } } object NotaryNodeFactory : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { require(advertisedServices.contains(SimpleNotaryService.Type)) // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { + override val basedir: Path = config.basedir override val myLegalName: String = "Notary Service" override val nearestCity: String = "Zurich" override val emailAddress: String = "" @@ -117,17 +119,18 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, override val trustStorePassword: String = "trustpass" override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) } - return SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) + return SimulatedNode(cfg, network, networkMapAddr, advertisedServices, id, keyPair) } } object RatesOracleFactory : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { require(advertisedServices.contains(NodeInterestRates.Type)) // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { + override val basedir: Path = config.basedir override val myLegalName: String = "Rates Service Provider" override val nearestCity: String = "Madrid" override val emailAddress: String = "" @@ -138,7 +141,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) } - return object : SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) { + return object : SimulatedNode(cfg, network, networkMapAddr, advertisedServices, id, keyPair) { override fun start(): MockNetwork.MockNode { super.start() findService().upload(javaClass.getResourceAsStream("example.rates.txt")) @@ -149,11 +152,12 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } object RegulatorFactory : MockNetwork.Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { // TODO: create a base class that provides a default implementation val cfg = object : NodeConfiguration { + override val basedir: Path = config.basedir override val myLegalName: String = "Regulator A" override val nearestCity: String = "Paris" override val emailAddress: String = "" @@ -164,7 +168,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) } - val n = object : SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) { + val n = object : SimulatedNode(cfg, network, networkMapAddr, advertisedServices, id, keyPair) { // TODO: Regulatory nodes don't actually exist properly, this is a last minute demo request. // So we just fire a message at a node that doesn't know how to handle it, and it'll ignore it. // But that's fine for visualisation purposes. diff --git a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt index b3e8f2f0e5..7f7bf29aa7 100644 --- a/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt +++ b/test-utils/src/main/kotlin/com/r3corda/testing/node/MockNode.kt @@ -18,6 +18,7 @@ import com.r3corda.core.serialization.deserialize import com.r3corda.core.testing.InMemoryVaultService import com.r3corda.core.utilities.DUMMY_NOTARY_KEY import com.r3corda.core.utilities.loggerFor +import com.r3corda.node.internal.AbstractNode import com.r3corda.node.services.config.NodeConfiguration import com.r3corda.node.services.keys.E2ETestKeyManagementService import com.r3corda.node.services.network.InMemoryNetworkMapService @@ -61,19 +62,19 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, /** Allows customisation of how nodes are created. */ interface Factory { - fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNode } object DefaultFactory : Factory { - override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, + override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, advertisedServices: Set, id: Int, keyPair: KeyPair?): MockNode { - return MockNode(dir, config, network, networkMapAddr, advertisedServices, id, keyPair) + return MockNode(config, network, networkMapAddr, advertisedServices, id, keyPair) } } - open class MockNode(dir: Path, config: NodeConfiguration, val mockNet: MockNetwork, networkMapAddr: SingleMessageRecipient?, - advertisedServices: Set, val id: Int, val keyPair: KeyPair?) : com.r3corda.node.internal.AbstractNode(dir, config, networkMapAddr, advertisedServices, TestClock()) { + open class MockNode(config: NodeConfiguration, val mockNet: MockNetwork, networkMapAddr: SingleMessageRecipient?, + advertisedServices: Set, val id: Int, val keyPair: KeyPair?) : AbstractNode(config, networkMapAddr, advertisedServices, TestClock()) { override val log: Logger = loggerFor() override val serverThread: com.r3corda.node.utilities.AffinityExecutor = if (mockNet.threadPerNode) @@ -167,7 +168,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, // TODO: create a base class that provides a default implementation val config = object : NodeConfiguration { - + override val basedir: Path = path override val myLegalName: String = legalName ?: "Mock Company $id" override val nearestCity: String = "Atlantis" override val emailAddress: String = "" @@ -178,7 +179,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, override val dataSourceProperties: Properties get() = if (databasePersistence) makeTestDataSourceProperties("node_$id") else Properties() override val certificateSigningService: HostAndPort = HostAndPort.fromParts("localhost", 0) } - val node = nodeFactory.create(path, config, this, networkMapAddress, advertisedServices.toSet(), id, keyPair) + val node = nodeFactory.create(config, this, networkMapAddress, advertisedServices.toSet(), id, keyPair) if (start) { node.setup().start() if (threadPerNode && networkMapAddress != null)