Merge fixes

This commit is contained in:
Shams Asari 2017-12-08 18:07:02 +00:00
parent 65ff931f53
commit 41bfd7a971
13 changed files with 92 additions and 88 deletions

View File

@ -6,7 +6,7 @@ import net.corda.core.internal.cert
import net.corda.core.internal.div
import net.corda.core.utilities.getOrThrow
import net.corda.node.services.config.configureDevKeyAndTrustStores
import net.corda.nodeapi.config.SSLConfiguration
import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.nodeapi.internal.crypto.*
import net.corda.testing.ALICE_NAME
import net.corda.testing.driver.driver
@ -32,7 +32,7 @@ class NodeKeystoreCheckTest {
val config = object : SSLConfiguration {
override val keyStorePassword: String = keystorePassword
override val trustStorePassword: String = keystorePassword
override val certificatesDirectory: Path = baseDirectory(ALICE_NAME.toString()) / "certificates"
override val certificatesDirectory: Path = baseDirectory(ALICE_NAME) / "certificates"
}
config.configureDevKeyAndTrustStores(ALICE_NAME)
@ -49,7 +49,7 @@ class NodeKeystoreCheckTest {
val badRootKeyPair = Crypto.generateKeyPair()
val badRoot = X509Utilities.createSelfSignedCACertificate(CordaX500Name("Bad Root", "Lodnon", "GB"), badRootKeyPair)
val nodeCA = keystore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA, config.keyStorePassword)
val badNodeCACert = X509Utilities.createCertificate(CertificateType.CLIENT_CA, badRoot, badRootKeyPair, ALICE_NAME, nodeCA.keyPair.public)
val badNodeCACert = X509Utilities.createCertificate(CertificateType.NODE_CA, badRoot, badRootKeyPair, ALICE_NAME, nodeCA.keyPair.public)
keystore.setKeyEntry(X509Utilities.CORDA_CLIENT_CA, nodeCA.keyPair.private, config.keyStorePassword.toCharArray(), arrayOf(badNodeCACert.cert, badRoot.cert))
keystore.save(config.nodeKeystore, config.keyStorePassword)

View File

@ -4,10 +4,10 @@ import net.corda.core.node.NodeInfo
import net.corda.core.utilities.seconds
import net.corda.testing.ALICE
import net.corda.testing.BOB
import net.corda.testing.driver.CompatibilityZoneParams
import net.corda.testing.internal.CompatibilityZoneParams
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.internalDriver
import net.corda.testing.internal.internalDriver
import net.corda.testing.node.network.NetworkMapServer
import org.assertj.core.api.Assertions.assertThat
import org.junit.After

View File

@ -13,9 +13,9 @@ import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_CLIENT_CA
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_INTERMEDIATE_CA
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
import net.corda.testing.driver.CompatibilityZoneParams
import net.corda.testing.internal.CompatibilityZoneParams
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.internalDriver
import net.corda.testing.internal.internalDriver
import net.corda.testing.node.network.NetworkMapServer
import org.assertj.core.api.Assertions.assertThat
import org.bouncycastle.pkcs.PKCS10CertificationRequest
@ -126,7 +126,7 @@ class RegistrationHandler(private val rootCertAndKeyPair: CertificateAndKeyPair)
caCertPath: Array<Certificate>): Pair<CertPath, CordaX500Name> {
val request = JcaPKCS10CertificationRequest(certificationRequest)
val name = CordaX500Name.parse(request.subject.toString())
val x509CertificateHolder = X509Utilities.createCertificate(CertificateType.CLIENT_CA,
val x509CertificateHolder = X509Utilities.createCertificate(CertificateType.NODE_CA,
caCertPath.first().toX509CertHolder(),
caKeyPair,
name,

View File

@ -43,7 +43,6 @@ import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.config.configureWithDevSSLCertificate
import net.corda.node.services.events.NodeSchedulerService
import net.corda.node.services.events.ScheduledActivityObserver
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.services.keys.PersistentKeyManagementService
import net.corda.node.services.messaging.MessagingService
@ -69,7 +68,6 @@ import org.slf4j.Logger
import rx.Observable
import rx.Scheduler
import java.io.IOException
import java.io.NotSerializableException
import java.lang.reflect.InvocationTargetException
import java.security.KeyPair
import java.security.KeyStoreException
@ -183,7 +181,9 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
val (identity, identityKeyPair) = obtainIdentity(notaryConfig = null)
initialiseDatabasePersistence(schemaService, makeIdentityService(identity.certificate)) { database ->
val persistentNetworkMapCache = PersistentNetworkMapCache(database)
// TODO The fact that we need to specify an empty list of notaries just to generate our node info looks like
// a code smell.
val persistentNetworkMapCache = PersistentNetworkMapCache(database, notaries = emptyList())
val (keyPairs, info) = initNodeInfo(persistentNetworkMapCache, identity, identityKeyPair)
val identityKeypair = keyPairs.first { it.public == info.legalIdentities.first().owningKey }
val serialisedNodeInfo = info.serialize()
@ -203,7 +203,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
val identityService = makeIdentityService(identity.certificate)
// Do all of this in a database transaction so anything that might need a connection has one.
val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService, identityService) { database ->
val networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database), identityService)
val networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, networkParameters.notaries), identityService)
val (keyPairs, info) = initNodeInfo(networkMapCache, identity, identityKeyPair)
identityService.loadIdentities(info.legalIdentitiesAndCerts)
val transactionStorage = makeTransactionStorage(database)

