mirror of
https://github.com/corda/corda.git
synced 2025-04-08 20:04:51 +00:00
Merged in pat-move-certificate-path-to-config (pull request #374)
Moved certificates path to node configuration
This commit is contained in:
commit
e2c793df05
@ -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"
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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<ServiceType>, 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ServiceType>, 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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ArtemisMessagingServer>()
|
||||
}
|
||||
@ -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))
|
||||
)
|
||||
|
@ -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<NodeMessagingClient>()
|
||||
|
||||
@ -103,7 +99,7 @@ class NodeMessagingClient(directory: Path,
|
||||
private val handlers = CopyOnWriteArrayList<Handler>()
|
||||
|
||||
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() {
|
||||
|
@ -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<CertificateSigner>()
|
||||
}
|
||||
|
||||
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<String>) {
|
||||
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()
|
||||
}
|
||||
|
||||
|
@ -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<ServiceType>, 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
|
||||
|
@ -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<ServiceType>, 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<ServiceType>, 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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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<ServiceType>, 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)
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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<String>) {
|
||||
|
||||
// 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<String>) {
|
||||
|
||||
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]
|
||||
|
@ -140,7 +140,7 @@ fun main(args: Array<String>) {
|
||||
|
||||
// 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
|
||||
|
@ -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<ServiceType>, id: Int, keyPair: KeyPair?) : MockNetwork.MockNode(dir, config, mockNet, networkMapAddress, advertisedServices, id, keyPair) {
|
||||
open class SimulatedNode(config: NodeConfiguration, mockNet: MockNetwork, networkMapAddress: SingleMessageRecipient?,
|
||||
advertisedServices: Set<ServiceType>, 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<ServiceType>, 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<SimulatedNode> = 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<ServiceType>, 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<ServiceType>, 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<ServiceType>, 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<NodeInterestRates.Service>().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<ServiceType>, 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.
|
||||
|
@ -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<ServiceType>, 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<ServiceType>, 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<ServiceType>, 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<ServiceType>, val id: Int, val keyPair: KeyPair?) : AbstractNode(config, networkMapAddr, advertisedServices, TestClock()) {
|
||||
override val log: Logger = loggerFor<MockNode>()
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user