mirror of
https://github.com/corda/corda.git
synced 2024-12-19 04:57:58 +00:00
Merge pull request #1231 from corda/feature/vkolomeyko/os-merge
OS->Ent merge
This commit is contained in:
commit
13af5e00b6
@ -54,7 +54,7 @@ class FlowsExecutionModeRpcTest : IntegrationTest() {
|
|||||||
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win"))
|
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win"))
|
||||||
|
|
||||||
val user = User("mark", "dadada", setOf(invokeRpc("setFlowsDrainingModeEnabled"), invokeRpc("isFlowsDrainingModeEnabled")))
|
val user = User("mark", "dadada", setOf(invokeRpc("setFlowsDrainingModeEnabled"), invokeRpc("isFlowsDrainingModeEnabled")))
|
||||||
driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = true)) {
|
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = true)) {
|
||||||
val nodeName = {
|
val nodeName = {
|
||||||
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
||||||
val nodeName = nodeHandle.nodeInfo.chooseIdentity().name
|
val nodeName = nodeHandle.nodeInfo.chooseIdentity().name
|
||||||
|
@ -13,13 +13,10 @@ package net.corda.core.identity
|
|||||||
import com.google.common.collect.ImmutableSet
|
import com.google.common.collect.ImmutableSet
|
||||||
import net.corda.core.KeepForDJVM
|
import net.corda.core.KeepForDJVM
|
||||||
import net.corda.core.internal.LegalNameValidator
|
import net.corda.core.internal.LegalNameValidator
|
||||||
|
import net.corda.core.internal.toAttributesMap
|
||||||
import net.corda.core.internal.unspecifiedCountry
|
import net.corda.core.internal.unspecifiedCountry
|
||||||
import net.corda.core.internal.x500Name
|
import net.corda.core.internal.toX500Name
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import org.bouncycastle.asn1.ASN1Encodable
|
|
||||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
|
||||||
import org.bouncycastle.asn1.x500.AttributeTypeAndValue
|
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
import org.bouncycastle.asn1.x500.style.BCStyle
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
@ -96,29 +93,13 @@ data class CordaX500Name(val commonName: String?,
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun build(principal: X500Principal): CordaX500Name {
|
fun build(principal: X500Principal): CordaX500Name {
|
||||||
val x500Name = X500Name.getInstance(principal.encoded)
|
val attrsMap = principal.toAttributesMap(supportedAttributes)
|
||||||
val attrsMap: Map<ASN1ObjectIdentifier, ASN1Encodable> = x500Name.rdNs
|
|
||||||
.flatMap { it.typesAndValues.asList() }
|
|
||||||
.groupBy(AttributeTypeAndValue::getType, AttributeTypeAndValue::getValue)
|
|
||||||
.mapValues {
|
|
||||||
require(it.value.size == 1) { "Duplicate attribute ${it.key}" }
|
|
||||||
it.value[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Supported attribute checks.
|
|
||||||
(attrsMap.keys - supportedAttributes).let { unsupported ->
|
|
||||||
require(unsupported.isEmpty()) {
|
|
||||||
"The following attribute${if (unsupported.size > 1) "s are" else " is"} not supported in Corda: " +
|
|
||||||
unsupported.map { BCStyle.INSTANCE.oidToDisplayName(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val CN = attrsMap[BCStyle.CN]?.toString()
|
val CN = attrsMap[BCStyle.CN]?.toString()
|
||||||
val OU = attrsMap[BCStyle.OU]?.toString()
|
val OU = attrsMap[BCStyle.OU]?.toString()
|
||||||
val O = attrsMap[BCStyle.O]?.toString() ?: throw IllegalArgumentException("Corda X.500 names must include an O attribute")
|
val O = requireNotNull(attrsMap[BCStyle.O]?.toString()) { "Corda X.500 names must include an O attribute" }
|
||||||
val L = attrsMap[BCStyle.L]?.toString() ?: throw IllegalArgumentException("Corda X.500 names must include an L attribute")
|
val L = requireNotNull(attrsMap[BCStyle.L]?.toString()) { "Corda X.500 names must include an L attribute" }
|
||||||
val ST = attrsMap[BCStyle.ST]?.toString()
|
val ST = attrsMap[BCStyle.ST]?.toString()
|
||||||
val C = attrsMap[BCStyle.C]?.toString() ?: throw IllegalArgumentException("Corda X.500 names must include an C attribute")
|
val C = requireNotNull(attrsMap[BCStyle.C]?.toString()) { "Corda X.500 names must include an C attribute" }
|
||||||
return CordaX500Name(CN, OU, O, L, ST, C)
|
return CordaX500Name(CN, OU, O, L, ST, C)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +113,7 @@ data class CordaX500Name(val commonName: String?,
|
|||||||
/** Return the [X500Principal] equivalent of this name. */
|
/** Return the [X500Principal] equivalent of this name. */
|
||||||
val x500Principal: X500Principal
|
val x500Principal: X500Principal
|
||||||
get() {
|
get() {
|
||||||
return _x500Principal ?: X500Principal(this.x500Name.encoded).also { _x500Principal = it }
|
return _x500Principal ?: X500Principal(this.toX500Name().encoded).also { _x500Principal = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = x500Principal.toString()
|
override fun toString(): String = x500Principal.toString()
|
||||||
|
@ -21,7 +21,6 @@ import net.corda.core.cordapp.CordappConfig
|
|||||||
import net.corda.core.cordapp.CordappContext
|
import net.corda.core.cordapp.CordappContext
|
||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.*
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.identity.CordaX500Name
|
|
||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.serialization.*
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.transactions.LedgerTransaction
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
@ -30,9 +29,6 @@ import net.corda.core.transactions.TransactionBuilder
|
|||||||
import net.corda.core.transactions.WireTransaction
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.UntrustworthyData
|
import net.corda.core.utilities.UntrustworthyData
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
|
||||||
import org.bouncycastle.asn1.x500.X500NameBuilder
|
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.MDC
|
import org.slf4j.MDC
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -487,27 +483,6 @@ $trustAnchor""", e, this, e.index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the underlying X.500 name from this Corda-safe X.500 name. These are guaranteed to have a consistent
|
|
||||||
* ordering, such that their `toString()` function returns the same value every time for the same [CordaX500Name].
|
|
||||||
*/
|
|
||||||
val CordaX500Name.x500Name: X500Name
|
|
||||||
get() {
|
|
||||||
return X500NameBuilder(BCStyle.INSTANCE).apply {
|
|
||||||
addRDN(BCStyle.C, country)
|
|
||||||
state?.let { addRDN(BCStyle.ST, it) }
|
|
||||||
addRDN(BCStyle.L, locality)
|
|
||||||
addRDN(BCStyle.O, organisation)
|
|
||||||
organisationUnit?.let { addRDN(BCStyle.OU, it) }
|
|
||||||
commonName?.let { addRDN(BCStyle.CN, it) }
|
|
||||||
}.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
@VisibleForTesting
|
|
||||||
val CordaX500Name.Companion.unspecifiedCountry
|
|
||||||
get() = "ZZ"
|
|
||||||
|
|
||||||
inline fun <T : Any> T.signWithCert(signer: (SerializedBytes<T>) -> DigitalSignatureWithCert): SignedDataWithCert<T> {
|
inline fun <T : Any> T.signWithCert(signer: (SerializedBytes<T>) -> DigitalSignatureWithCert): SignedDataWithCert<T> {
|
||||||
val serialised = serialize()
|
val serialised = serialize()
|
||||||
return SignedDataWithCert(serialised, signer(serialised))
|
return SignedDataWithCert(serialised, signer(serialised))
|
||||||
|
73
core/src/main/kotlin/net/corda/core/internal/X500Utils.kt
Normal file
73
core/src/main/kotlin/net/corda/core/internal/X500Utils.kt
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
@file:KeepForDJVM
|
||||||
|
|
||||||
|
package net.corda.core.internal
|
||||||
|
|
||||||
|
import net.corda.core.KeepForDJVM
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import org.bouncycastle.asn1.ASN1Encodable
|
||||||
|
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
||||||
|
import org.bouncycastle.asn1.x500.AttributeTypeAndValue
|
||||||
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
|
import org.bouncycastle.asn1.x500.X500NameBuilder
|
||||||
|
import org.bouncycastle.asn1.x500.style.BCStyle
|
||||||
|
import javax.security.auth.x500.X500Principal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the underlying X.500 name from this Corda-safe X.500 name. These are guaranteed to have a consistent
|
||||||
|
* ordering, such that their `toString()` function returns the same value every time for the same [CordaX500Name].
|
||||||
|
*/
|
||||||
|
fun CordaX500Name.toX500Name(): X500Name {
|
||||||
|
return X500NameBuilder(BCStyle.INSTANCE).apply {
|
||||||
|
addRDN(BCStyle.C, country)
|
||||||
|
state?.let { addRDN(BCStyle.ST, it) }
|
||||||
|
addRDN(BCStyle.L, locality)
|
||||||
|
addRDN(BCStyle.O, organisation)
|
||||||
|
organisationUnit?.let { addRDN(BCStyle.OU, it) }
|
||||||
|
commonName?.let { addRDN(BCStyle.CN, it) }
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the X500Principal instance to the X500Name object.
|
||||||
|
*/
|
||||||
|
fun X500Principal.toX500Name(): X500Name = X500Name.getInstance(this.encoded)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the X500Principal to the attributes map.
|
||||||
|
*
|
||||||
|
* @param supportedAttributes list of supported attributes. If empty, it accepts all the attributes.
|
||||||
|
*
|
||||||
|
* @return attributes map for this principal
|
||||||
|
* @throws IllegalArgumentException if this principal consists of duplicated attributes or the attribute is not supported.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
fun X500Principal.toAttributesMap(supportedAttributes: Set<ASN1ObjectIdentifier> = emptySet()): Map<ASN1ObjectIdentifier, ASN1Encodable> {
|
||||||
|
val x500Name = this.toX500Name()
|
||||||
|
val attrsMap: Map<ASN1ObjectIdentifier, ASN1Encodable> = x500Name.rdNs
|
||||||
|
.flatMap { it.typesAndValues.asList() }
|
||||||
|
.groupBy(AttributeTypeAndValue::getType, AttributeTypeAndValue::getValue)
|
||||||
|
.mapValues {
|
||||||
|
require(it.value.size == 1) { "Duplicate attribute ${it.key}" }
|
||||||
|
it.value[0]
|
||||||
|
}
|
||||||
|
if (supportedAttributes.isNotEmpty()) {
|
||||||
|
(attrsMap.keys - supportedAttributes).let { unsupported ->
|
||||||
|
require(unsupported.isEmpty()) {
|
||||||
|
"The following attribute${if (unsupported.size > 1) "s are" else " is"} not supported in Corda: " +
|
||||||
|
unsupported.map { BCStyle.INSTANCE.oidToDisplayName(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attrsMap
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks equality between the two X500Principal instances ignoring the ordering of the X500Name parts.
|
||||||
|
*/
|
||||||
|
fun X500Principal.isEquivalentTo(other: X500Principal): Boolean {
|
||||||
|
return toAttributesMap() == other.toAttributesMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
val CordaX500Name.Companion.unspecifiedCountry
|
||||||
|
get() = "ZZ"
|
@ -0,0 +1,26 @@
|
|||||||
|
package net.corda.core.identity
|
||||||
|
|
||||||
|
import net.corda.core.internal.isEquivalentTo
|
||||||
|
import org.junit.Test
|
||||||
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class X500UtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `X500Principal equalX500NameParts matches regardless the order`() {
|
||||||
|
// given
|
||||||
|
val orderingA = "O=Bank A, OU=Organisation Unit, L=New York, C=US"
|
||||||
|
val orderingB = "OU=Organisation Unit, O=Bank A, L=New York, C=US"
|
||||||
|
val orderingC = "L=New York, O=Bank A, C=US, OU=Organisation Unit"
|
||||||
|
|
||||||
|
// when
|
||||||
|
val principalA = X500Principal(orderingA)
|
||||||
|
val principalB = X500Principal(orderingB)
|
||||||
|
val principalC = X500Principal(orderingC)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertTrue { principalA.isEquivalentTo(principalB) }
|
||||||
|
assertTrue { principalB.isEquivalentTo(principalC) }
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
Network Map
|
Network map
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
The network map is a collection of signed ``NodeInfo`` objects. Each NodeInfo is signed by the node it represents and
|
The network map is a collection of signed ``NodeInfo`` objects. Each NodeInfo is signed by the node it represents and
|
||||||
thus cannot be tampered with. It forms the set of reachable nodes in a compatibility zone. A node can receive these
|
thus cannot be tampered with. It forms the set of reachable nodes in a compatibility zone. A node can receive these
|
||||||
objects from two sources:
|
objects from two sources:
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
Setting up a Corda network
|
Setting up a Corda network
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
A Corda network consists of a number of machines running nodes. These nodes communicate using persistent protocols in
|
A Corda network consists of a number of machines running nodes. These nodes communicate using persistent protocols in
|
||||||
order to create and validate transactions.
|
order to create and validate transactions.
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import net.corda.core.crypto.Crypto
|
|||||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
import net.corda.core.internal.x500Name
|
import net.corda.core.internal.toX500Name
|
||||||
import net.corda.nodeapi.internal.config.SSLConfiguration
|
import net.corda.nodeapi.internal.config.SSLConfiguration
|
||||||
import net.corda.nodeapi.internal.crypto.*
|
import net.corda.nodeapi.internal.crypto.*
|
||||||
import org.bouncycastle.asn1.x509.GeneralName
|
import org.bouncycastle.asn1.x509.GeneralName
|
||||||
@ -93,7 +93,7 @@ fun createDevNetworkMapCa(rootCa: CertificateAndKeyPair = DEV_ROOT_CA): Certific
|
|||||||
fun createDevNodeCa(intermediateCa: CertificateAndKeyPair,
|
fun createDevNodeCa(intermediateCa: CertificateAndKeyPair,
|
||||||
legalName: CordaX500Name,
|
legalName: CordaX500Name,
|
||||||
nodeKeyPair: KeyPair = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)): CertificateAndKeyPair {
|
nodeKeyPair: KeyPair = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)): CertificateAndKeyPair {
|
||||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.x500Name))), arrayOf())
|
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.toX500Name()))), arrayOf())
|
||||||
val cert = X509Utilities.createCertificate(
|
val cert = X509Utilities.createCertificate(
|
||||||
CertificateType.NODE_CA,
|
CertificateType.NODE_CA,
|
||||||
intermediateCa.certificate,
|
intermediateCa.certificate,
|
||||||
|
@ -73,7 +73,7 @@ class BootTests : IntegrationTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `double node start doesn't write into log file`() {
|
fun `double node start doesn't write into log file`() {
|
||||||
driver(DriverParameters(isDebug = true)) {
|
driver {
|
||||||
val alice = startNode(providedName = ALICE_NAME).get()
|
val alice = startNode(providedName = ALICE_NAME).get()
|
||||||
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
|
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
|
||||||
val logFile = logFolder.list { it.filter { it.fileName.toString().endsWith(".log") }.findAny().get() }
|
val logFile = logFolder.list { it.filter { it.fileName.toString().endsWith(".log") }.findAny().get() }
|
||||||
|
@ -38,7 +38,7 @@ class NodeUnloadHandlerTests : IntegrationTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `should be able to register run on stop lambda`() {
|
fun `should be able to register run on stop lambda`() {
|
||||||
driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.node"), isDebug = true)) {
|
driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.node"))) {
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME).getOrThrow()
|
startNode(providedName = DUMMY_BANK_A_NAME).getOrThrow()
|
||||||
// just want to fall off the end of this for the mo...
|
// just want to fall off the end of this for the mo...
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class FlowRetryTest : IntegrationTest() {
|
|||||||
val numSessions = 2
|
val numSessions = 2
|
||||||
val numIterations = 10
|
val numIterations = 10
|
||||||
val user = User("mark", "dadada", setOf(Permissions.startFlow<InitiatorFlow>()))
|
val user = User("mark", "dadada", setOf(Permissions.startFlow<InitiatorFlow>()))
|
||||||
val result: Any? = driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(),
|
val result: Any? = driver(DriverParameters(startNodesInProcess = isQuasarAgentSpecified(),
|
||||||
portAllocation = RandomFree)) {
|
portAllocation = RandomFree)) {
|
||||||
|
|
||||||
val nodeAHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).getOrThrow()
|
val nodeAHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).getOrThrow()
|
||||||
|
@ -67,7 +67,7 @@ class FlowsDrainingModeContentionTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `draining mode does not deadlock with acks between 2 nodes`() {
|
fun `draining mode does not deadlock with acks between 2 nodes`() {
|
||||||
val message = "Ground control to Major Tom"
|
val message = "Ground control to Major Tom"
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = portAllocation, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = portAllocation, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
|
||||||
val nodeA = startNode(providedName = ALICE_NAME, rpcUsers = users).getOrThrow()
|
val nodeA = startNode(providedName = ALICE_NAME, rpcUsers = users).getOrThrow()
|
||||||
val nodeB = startNode(providedName = BOB_NAME, rpcUsers = users).getOrThrow()
|
val nodeB = startNode(providedName = BOB_NAME, rpcUsers = users).getOrThrow()
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ class P2PFlowsDrainingModeTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `flows draining mode suspends consumption of initial session messages`() {
|
fun `flows draining mode suspends consumption of initial session messages`() {
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = false, portAllocation = portAllocation)) {
|
driver(DriverParameters(startNodesInProcess = false, portAllocation = portAllocation)) {
|
||||||
|
|
||||||
val initiatedNode = startNode(providedName = ALICE_NAME).getOrThrow()
|
val initiatedNode = startNode(providedName = ALICE_NAME).getOrThrow()
|
||||||
val initiating = startNode(providedName = BOB_NAME, rpcUsers = users).getOrThrow().rpc
|
val initiating = startNode(providedName = BOB_NAME, rpcUsers = users).getOrThrow().rpc
|
||||||
@ -101,7 +101,7 @@ class P2PFlowsDrainingModeTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `clean shutdown by draining`() {
|
fun `clean shutdown by draining`() {
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = portAllocation)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = portAllocation)) {
|
||||||
|
|
||||||
val nodeA = startNode(providedName = ALICE_NAME, rpcUsers = users).getOrThrow()
|
val nodeA = startNode(providedName = ALICE_NAME, rpcUsers = users).getOrThrow()
|
||||||
val nodeB = startNode(providedName = BOB_NAME, rpcUsers = users).getOrThrow()
|
val nodeB = startNode(providedName = BOB_NAME, rpcUsers = users).getOrThrow()
|
||||||
|
@ -45,7 +45,7 @@ class RpcFlowsDrainingModeTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `flows draining mode rejects start flows commands through rpc`() {
|
fun `flows draining mode rejects start flows commands through rpc`() {
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = false, portAllocation = portAllocation)) {
|
driver(DriverParameters(startNodesInProcess = false, portAllocation = portAllocation)) {
|
||||||
|
|
||||||
startNode(rpcUsers = users).getOrThrow().rpc.apply {
|
startNode(rpcUsers = users).getOrThrow().rpc.apply {
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class NodeStatePersistenceTests : IntegrationTest() {
|
|||||||
fun `persistent state survives node restart`() {
|
fun `persistent state survives node restart`() {
|
||||||
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
|
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
|
||||||
val message = Message("Hello world!")
|
val message = Message("Hello world!")
|
||||||
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(),
|
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(),
|
||||||
portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
|
portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
|
||||||
val nodeName = {
|
val nodeName = {
|
||||||
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
||||||
@ -90,7 +90,7 @@ class NodeStatePersistenceTests : IntegrationTest() {
|
|||||||
|
|
||||||
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
|
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
|
||||||
val message = Message("Hello world!")
|
val message = Message("Hello world!")
|
||||||
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
|
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
|
||||||
val nodeName = {
|
val nodeName = {
|
||||||
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
||||||
val nodeName = nodeHandle.nodeInfo.singleIdentity().name
|
val nodeName = nodeHandle.nodeInfo.singleIdentity().name
|
||||||
|
@ -70,7 +70,7 @@ class RpcSslTest : IntegrationTest() {
|
|||||||
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert)
|
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert)
|
||||||
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
val node = startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow()
|
val node = startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow()
|
||||||
val client = CordaRPCClient.createWithSsl(node.rpcAddress, sslConfiguration = clientSslOptions)
|
val client = CordaRPCClient.createWithSsl(node.rpcAddress, sslConfiguration = clientSslOptions)
|
||||||
val connection = client.start(user.username, user.password)
|
val connection = client.start(user.username, user.password)
|
||||||
@ -108,7 +108,7 @@ class RpcSslTest : IntegrationTest() {
|
|||||||
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert1)
|
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert1)
|
||||||
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
val node = startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow()
|
val node = startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow()
|
||||||
Assertions.assertThatThrownBy {
|
Assertions.assertThatThrownBy {
|
||||||
val connection = CordaRPCClient.createWithSsl(node.rpcAddress, sslConfiguration = clientSslOptions).start(user.username, user.password)
|
val connection = CordaRPCClient.createWithSsl(node.rpcAddress, sslConfiguration = clientSslOptions).start(user.username, user.password)
|
||||||
@ -128,7 +128,7 @@ class RpcSslTest : IntegrationTest() {
|
|||||||
fun `RPC client not using ssl can run commands`() {
|
fun `RPC client not using ssl can run commands`() {
|
||||||
val user = User("mark", "dadada", setOf(all()))
|
val user = User("mark", "dadada", setOf(all()))
|
||||||
var successful = false
|
var successful = false
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
val node = startNode(rpcUsers = listOf(user)).getOrThrow()
|
val node = startNode(rpcUsers = listOf(user)).getOrThrow()
|
||||||
val connection = CordaRPCClient(node.rpcAddress).start(user.username, user.password)
|
val connection = CordaRPCClient(node.rpcAddress).start(user.username, user.password)
|
||||||
connection.proxy.apply {
|
connection.proxy.apply {
|
||||||
@ -148,7 +148,7 @@ class RpcSslTest : IntegrationTest() {
|
|||||||
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert)
|
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert)
|
||||||
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
val node = startNode(customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow()
|
val node = startNode(customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow()
|
||||||
val client = CordaRPCClient.createWithSsl(node.rpcAddress, sslConfiguration = clientSslOptions)
|
val client = CordaRPCClient.createWithSsl(node.rpcAddress, sslConfiguration = clientSslOptions)
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class HardRestartTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun restartShortPingPongFlowRandomly() {
|
fun restartShortPingPongFlowRandomly() {
|
||||||
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
|
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
||||||
val (a, b) = listOf(
|
val (a, b) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
||||||
@ -102,7 +102,7 @@ class HardRestartTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun restartLongPingPongFlowRandomly() {
|
fun restartLongPingPongFlowRandomly() {
|
||||||
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
|
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
||||||
val (a, b) = listOf(
|
val (a, b) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
||||||
@ -134,7 +134,7 @@ class HardRestartTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun softRestartLongPingPongFlowRandomly() {
|
fun softRestartLongPingPongFlowRandomly() {
|
||||||
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
|
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
||||||
val (a, b) = listOf(
|
val (a, b) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
||||||
@ -210,7 +210,7 @@ class HardRestartTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun restartRecursiveFlowRandomly() {
|
fun restartRecursiveFlowRandomly() {
|
||||||
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<RecursiveA>(), Permissions.all()))
|
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<RecursiveA>(), Permissions.all()))
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
|
||||||
val (a, b) = listOf(
|
val (a, b) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
|
||||||
|
@ -15,7 +15,7 @@ import net.corda.core.identity.CordaX500Name
|
|||||||
import net.corda.core.internal.copyTo
|
import net.corda.core.internal.copyTo
|
||||||
import net.corda.core.internal.createDirectories
|
import net.corda.core.internal.createDirectories
|
||||||
import net.corda.core.internal.exists
|
import net.corda.core.internal.exists
|
||||||
import net.corda.core.internal.x500Name
|
import net.corda.core.internal.toX500Name
|
||||||
import net.corda.nodeapi.RPCApi
|
import net.corda.nodeapi.RPCApi
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.NODE_P2P_USER
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.NODE_P2P_USER
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.PEER_USER
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.PEER_USER
|
||||||
@ -109,7 +109,7 @@ class MQSecurityAsNodeTest : P2PMQSecurityTest() {
|
|||||||
|
|
||||||
val clientKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
val clientKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||||
// Set name constrain to the legal name.
|
// Set name constrain to the legal name.
|
||||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.x500Name))), arrayOf())
|
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.toX500Name()))), arrayOf())
|
||||||
val clientCACert = X509Utilities.createCertificate(
|
val clientCACert = X509Utilities.createCertificate(
|
||||||
CertificateType.INTERMEDIATE_CA,
|
CertificateType.INTERMEDIATE_CA,
|
||||||
DEV_INTERMEDIATE_CA.certificate,
|
DEV_INTERMEDIATE_CA.certificate,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import com.typesafe.config.*;
|
import com.typesafe.config.*;
|
||||||
import sun.misc.Signal;
|
import sun.misc.Signal;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@ -53,7 +54,7 @@ public class CordaCaplet extends Capsule {
|
|||||||
Config nodeConfig = ConfigFactory.parseFile(configFile, parseOptions);
|
Config nodeConfig = ConfigFactory.parseFile(configFile, parseOptions);
|
||||||
return baseDirectoryConfig.withFallback(nodeConfig).withFallback(defaultConfig).resolve();
|
return baseDirectoryConfig.withFallback(nodeConfig).withFallback(defaultConfig).resolve();
|
||||||
} catch (ConfigException e) {
|
} catch (ConfigException e) {
|
||||||
log(LOG_QUIET, e);
|
log(LOG_DEBUG, e);
|
||||||
return ConfigFactory.empty();
|
return ConfigFactory.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,19 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
|
|||||||
private val logger = contextLogger()
|
private val logger = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class Error(message: String) : Exception(message) {
|
||||||
|
class ParamsNotConfigured : Error("Couldn't find network parameters file and compatibility zone wasn't configured/isn't reachable.")
|
||||||
|
class NetworkMapNotConfigured : Error("Node hasn't been configured to connect to a network map from which to get the network parameters.")
|
||||||
|
class OldParamsAndUpdate : Error(
|
||||||
|
"Both network parameters and network parameters update files don't match" +
|
||||||
|
"parameters advertised by network map. Please update node to use correct network parameters file."
|
||||||
|
)
|
||||||
|
class OldParams(previousParametersHash: SecureHash, advertisedParametersHash: SecureHash) : Error(
|
||||||
|
"Node uses parameters with hash: $previousParametersHash but network map is advertising: " +
|
||||||
|
"$advertisedParametersHash. Please update node to use correct network parameters file."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private data class NetworkParamsAndHash(val networkParameters: NetworkParameters, val hash: SecureHash)
|
private data class NetworkParamsAndHash(val networkParameters: NetworkParameters, val hash: SecureHash)
|
||||||
private val networkParamsFile = baseDirectory / NETWORK_PARAMS_FILE_NAME
|
private val networkParamsFile = baseDirectory / NETWORK_PARAMS_FILE_NAME
|
||||||
private val parametersUpdateFile = baseDirectory / NETWORK_PARAMS_UPDATE_FILE_NAME
|
private val parametersUpdateFile = baseDirectory / NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||||
@ -63,7 +76,7 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
|
|||||||
readParametersUpdate(advertisedParametersHash, signedParametersFromFile.raw.hash)
|
readParametersUpdate(advertisedParametersHash, signedParametersFromFile.raw.hash)
|
||||||
}
|
}
|
||||||
} else { // No compatibility zone configured. Node should proceed with parameters from file.
|
} else { // No compatibility zone configured. Node should proceed with parameters from file.
|
||||||
signedParametersFromFile ?: throw IllegalArgumentException("Couldn't find network parameters file and compatibility zone wasn't configured/isn't reachable")
|
signedParametersFromFile ?: throw Error.ParamsNotConfigured()
|
||||||
}
|
}
|
||||||
logger.info("Loaded network parameters: $parameters")
|
logger.info("Loaded network parameters: $parameters")
|
||||||
return NetworkParamsAndHash(parameters.verifiedNetworkMapCert(trustRoot), parameters.raw.hash)
|
return NetworkParamsAndHash(parameters.verifiedNetworkMapCert(trustRoot), parameters.raw.hash)
|
||||||
@ -71,15 +84,11 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
|
|||||||
|
|
||||||
private fun readParametersUpdate(advertisedParametersHash: SecureHash, previousParametersHash: SecureHash): SignedNetworkParameters {
|
private fun readParametersUpdate(advertisedParametersHash: SecureHash, previousParametersHash: SecureHash): SignedNetworkParameters {
|
||||||
if (!parametersUpdateFile.exists()) {
|
if (!parametersUpdateFile.exists()) {
|
||||||
throw IllegalArgumentException("Node uses parameters with hash: $previousParametersHash " +
|
throw Error.OldParams(previousParametersHash, advertisedParametersHash)
|
||||||
"but network map is advertising: $advertisedParametersHash.\n" +
|
|
||||||
"Please update node to use correct network parameters file.")
|
|
||||||
}
|
}
|
||||||
val signedUpdatedParameters = parametersUpdateFile.readObject<SignedNetworkParameters>()
|
val signedUpdatedParameters = parametersUpdateFile.readObject<SignedNetworkParameters>()
|
||||||
if (signedUpdatedParameters.raw.hash != advertisedParametersHash) {
|
if (signedUpdatedParameters.raw.hash != advertisedParametersHash) {
|
||||||
throw IllegalArgumentException("Both network parameters and network parameters update files don't match" +
|
throw Error.OldParamsAndUpdate()
|
||||||
"parameters advertised by network map.\n" +
|
|
||||||
"Please update node to use correct network parameters file.")
|
|
||||||
}
|
}
|
||||||
parametersUpdateFile.moveTo(networkParamsFile, StandardCopyOption.REPLACE_EXISTING)
|
parametersUpdateFile.moveTo(networkParamsFile, StandardCopyOption.REPLACE_EXISTING)
|
||||||
logger.info("Scheduled update to network parameters has occurred - node now updated to these new parameters.")
|
logger.info("Scheduled update to network parameters has occurred - node now updated to these new parameters.")
|
||||||
@ -89,9 +98,7 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
|
|||||||
// Used only when node joins for the first time.
|
// Used only when node joins for the first time.
|
||||||
private fun downloadParameters(parametersHash: SecureHash): SignedNetworkParameters {
|
private fun downloadParameters(parametersHash: SecureHash): SignedNetworkParameters {
|
||||||
logger.info("No network-parameters file found. Expecting network parameters to be available from the network map.")
|
logger.info("No network-parameters file found. Expecting network parameters to be available from the network map.")
|
||||||
val networkMapClient = checkNotNull(networkMapClient) {
|
val networkMapClient = networkMapClient ?: throw Error.NetworkMapNotConfigured()
|
||||||
"Node hasn't been configured to connect to a network map from which to get the network parameters"
|
|
||||||
}
|
|
||||||
val signedParams = networkMapClient.getNetworkParameters(parametersHash)
|
val signedParams = networkMapClient.getNetworkParameters(parametersHash)
|
||||||
signedParams.serialize().open().copyTo(baseDirectory / NETWORK_PARAMS_FILE_NAME)
|
signedParams.serialize().open().copyTo(baseDirectory / NETWORK_PARAMS_FILE_NAME)
|
||||||
return signedParams
|
return signedParams
|
||||||
|
@ -21,12 +21,7 @@ import net.corda.core.internal.*
|
|||||||
import net.corda.core.internal.concurrent.thenMatch
|
import net.corda.core.internal.concurrent.thenMatch
|
||||||
import net.corda.core.utilities.Try
|
import net.corda.core.utilities.Try
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.CmdLineOptions
|
import net.corda.node.*
|
||||||
import net.corda.node.NodeArgsParser
|
|
||||||
import net.corda.node.NodeRegistrationOption
|
|
||||||
import net.corda.node.SerialFilter
|
|
||||||
import net.corda.node.VersionInfo
|
|
||||||
import net.corda.node.defaultSerialFilter
|
|
||||||
import net.corda.node.internal.cordapp.MultipleCordappsForFlowException
|
import net.corda.node.internal.cordapp.MultipleCordappsForFlowException
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
import net.corda.node.services.config.NodeConfigurationImpl
|
import net.corda.node.services.config.NodeConfigurationImpl
|
||||||
@ -36,9 +31,9 @@ import net.corda.node.services.transactions.bftSMaRtSerialFilter
|
|||||||
import net.corda.node.utilities.createKeyPairAndSelfSignedTLSCertificate
|
import net.corda.node.utilities.createKeyPairAndSelfSignedTLSCertificate
|
||||||
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
|
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
|
||||||
import net.corda.node.utilities.registration.NodeRegistrationHelper
|
import net.corda.node.utilities.registration.NodeRegistrationHelper
|
||||||
|
import net.corda.node.utilities.registration.UnableToRegisterNodeWithDoormanException
|
||||||
import net.corda.node.utilities.saveToKeyStore
|
import net.corda.node.utilities.saveToKeyStore
|
||||||
import net.corda.node.utilities.saveToTrustStore
|
import net.corda.node.utilities.saveToTrustStore
|
||||||
import net.corda.node.utilities.registration.UnableToRegisterNodeWithDoormanException
|
|
||||||
import net.corda.nodeapi.internal.addShutdownHook
|
import net.corda.nodeapi.internal.addShutdownHook
|
||||||
import net.corda.nodeapi.internal.config.UnknownConfigurationKeysException
|
import net.corda.nodeapi.internal.config.UnknownConfigurationKeysException
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseMigrationException
|
import net.corda.nodeapi.internal.persistence.DatabaseMigrationException
|
||||||
@ -171,6 +166,9 @@ open class NodeStartup(val args: Array<String>) {
|
|||||||
} catch (e: CheckpointIncompatibleException) {
|
} catch (e: CheckpointIncompatibleException) {
|
||||||
logger.error(e.message)
|
logger.error(e.message)
|
||||||
return false
|
return false
|
||||||
|
} catch (e: NetworkParametersReader.Error) {
|
||||||
|
logger.error(e.message)
|
||||||
|
return false
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (e is Errors.NativeIoException && e.message?.contains("Address already in use") == true) {
|
if (e is Errors.NativeIoException && e.message?.contains("Address already in use") == true) {
|
||||||
logger.error("One of the ports required by the Corda node is already in use.")
|
logger.error("One of the ports required by the Corda node is already in use.")
|
||||||
|
@ -35,6 +35,7 @@ import java.security.PublicKey
|
|||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import javax.naming.ServiceUnavailableException
|
import javax.naming.ServiceUnavailableException
|
||||||
|
import javax.security.auth.x500.X500Principal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for managing the node registration process, which checks for any existing certificates and requests them if
|
* Helper for managing the node registration process, which checks for any existing certificates and requests them if
|
||||||
@ -53,13 +54,14 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration,
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val SELF_SIGNED_PRIVATE_KEY = "Self Signed Private Key"
|
const val SELF_SIGNED_PRIVATE_KEY = "Self Signed Private Key"
|
||||||
|
val logger = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val requestIdStore = config.certificatesDirectory / "certificate-request-id.txt"
|
private val requestIdStore = config.certificatesDirectory / "certificate-request-id.txt"
|
||||||
// TODO: Use different password for private key.
|
// TODO: Use different password for private key.
|
||||||
private val privateKeyPassword = config.keyStorePassword
|
private val privateKeyPassword = config.keyStorePassword
|
||||||
private val rootTrustStore: X509KeyStore
|
private val rootTrustStore: X509KeyStore
|
||||||
private val rootCert: X509Certificate
|
protected val rootCert: X509Certificate
|
||||||
|
|
||||||
init {
|
init {
|
||||||
require(networkRootTrustStorePath.exists()) {
|
require(networkRootTrustStorePath.exists()) {
|
||||||
@ -88,6 +90,13 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration,
|
|||||||
println("Certificate already exists, Corda node will now terminate...")
|
println("Certificate already exists, Corda node will now terminate...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
val tlsCrlIssuerCert = validateAndGetTlsCrlIssuerCert()
|
||||||
|
if (tlsCrlIssuerCert == null && isTlsCrlIssuerCertRequired()) {
|
||||||
|
System.err.println("""tlsCrlIssuerCert config does not match the root certificate issuer and nor is there any other certificate in the trust store with a matching issuer.
|
||||||
|
| Please make sure the config is correct or that the correct certificate for the CRL issuer is added to the node's trust store.
|
||||||
|
| The node will now terminate.""".trimMargin())
|
||||||
|
throw IllegalArgumentException("TLS CRL issuer certificate not found in the trust store.")
|
||||||
|
}
|
||||||
|
|
||||||
val keyPair = nodeKeyStore.loadOrCreateKeyPair(SELF_SIGNED_PRIVATE_KEY)
|
val keyPair = nodeKeyStore.loadOrCreateKeyPair(SELF_SIGNED_PRIVATE_KEY)
|
||||||
|
|
||||||
@ -104,7 +113,7 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration,
|
|||||||
}
|
}
|
||||||
validateCertificates(keyPair.public, certificates)
|
validateCertificates(keyPair.public, certificates)
|
||||||
storePrivateKeyWithCertificates(nodeKeyStore, keyPair, certificates, keyAlias)
|
storePrivateKeyWithCertificates(nodeKeyStore, keyPair, certificates, keyAlias)
|
||||||
onSuccess(keyPair, certificates)
|
onSuccess(keyPair, certificates, tlsCrlIssuerCert?.let { it.subjectX500Principal.toX500Name() })
|
||||||
// All done, clean up temp files.
|
// All done, clean up temp files.
|
||||||
requestIdStore.deleteIfExists()
|
requestIdStore.deleteIfExists()
|
||||||
}
|
}
|
||||||
@ -226,7 +235,11 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun onSuccess(nodeCAKeyPair: KeyPair, certificates: List<X509Certificate>) {}
|
protected open fun onSuccess(nodeCAKeyPair: KeyPair, certificates: List<X509Certificate>, tlsCrlCertificateIssuer: X500Name?) {}
|
||||||
|
|
||||||
|
protected open fun validateAndGetTlsCrlIssuerCert(): X509Certificate? = null
|
||||||
|
|
||||||
|
protected open fun isTlsCrlIssuerCertRequired(): Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnableToRegisterNodeWithDoormanException : IOException()
|
class UnableToRegisterNodeWithDoormanException : IOException()
|
||||||
@ -246,12 +259,12 @@ class NodeRegistrationHelper(private val config: NodeConfiguration, certService:
|
|||||||
val logger = contextLogger()
|
val logger = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(nodeCAKeyPair: KeyPair, certificates: List<X509Certificate>) {
|
override fun onSuccess(nodeCAKeyPair: KeyPair, certificates: List<X509Certificate>, tlsCrlCertificateIssuer: X500Name?) {
|
||||||
createSSLKeystore(nodeCAKeyPair, certificates)
|
createSSLKeystore(nodeCAKeyPair, certificates, tlsCrlCertificateIssuer)
|
||||||
createTruststore(certificates.last())
|
createTruststore(certificates.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSSLKeystore(nodeCAKeyPair: KeyPair, certificates: List<X509Certificate>) {
|
private fun createSSLKeystore(nodeCAKeyPair: KeyPair, certificates: List<X509Certificate>, tlsCertCrlIssuer: X500Name?) {
|
||||||
config.loadSslKeyStore(createNew = true).update {
|
config.loadSslKeyStore(createNew = true).update {
|
||||||
println("Generating SSL certificate for node messaging service.")
|
println("Generating SSL certificate for node messaging service.")
|
||||||
val sslKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
val sslKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||||
@ -262,7 +275,7 @@ class NodeRegistrationHelper(private val config: NodeConfiguration, certService:
|
|||||||
config.myLegalName.x500Principal,
|
config.myLegalName.x500Principal,
|
||||||
sslKeyPair.public,
|
sslKeyPair.public,
|
||||||
crlDistPoint = config.tlsCertCrlDistPoint?.toString(),
|
crlDistPoint = config.tlsCertCrlDistPoint?.toString(),
|
||||||
crlIssuer = if (config.tlsCertCrlIssuer != null) X500Name(config.tlsCertCrlIssuer) else null)
|
crlIssuer = tlsCertCrlIssuer)
|
||||||
logger.info("Generated TLS certificate: $sslCert")
|
logger.info("Generated TLS certificate: $sslCert")
|
||||||
setPrivateKey(CORDA_CLIENT_TLS, sslKeyPair.private, listOf(sslCert) + certificates)
|
setPrivateKey(CORDA_CLIENT_TLS, sslKeyPair.private, listOf(sslCert) + certificates)
|
||||||
}
|
}
|
||||||
@ -278,6 +291,37 @@ class NodeRegistrationHelper(private val config: NodeConfiguration, certService:
|
|||||||
}
|
}
|
||||||
println("Node trust store stored in ${config.trustStoreFile}.")
|
println("Node trust store stored in ${config.trustStoreFile}.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun validateAndGetTlsCrlIssuerCert(): X509Certificate? {
|
||||||
|
config.tlsCertCrlIssuer ?: return null
|
||||||
|
val tlsCertCrlIssuerPrincipal = X500Principal(config.tlsCertCrlIssuer)
|
||||||
|
if (principalMatchesCertificatePrincipal(tlsCertCrlIssuerPrincipal, rootCert)) {
|
||||||
|
return rootCert
|
||||||
|
}
|
||||||
|
return if (config.trustStoreFile.exists()) {
|
||||||
|
findMatchingCertificate(tlsCertCrlIssuerPrincipal, config.loadTrustStore())
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isTlsCrlIssuerCertRequired(): Boolean {
|
||||||
|
return !config.tlsCertCrlIssuer.isNullOrEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findMatchingCertificate(principal: X500Principal, trustStore: X509KeyStore): X509Certificate? {
|
||||||
|
trustStore.aliases().forEach {
|
||||||
|
val certificate = trustStore.getCertificate(it)
|
||||||
|
if (principalMatchesCertificatePrincipal(principal, certificate)) {
|
||||||
|
return certificate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun principalMatchesCertificatePrincipal(principal: X500Principal, certificate: X509Certificate): Boolean {
|
||||||
|
return certificate.subjectX500Principal.isEquivalentTo(principal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FixedPeriodLimitedRetrialStrategy(times: Int, private val period: Duration) : (Duration?) -> Duration? {
|
private class FixedPeriodLimitedRetrialStrategy(times: Int, private val period: Duration) : (Duration?) -> Duration? {
|
||||||
|
@ -22,10 +22,9 @@ import net.corda.core.identity.CordaX500Name
|
|||||||
import net.corda.core.internal.CertRole
|
import net.corda.core.internal.CertRole
|
||||||
import net.corda.core.internal.createDirectories
|
import net.corda.core.internal.createDirectories
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.internal.x500Name
|
import net.corda.core.internal.toX500Name
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.node.NodeRegistrationOption
|
import net.corda.node.NodeRegistrationOption
|
||||||
import net.corda.node.VersionInfo
|
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
import net.corda.nodeapi.internal.DevIdentityGenerator
|
import net.corda.nodeapi.internal.DevIdentityGenerator
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||||
@ -71,6 +70,7 @@ class NetworkRegistrationHelperTest {
|
|||||||
doReturn("").whenever(it).emailAddress
|
doReturn("").whenever(it).emailAddress
|
||||||
doReturn(null).whenever(it).tlsCertCrlDistPoint
|
doReturn(null).whenever(it).tlsCertCrlDistPoint
|
||||||
doReturn(null).whenever(it).tlsCertCrlIssuer
|
doReturn(null).whenever(it).tlsCertCrlIssuer
|
||||||
|
doReturn(true).whenever(it).crlCheckSoftFail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ class NetworkRegistrationHelperTest {
|
|||||||
rootAndIntermediateCA: Pair<CertificateAndKeyPair, CertificateAndKeyPair> = createDevIntermediateCaCertPath()): List<X509Certificate> {
|
rootAndIntermediateCA: Pair<CertificateAndKeyPair, CertificateAndKeyPair> = createDevIntermediateCaCertPath()): List<X509Certificate> {
|
||||||
val (rootCa, intermediateCa) = rootAndIntermediateCA
|
val (rootCa, intermediateCa) = rootAndIntermediateCA
|
||||||
val nameConstraints = if (type == CertificateType.NODE_CA) {
|
val nameConstraints = if (type == CertificateType.NODE_CA) {
|
||||||
NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.x500Name))), arrayOf())
|
NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.toX500Name()))), arrayOf())
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class AttachmentDemoTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `attachment demo using a 10MB zip file`() {
|
fun `attachment demo using a 10MB zip file`() {
|
||||||
val numOfExpectedBytes = 10_000_000
|
val numOfExpectedBytes = 10_000_000
|
||||||
driver(DriverParameters(isDebug = true, portAllocation = PortAllocation.Incremental(20000), startNodesInProcess = true)) {
|
driver(DriverParameters(portAllocation = PortAllocation.Incremental(20000), startNodesInProcess = true)) {
|
||||||
val demoUser = listOf(User("demo", "demo", setOf(all())))
|
val demoUser = listOf(User("demo", "demo", setOf(all())))
|
||||||
val (nodeA, nodeB) = listOf(
|
val (nodeA, nodeB) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"),
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"),
|
||||||
|
@ -23,7 +23,7 @@ import net.corda.testing.node.User
|
|||||||
*/
|
*/
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
|
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
|
||||||
driver(DriverParameters(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes", waitForAllNodesToFinish = true)) {
|
driver(DriverParameters(driverDirectory = "build" / "attachment-demo-nodes", waitForAllNodesToFinish = true)) {
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser)
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser)
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = demoUser)
|
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = demoUser)
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class BankOfCordaRPCClientTest : IntegrationTest() {
|
|||||||
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
|
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
|
||||||
invokeRpc(CordaRPCOps::notaryIdentities)
|
invokeRpc(CordaRPCOps::notaryIdentities)
|
||||||
)
|
)
|
||||||
driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"), isDebug = true)) {
|
driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"))) {
|
||||||
val bocManager = User("bocManager", "password1", permissions = setOf(
|
val bocManager = User("bocManager", "password1", permissions = setOf(
|
||||||
startFlow<CashIssueAndPaymentFlow>()) + commonPermissions)
|
startFlow<CashIssueAndPaymentFlow>()) + commonPermissions)
|
||||||
val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet<String>() + commonPermissions)
|
val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet<String>() + commonPermissions)
|
||||||
|
@ -22,7 +22,7 @@ import net.corda.testing.driver.driver
|
|||||||
* Do not use in a production environment.
|
* Do not use in a production environment.
|
||||||
*/
|
*/
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
driver(DriverParameters(useTestClock = true, isDebug = true, waitForAllNodesToFinish = true)) {
|
driver(DriverParameters(useTestClock = true, waitForAllNodesToFinish = true)) {
|
||||||
val (nodeA, nodeB) = listOf(
|
val (nodeA, nodeB) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME),
|
startNode(providedName = DUMMY_BANK_A_NAME),
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME),
|
startNode(providedName = DUMMY_BANK_B_NAME),
|
||||||
|
@ -72,7 +72,6 @@ class IRSDemoTest : IntegrationTest() {
|
|||||||
springDriver(DriverParameters(
|
springDriver(DriverParameters(
|
||||||
useTestClock = true,
|
useTestClock = true,
|
||||||
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = rpcUsers)),
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = rpcUsers)),
|
||||||
isDebug = true,
|
|
||||||
extraCordappPackagesToScan = listOf("net.corda.irs")
|
extraCordappPackagesToScan = listOf("net.corda.irs")
|
||||||
)) {
|
)) {
|
||||||
val (controller, nodeA, nodeB) = listOf(
|
val (controller, nodeA, nodeB) = listOf(
|
||||||
|
@ -69,7 +69,6 @@ class SimmValuationTest : IntegrationTest() {
|
|||||||
val logConfigFile = projectRootDir / "samples" / "simm-valuation-demo" / "src" / "main" / "resources" / "log4j2.xml"
|
val logConfigFile = projectRootDir / "samples" / "simm-valuation-demo" / "src" / "main" / "resources" / "log4j2.xml"
|
||||||
assertThat(logConfigFile).isRegularFile()
|
assertThat(logConfigFile).isRegularFile()
|
||||||
driver(DriverParameters(
|
driver(DriverParameters(
|
||||||
isDebug = true,
|
|
||||||
extraCordappPackagesToScan = listOf("net.corda.vega.contracts", "net.corda.vega.plugin.customserializers"),
|
extraCordappPackagesToScan = listOf("net.corda.vega.contracts", "net.corda.vega.plugin.customserializers"),
|
||||||
systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))
|
systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))
|
||||||
) {
|
) {
|
||||||
|
@ -23,7 +23,7 @@ import net.corda.testing.driver.driver
|
|||||||
* via the web api.
|
* via the web api.
|
||||||
*/
|
*/
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
driver(DriverParameters(isDebug = true, waitForAllNodesToFinish = true)) {
|
driver(DriverParameters(waitForAllNodesToFinish = true)) {
|
||||||
val (nodeA, nodeB, nodeC) = listOf(
|
val (nodeA, nodeB, nodeC) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME),
|
startNode(providedName = DUMMY_BANK_A_NAME),
|
||||||
startNode(providedName = DUMMY_BANK_B_NAME),
|
startNode(providedName = DUMMY_BANK_B_NAME),
|
||||||
|
@ -96,7 +96,7 @@ class TraderDemoTest : IntegrationTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Tudor test`() {
|
fun `Tudor test`() {
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) {
|
driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) {
|
||||||
val demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all()))
|
val demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all()))
|
||||||
val bankUser = User("user1", "test", permissions = setOf(all()))
|
val bankUser = User("user1", "test", permissions = setOf(all()))
|
||||||
val (nodeA, nodeB, bankNode) = listOf(
|
val (nodeA, nodeB, bankNode) = listOf(
|
||||||
|
@ -33,7 +33,7 @@ fun main(args: Array<String>) {
|
|||||||
startFlow<SellerFlow>(),
|
startFlow<SellerFlow>(),
|
||||||
all())
|
all())
|
||||||
val demoUser = listOf(User("demo", "demo", permissions))
|
val demoUser = listOf(User("demo", "demo", permissions))
|
||||||
driver(DriverParameters(driverDirectory = "build" / "trader-demo-nodes", isDebug = true, waitForAllNodesToFinish = true)) {
|
driver(DriverParameters(driverDirectory = "build" / "trader-demo-nodes", waitForAllNodesToFinish = true)) {
|
||||||
val user = User("user1", "test", permissions = setOf(startFlow<CashIssueFlow>(),
|
val user = User("user1", "test", permissions = setOf(startFlow<CashIssueFlow>(),
|
||||||
startFlow<CommercialPaperIssueFlow>(),
|
startFlow<CommercialPaperIssueFlow>(),
|
||||||
startFlow<SellerFlow>()))
|
startFlow<SellerFlow>()))
|
||||||
|
@ -67,7 +67,6 @@ class CordformNodeRunner(val cordformDefinition: CordformDefinition) {
|
|||||||
.mapNotNull { address -> address?.let { NetworkHostAndPort.parse(it).port } }
|
.mapNotNull { address -> address?.let { NetworkHostAndPort.parse(it).port } }
|
||||||
.max()!!
|
.max()!!
|
||||||
internalDriver(
|
internalDriver(
|
||||||
isDebug = true,
|
|
||||||
jmxPolicy = JmxPolicy(true),
|
jmxPolicy = JmxPolicy(true),
|
||||||
driverDirectory = cordformDefinition.nodesDirectory,
|
driverDirectory = cordformDefinition.nodesDirectory,
|
||||||
extraCordappPackagesToScan = extraPackagesToScan,
|
extraCordappPackagesToScan = extraPackagesToScan,
|
||||||
|
@ -67,7 +67,7 @@ class InteractiveShellIntegrationTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `shell should not log in with invalid credentials`() {
|
fun `shell should not log in with invalid credentials`() {
|
||||||
val user = User("u", "p", setOf())
|
val user = User("u", "p", setOf())
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
val nodeFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user), startInSameProcess = true)
|
val nodeFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user), startInSameProcess = true)
|
||||||
val node = nodeFuture.getOrThrow()
|
val node = nodeFuture.getOrThrow()
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ class InteractiveShellIntegrationTest : IntegrationTest() {
|
|||||||
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert)
|
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert)
|
||||||
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow().use { node ->
|
startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow().use { node ->
|
||||||
|
|
||||||
val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(),
|
val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(),
|
||||||
@ -136,7 +136,7 @@ class InteractiveShellIntegrationTest : IntegrationTest() {
|
|||||||
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert1)
|
val trustStorePath = saveToTrustStore(tempFolder.root.toPath() / "truststore.jks", cert1)
|
||||||
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
||||||
|
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow().use { node ->
|
startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow().use { node ->
|
||||||
|
|
||||||
val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(),
|
val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(),
|
||||||
@ -153,7 +153,7 @@ class InteractiveShellIntegrationTest : IntegrationTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `internal shell user should not be able to connect if node started with devMode=false`() {
|
fun `internal shell user should not be able to connect if node started with devMode=false`() {
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
startNode().getOrThrow().use { node ->
|
startNode().getOrThrow().use { node ->
|
||||||
val conf = (node as NodeHandleInternal).configuration.toShellConfig()
|
val conf = (node as NodeHandleInternal).configuration.toShellConfig()
|
||||||
InteractiveShell.startShellInternal(conf)
|
InteractiveShell.startShellInternal(conf)
|
||||||
@ -219,7 +219,7 @@ class InteractiveShellIntegrationTest : IntegrationTest() {
|
|||||||
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
val clientSslOptions = ClientRpcSslOptions(trustStorePath, "password")
|
||||||
|
|
||||||
var successful = false
|
var successful = false
|
||||||
driver(DriverParameters(isDebug = true, startNodesInProcess = true, portAllocation = RandomFree)) {
|
driver(DriverParameters(startNodesInProcess = true, portAllocation = RandomFree)) {
|
||||||
startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow().use { node ->
|
startNode(rpcUsers = listOf(user), customOverrides = brokerSslOptions.useSslRpcOverrides()).getOrThrow().use { node ->
|
||||||
|
|
||||||
val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(),
|
val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(),
|
||||||
|
@ -117,7 +117,7 @@ class SSHServerTest : IntegrationTest() {
|
|||||||
val user = User("u", "p", setOf(startFlow<FlowICanRun>(),
|
val user = User("u", "p", setOf(startFlow<FlowICanRun>(),
|
||||||
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name)))
|
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name)))
|
||||||
// The driver will automatically pick up the annotated flows below
|
// The driver will automatically pick up the annotated flows below
|
||||||
driver(DriverParameters(isDebug = true)) {
|
driver {
|
||||||
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user),
|
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user),
|
||||||
customOverrides = mapOf("sshd" to mapOf("port" to 2222)))
|
customOverrides = mapOf("sshd" to mapOf("port" to 2222)))
|
||||||
node.getOrThrow()
|
node.getOrThrow()
|
||||||
@ -146,7 +146,7 @@ class SSHServerTest : IntegrationTest() {
|
|||||||
fun `ssh runs flows`() {
|
fun `ssh runs flows`() {
|
||||||
val user = User("u", "p", setOf(startFlow<FlowICanRun>()))
|
val user = User("u", "p", setOf(startFlow<FlowICanRun>()))
|
||||||
// The driver will automatically pick up the annotated flows below
|
// The driver will automatically pick up the annotated flows below
|
||||||
driver(DriverParameters(isDebug = true)) {
|
driver {
|
||||||
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user),
|
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user),
|
||||||
customOverrides = mapOf("sshd" to mapOf("port" to 2222)))
|
customOverrides = mapOf("sshd" to mapOf("port" to 2222)))
|
||||||
node.getOrThrow()
|
node.getOrThrow()
|
||||||
|
Loading…
Reference in New Issue
Block a user