View File

@ -7,9 +7,7 @@ import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.WebserverHandle
import net.corda.testing.internal.DriverDSLImpl
import net.corda.testing.internal.ProcessUtilities
import net.corda.testing.internal.addressMustBeBoundFuture
import net.corda.testing.internal.*
import net.corda.testing.node.NotarySpec
import okhttp3.OkHttpClient
import okhttp3.Request
@ -93,7 +91,7 @@ data class SpringBootDriverDSL(private val driverDSL: DriverDSLImpl) : InternalD
log.debug("Retrying webserver info at ${handle.webAddress}")
}
throw IllegalStateException("Webserver at ${handle.webAddress} has died or was not reachable at URL ${url}")
throw IllegalStateException("Webserver at ${handle.webAddress} has died or was not reachable at URL $url")
}
private fun startApplication(handle: NodeHandle, debugPort: Int?, clazz: Class<*>): Process {

View File

@ -2,6 +2,8 @@ package net.corda.testing.driver
import net.corda.core.concurrent.CordaFuture
import net.corda.core.internal.div
import net.corda.core.internal.list
import net.corda.core.internal.readLines
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.NodeStartup
import net.corda.testing.DUMMY_BANK_A
@ -10,13 +12,13 @@ import net.corda.testing.DUMMY_REGULATOR
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import net.corda.testing.internal.addressMustBeBound
import net.corda.testing.internal.addressMustNotBeBound
import net.corda.testing.internal.internalDriver
import net.corda.testing.node.NotarySpec
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
class DriverTests {
companion object {
private val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(2)
@ -33,7 +35,6 @@ class DriverTests {
addressMustNotBeBound(executorService, hostAndPort)
}
}
private val portAllocation = PortAllocation.Incremental(10000)
@Test
fun `simple node startup and shutdown`() {
@ -46,14 +47,13 @@ class DriverTests {
@Test
fun `random free port allocation`() {
val nodeHandle = driver(portAllocation = portAllocation) {
val nodeHandle = driver(portAllocation = PortAllocation.RandomFree) {
val nodeInfo = startNode(providedName = DUMMY_BANK_A.name)
nodeMustBeUp(nodeInfo)
}
nodeMustBeDown(nodeHandle)
}
@Test
fun `debug mode enables debug logging level`() {
// Make sure we're using the log4j2 config which writes to the log file

View File

@ -16,13 +16,13 @@ import net.corda.node.services.config.VerifierType
import net.corda.nodeapi.internal.config.User
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.internal.DriverDSLImpl
import net.corda.testing.internal.genericDriver
import net.corda.testing.internal.getTimestampAsDirectoryName
import net.corda.testing.node.NotarySpec
import java.net.InetSocketAddress
import java.net.ServerSocket
import java.net.URL
import java.nio.file.Path
import java.nio.file.Paths
import java.security.cert.X509Certificate
import java.util.concurrent.atomic.AtomicInteger
/**
@ -136,7 +136,7 @@ data class NodeParameters(
* (...)
* }
*
* Note that [DriverDSLImpl.startNode] does not wait for the node to start up synchronously, but rather returns a [CordaFuture]
* Note that [DriverDSL.startNode] does not wait for the node to start up synchronously, but rather returns a [CordaFuture]
* of the [NodeInfo] that may be waited on, which completes when the new node registered with the network map service or
* loaded node data from database.
*
@ -145,7 +145,7 @@ data class NodeParameters(
* @param isDebug Indicates whether the spawned nodes should start in jdwt debug mode and have debug level logging.
* @param driverDirectory The base directory node directories go into, defaults to "build/<timestamp>/". The node
* directories themselves are "<baseDirectory>/<legalName>/", where legalName defaults to "<randomName>-<messagingPort>"
* and may be specified in [DriverDSLImpl.startNode].
* and may be specified in [DriverDSL.startNode].
* @param portAllocation The port allocation strategy to use for the messaging and the web server addresses. Defaults to incremental.
* @param debugPortAllocation The port allocation strategy to use for jvm debugging. Defaults to incremental.
* @param systemProperties A Map of extra system properties which will be given to each new node. Defaults to empty.
@ -192,50 +192,6 @@ fun <A> driver(
)
}
// TODO Move CompatibilityZoneParams and internalDriver into internal package
/**
* @property url The base CZ URL for registration and network map updates
* @property rootCert If specified then the node will register itself using [url] and expect the registration response
* to be rooted at this cert.
*/
data class CompatibilityZoneParams(val url: URL, val rootCert: X509Certificate? = null)
fun <A> internalDriver(
isDebug: Boolean = DriverParameters().isDebug,
driverDirectory: Path = DriverParameters().driverDirectory,
portAllocation: PortAllocation = DriverParameters().portAllocation,
debugPortAllocation: PortAllocation = DriverParameters().debugPortAllocation,
systemProperties: Map<String, String> = DriverParameters().systemProperties,
useTestClock: Boolean = DriverParameters().useTestClock,
initialiseSerialization: Boolean = DriverParameters().initialiseSerialization,
startNodesInProcess: Boolean = DriverParameters().startNodesInProcess,
waitForAllNodesToFinish: Boolean = DriverParameters().waitForNodesToFinish,
notarySpecs: List<NotarySpec> = DriverParameters().notarySpecs,
extraCordappPackagesToScan: List<String> = DriverParameters().extraCordappPackagesToScan,
compatibilityZone: CompatibilityZoneParams? = null,
dsl: DriverDSLImpl.() -> A
): A {
return genericDriver(
driverDsl = DriverDSLImpl(
portAllocation = portAllocation,
debugPortAllocation = debugPortAllocation,
systemProperties = systemProperties,
driverDirectory = driverDirectory.toAbsolutePath(),
useTestClock = useTestClock,
isDebug = isDebug,
startNodesInProcess = startNodesInProcess,
waitForNodesToFinish = waitForAllNodesToFinish,
notarySpecs = notarySpecs,
extraCordappPackagesToScan = extraCordappPackagesToScan,
compatibilityZone = compatibilityZone
),
coerce = { it },
dsl = dsl,
initialiseSerialization = initialiseSerialization
)
}
/**
* Helper function for starting a [driver] with custom parameters from Java.
*

View File

@ -64,11 +64,9 @@ interface DriverDSL {
verifierType: VerifierType = defaultParameters.verifierType,
customOverrides: Map<String, Any?> = defaultParameters.customOverrides,
startInSameProcess: Boolean? = defaultParameters.startInSameProcess,
maximumHeapSize: String = defaultParameters.maximumHeapSize
): CordaFuture<NodeHandle>
/**
* Helper function for starting a [Node] with custom parameters from Java.
*

View File

@ -94,8 +94,7 @@ class DriverDSLImpl(
// TODO: this object will copy NodeInfo files from started nodes to other nodes additional-node-infos/
// This uses the FileSystem and adds a delay (~5 seconds) given by the time we wait before polling the file system.
// Investigate whether we can avoid that.
// TODO: NodeInfoFilesCopier create observable threads in the init method, we should move that to a start method instead, changing this to lateinit instead to prevent that.
private lateinit var nodeInfoFilesCopier: NodeInfoFilesCopier
private var nodeInfoFilesCopier: NodeInfoFilesCopier? = null
// Map from a nodes legal name to an observable emitting the number of nodes in its network map.
private val countObservables = mutableMapOf<CordaX500Name, Observable<Int>>()
private lateinit var _notaries: List<NotaryHandle>
@ -327,7 +326,12 @@ class DriverDSLImpl(
}
_executorService = Executors.newScheduledThreadPool(2, ThreadFactoryBuilder().setNameFormat("driver-pool-thread-%d").build())
_shutdownManager = ShutdownManager(executorService)
shutdownManager.registerShutdown { nodeInfoFilesCopier.close() }
if (compatibilityZone == null) {
// Without a compatibility zone URL we have to copy the node info files ourselves to make sure the nodes see each other
nodeInfoFilesCopier = NodeInfoFilesCopier().also {
shutdownManager.registerShutdown(it::close)
}
}
val notaryInfos = generateNotaryIdentities()
// The network parameters must be serialised before starting any of the nodes
networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos))
@ -493,10 +497,6 @@ class DriverDSLImpl(
maximumHeapSize: String): CordaFuture<NodeHandle> {
val configuration = config.parseAsNodeConfiguration()
val baseDirectory = configuration.baseDirectory.createDirectories()
// Distribute node info file using file copier when network map service URL (compatibilityZoneURL) is null.
// TODO: need to implement the same in cordformation?
val nodeInfoFilesCopier = if (compatibilityZone == null) nodeInfoFilesCopier else null
nodeInfoFilesCopier?.addConfig(baseDirectory)
networkParameters!!.install(baseDirectory)
val onNodeExit: () -> Unit = {
@ -625,13 +625,19 @@ class DriverDSLImpl(
// Write node.conf
writeConfig(nodeConf.baseDirectory, "node.conf", config)
val systemProperties = overriddenSystemProperties + mapOf(
val systemProperties = mutableMapOf(
"name" to nodeConf.myLegalName,
"visualvm.display.name" to "corda-${nodeConf.myLegalName}",
Node.scanPackagesSystemProperty to cordappPackages.joinToString(Node.scanPackagesSeparator),
"java.io.tmpdir" to System.getProperty("java.io.tmpdir"), // Inherit from parent process
"log4j2.debug" to if(debugPort != null) "true" else "false"
)
if (cordappPackages.isNotEmpty()) {
systemProperties += Node.scanPackagesSystemProperty to cordappPackages.joinToString(Node.scanPackagesSeparator)
}
systemProperties += overriddenSystemProperties
// See experimental/quasar-hook/README.md for how to generate.
val excludePattern = "x(antlr**;bftsmart**;ch**;co.paralleluniverse**;com.codahale**;com.esotericsoftware**;" +
"com.fasterxml**;com.google**;com.ibm**;com.intellij**;com.jcabi**;com.nhaarman**;com.opengamma**;" +
@ -805,7 +811,8 @@ fun <DI : DriverDSL, D : InternalDriverDSL, A> genericDriver(
startNodesInProcess = startNodesInProcess,
waitForNodesToFinish = waitForNodesToFinish,
extraCordappPackagesToScan = extraCordappPackagesToScan,
notarySpecs = notarySpecs
notarySpecs = notarySpecs,
compatibilityZone = null
)
)
val shutdownHook = addShutdownHook(driverDsl::shutdown)
@ -822,6 +829,48 @@ fun <DI : DriverDSL, D : InternalDriverDSL, A> genericDriver(
}
}
/**
* @property url The base CZ URL for registration and network map updates
* @property rootCert If specified then the node will register itself using [url] and expect the registration response
* to be rooted at this cert.
*/
data class CompatibilityZoneParams(val url: URL, val rootCert: X509Certificate? = null)
fun <A> internalDriver(
isDebug: Boolean = DriverParameters().isDebug,
driverDirectory: Path = DriverParameters().driverDirectory,
portAllocation: PortAllocation = DriverParameters().portAllocation,
debugPortAllocation: PortAllocation = DriverParameters().debugPortAllocation,
systemProperties: Map<String, String> = DriverParameters().systemProperties,
useTestClock: Boolean = DriverParameters().useTestClock,
initialiseSerialization: Boolean = DriverParameters().initialiseSerialization,
startNodesInProcess: Boolean = DriverParameters().startNodesInProcess,
waitForAllNodesToFinish: Boolean = DriverParameters().waitForAllNodesToFinish,
notarySpecs: List<NotarySpec> = DriverParameters().notarySpecs,
extraCordappPackagesToScan: List<String> = DriverParameters().extraCordappPackagesToScan,
compatibilityZone: CompatibilityZoneParams? = null,
dsl: DriverDSLImpl.() -> A
): A {
return genericDriver(
driverDsl = DriverDSLImpl(
portAllocation = portAllocation,
debugPortAllocation = debugPortAllocation,
systemProperties = systemProperties,
driverDirectory = driverDirectory.toAbsolutePath(),
useTestClock = useTestClock,
isDebug = isDebug,
startNodesInProcess = startNodesInProcess,
waitForNodesToFinish = waitForAllNodesToFinish,
notarySpecs = notarySpecs,
extraCordappPackagesToScan = extraCordappPackagesToScan,
compatibilityZone = compatibilityZone
),
coerce = { it },
dsl = dsl,
initialiseSerialization = initialiseSerialization
)
}
fun getTimestampAsDirectoryName(): String {
return DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC).format(Instant.now())
}

View File

@ -10,7 +10,9 @@ import net.corda.core.context.Trace
import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.internal.concurrent.fork
import net.corda.core.internal.concurrent.map
import net.corda.core.internal.div
import net.corda.core.internal.uncheckedCast
import net.corda.core.messaging.RPCOps
import net.corda.core.utilities.NetworkHostAndPort

View File

@ -5,8 +5,9 @@ package net.corda.testing.internal.demorun
import net.corda.cordform.CordformDefinition
import net.corda.cordform.CordformNode
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.getOrThrow
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.internalDriver
import net.corda.testing.internal.internalDriver
fun CordformDefinition.clean() {
System.err.println("Deleting: $nodesDirectory")

View File

@ -46,7 +46,7 @@ class NetworkMapServer(cacheTimeout: Duration,
private fun networkMapKeyAndCert(rootCAKeyAndCert: CertificateAndKeyPair): CertificateAndKeyPair {
val networkMapKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val networkMapCert = X509Utilities.createCertificate(
CertificateType.IDENTITY,
CertificateType.INTERMEDIATE_CA,
rootCAKeyAndCert.certificate,
rootCAKeyAndCert.keyPair,
X500Name("CN=Corda Network Map,L=London"),

View File

@ -7,7 +7,10 @@ import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.concurrent.OpenFuture
import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.internal.concurrent.fork
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.createDirectories
import net.corda.core.internal.div
import net.corda.core.serialization.internal.nodeSerializationEnv
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.utilities.NetworkHostAndPort
@ -22,9 +25,7 @@ import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.internal.DriverDSLImpl
import net.corda.testing.internal.ProcessUtilities
import net.corda.testing.internal.poll
import net.corda.testing.internal.*
import net.corda.testing.node.NotarySpec
import org.apache.activemq.artemis.api.core.SimpleString
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
@ -180,7 +181,6 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri
val securityManager = object : ActiveMQSecurityManager {
// We don't need auth, SSL is good enough
override fun validateUser(user: String?, password: String?) = true
override fun validateUserAndRole(user: String?, password: String?, roles: MutableSet<Role>?, checkType: CheckType?) = true
}