diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 43a1d65c41..1b1637872f 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -54,6 +54,12 @@
+
+
+
+
+
+
@@ -93,6 +99,7 @@
+
@@ -170,6 +177,8 @@
+
+
diff --git a/bridge/bridgecapsule/src/smoke-test/kotlin/net/corda/bridge/smoketest/BridgeSmokeTest.kt b/bridge/bridgecapsule/src/smoke-test/kotlin/net/corda/bridge/smoketest/BridgeSmokeTest.kt
index e327e26490..3648f0cd33 100644
--- a/bridge/bridgecapsule/src/smoke-test/kotlin/net/corda/bridge/smoketest/BridgeSmokeTest.kt
+++ b/bridge/bridgecapsule/src/smoke-test/kotlin/net/corda/bridge/smoketest/BridgeSmokeTest.kt
@@ -7,12 +7,10 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.*
import net.corda.core.node.NetworkParameters
import net.corda.core.node.NotaryInfo
-import net.corda.core.node.services.AttachmentId
import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.serialize
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger
-import net.corda.node.services.config.CertChainPolicyConfig
import net.corda.node.services.config.EnterpriseConfiguration
import net.corda.node.services.config.MutualExclusionConfiguration
import net.corda.node.services.config.NodeConfiguration
@@ -102,7 +100,7 @@ class BridgeSmokeTest {
bridgeJar.copyToDirectory(testDir)
}
- fun createNetworkParams(baseDirectory: Path) {
+ private fun createNetworkParams(baseDirectory: Path) {
val dummyNotaryParty = TestIdentity(DUMMY_NOTARY_NAME)
val notaryInfo = NotaryInfo(dummyNotaryParty.party, false)
val copier = NetworkParametersCopier(NetworkParameters(
@@ -112,18 +110,18 @@ class BridgeSmokeTest {
maxMessageSize = 10485760,
maxTransactionSize = 40000,
epoch = 1,
- whitelistedContractImplementations = emptyMap>()
+ whitelistedContractImplementations = emptyMap()
), overwriteFile = true)
copier.install(baseDirectory)
}
- fun SSLConfiguration.createBridgeKeyStores(legalName: CordaX500Name,
- rootCert: X509Certificate = DEV_ROOT_CA.certificate,
- intermediateCa: CertificateAndKeyPair = DEV_INTERMEDIATE_CA) {
+ private fun SSLConfiguration.createBridgeKeyStores(legalName: CordaX500Name,
+ rootCert: X509Certificate = DEV_ROOT_CA.certificate,
+ intermediateCa: CertificateAndKeyPair = DEV_INTERMEDIATE_CA) {
certificatesDirectory.createDirectories()
if (!trustStoreFile.exists()) {
- loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/${DEV_CA_TRUST_STORE_FILE}"), DEV_CA_TRUST_STORE_PASS).save(trustStoreFile, trustStorePassword)
+ loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/$DEV_CA_TRUST_STORE_FILE"), DEV_CA_TRUST_STORE_PASS).save(trustStoreFile, trustStorePassword)
}
val (nodeCaCert, nodeCaKeyPair) = createDevNodeCa(intermediateCa, legalName)
@@ -189,13 +187,13 @@ class BridgeSmokeTest {
}
}
- fun serverListening(host: String, port: Int): Boolean {
+ private fun serverListening(host: String, port: Int): Boolean {
var s: Socket? = null
- try {
+ return try {
s = Socket(host, port)
- return true
+ true
} catch (e: Exception) {
- return false
+ false
} finally {
try {
s?.close()
@@ -212,7 +210,6 @@ class BridgeSmokeTest {
doReturn("cordacadevpass").whenever(it).keyStorePassword
doReturn(NetworkHostAndPort("localhost", 11005)).whenever(it).p2pAddress
doReturn(null).whenever(it).jmxMonitoringHttpPort
- doReturn(emptyList()).whenever(it).certificateChainCheckPolicies
doReturn(EnterpriseConfiguration(MutualExclusionConfiguration(false, "", 20000, 40000), externalBridge = true)).whenever(it).enterpriseConfiguration
}
val artemisServer = ArtemisMessagingServer(artemisConfig, NetworkHostAndPort("0.0.0.0", 11005), MAX_MESSAGE_SIZE)
diff --git a/bridge/src/integration-test/kotlin/net/corda/bridge/services/ArtemisConnectionTest.kt b/bridge/src/integration-test/kotlin/net/corda/bridge/services/ArtemisConnectionTest.kt
index f6f462f4a0..bf844b1b9a 100644
--- a/bridge/src/integration-test/kotlin/net/corda/bridge/services/ArtemisConnectionTest.kt
+++ b/bridge/src/integration-test/kotlin/net/corda/bridge/services/ArtemisConnectionTest.kt
@@ -17,7 +17,6 @@ import net.corda.bridge.createBridgeKeyStores
import net.corda.bridge.createNetworkParams
import net.corda.bridge.services.artemis.BridgeArtemisConnectionServiceImpl
import net.corda.core.utilities.NetworkHostAndPort
-import net.corda.node.services.config.CertChainPolicyConfig
import net.corda.node.services.config.EnterpriseConfiguration
import net.corda.node.services.config.MutualExclusionConfiguration
import net.corda.node.services.config.NodeConfiguration
@@ -102,7 +101,6 @@ class ArtemisConnectionTest {
doReturn("cordacadevpass").whenever(it).keyStorePassword
doReturn(NetworkHostAndPort("localhost", 11005)).whenever(it).p2pAddress
doReturn(null).whenever(it).jmxMonitoringHttpPort
- doReturn(emptyList()).whenever(it).certificateChainCheckPolicies
doReturn(EnterpriseConfiguration(MutualExclusionConfiguration(false, "", 20000, 40000), externalBridge = true)).whenever(it).enterpriseConfiguration
}
val artemisServer = ArtemisMessagingServer(artemisConfig, NetworkHostAndPort("0.0.0.0", 11005), MAX_MESSAGE_SIZE)
diff --git a/build.gradle b/build.gradle
index 42f9185c35..b853040c16 100644
--- a/build.gradle
+++ b/build.gradle
@@ -188,6 +188,7 @@ allprojects {
jvmTarget = "1.8"
javaParameters = true // Useful for reflection.
freeCompilerArgs = ['-Xjvm-default=compatibility']
+ allWarningsAsErrors = true
}
}
diff --git a/buildSrc/jarfilter/kotlin-metadata/build.gradle b/buildSrc/jarfilter/kotlin-metadata/build.gradle
index b509187551..561cea19a1 100644
--- a/buildSrc/jarfilter/kotlin-metadata/build.gradle
+++ b/buildSrc/jarfilter/kotlin-metadata/build.gradle
@@ -39,7 +39,6 @@ task metadata(type: ProGuardTask) {
keepattributes '*'
dontoptimize
- printseeds
verbose
dontwarn 'com.sun.jna.**'
@@ -47,6 +46,7 @@ task metadata(type: ProGuardTask) {
dontwarn 'org.jetbrains.kotlin.com.intellij.**'
dontwarn 'org.jetbrains.kotlin.com.google.j2objc.annotations.**'
dontwarn 'org.jetbrains.kotlin.com.google.errorprone.annotations.**'
+ dontnote
keep 'class org.jetbrains.kotlin.load.java.JvmAnnotationNames { *; }'
keep 'class org.jetbrains.kotlin.metadata.** { *; }', includedescriptorclasses: true
@@ -68,6 +68,7 @@ task validate(type: ProGuardTask) {
verbose
dontwarn 'org.jetbrains.kotlin.com.google.errorprone.annotations.**'
+ dontnote
keep 'class *'
}
@@ -77,5 +78,4 @@ artifacts {
}
defaultTasks "metadata"
-assemble.dependsOn metadata
metadata.finalizedBy validate
diff --git a/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt b/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt
index 420be1a61a..29e237df2c 100644
--- a/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt
+++ b/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt
@@ -401,6 +401,11 @@ class JacksonSupportTest(@Suppress("unused") private val name: String, factory:
testToStringSerialisation(UUID.randomUUID())
}
+ @Test
+ fun Instant() {
+ testToStringSerialisation(Instant.now())
+ }
+
@Test
fun `Date is treated as Instant`() {
val date = Date()
diff --git a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt
index 7a772e4022..e0a2bb2ba5 100644
--- a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt
+++ b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt
@@ -13,7 +13,6 @@ package net.corda.client.jfx
import net.corda.client.jfx.model.NodeMonitorModel
import net.corda.client.jfx.model.ProgressTrackingEvent
import net.corda.core.context.InvocationOrigin
-import net.corda.core.contracts.Amount
import net.corda.core.contracts.ContractState
import net.corda.core.crypto.isFulfilledBy
import net.corda.core.crypto.keys
@@ -32,12 +31,9 @@ import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
-import net.corda.finance.USD
-import net.corda.finance.flows.CashExitFlow
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
-import net.corda.node.services.Permissions.Companion.invokeRpc
-import net.corda.node.services.Permissions.Companion.startFlow
+import net.corda.node.services.Permissions.Companion.all
import net.corda.testing.core.*
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
@@ -75,18 +71,7 @@ class NodeMonitorModelTest : IntegrationTest() {
private fun setup(runTest: () -> Unit) {
driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"))) {
- val cashUser = User("user1", "test", permissions = setOf(
- startFlow(),
- startFlow(),
- startFlow(),
- invokeRpc(CordaRPCOps::notaryIdentities),
- invokeRpc("vaultTrackBy"),
- invokeRpc("vaultQueryBy"),
- invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed),
- invokeRpc(CordaRPCOps::stateMachineRecordedTransactionMappingFeed),
- invokeRpc(CordaRPCOps::stateMachinesFeed),
- invokeRpc(CordaRPCOps::networkMapFeed))
- )
+ val cashUser = User("user1", "test", permissions = setOf(all()))
val aliceNodeHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(cashUser)).getOrThrow()
aliceNode = aliceNodeHandle.nodeInfo
newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
@@ -135,11 +120,7 @@ class NodeMonitorModelTest : IntegrationTest() {
@Test
fun `cash issue works end to end`() = setup {
- rpc.startFlow(::CashIssueFlow,
- Amount(100, USD),
- OpaqueBytes(ByteArray(1, { 1 })),
- notaryParty
- )
+ rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryParty)
vaultUpdates.expectEvents(isStrict = false) {
sequence(
diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt
index 555af2e2f8..e79a718658 100644
--- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt
+++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt
@@ -111,12 +111,12 @@ class NodeMonitorModel : AutoCloseable {
* TODO provide an unsubscribe mechanism
*/
fun register(nodeHostAndPort: NetworkHostAndPort, username: String, password: String) {
-
// `retryableStateMachineUpdatesSubject` will change it's upstream subscriber in case of RPC connection failure, this `Observable` should
// never produce an error.
// `stateMachineUpdatesSubject` will stay firmly subscribed to `retryableStateMachineUpdatesSubject`
retryableStateMachineUpdatesSubject.subscribe(stateMachineUpdatesSubject)
+ @Suppress("DEPRECATION")
// Proxy may change during re-connect, ensure that subject wiring accurately reacts to this activity.
proxyObservable.addListener { _, _, wrapper ->
if (wrapper != null) {
diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt
index a400c74e41..e9bd23ba68 100644
--- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt
+++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt
@@ -57,14 +57,16 @@ class StateMachineDataModel {
private val progressTracking by observable(NodeMonitorModel::progressTracking)
private val progressEvents = progressTracking.recordAsAssociation(ProgressTrackingEvent::stateMachineId)
- val counter = Counter()
+ private val counter = Counter()
private val stateMachineIndexMap = HashMap()
private val stateMachineStatus = stateMachineUpdates.fold(FXCollections.observableArrayList>()) { list, update ->
when (update) {
is StateMachineUpdate.Added -> {
counter.addSmm()
- val flowInitiator= update.stateMachineInfo.initiator
+ // TODO Use invocationContext instead
+ @Suppress("DEPRECATION")
+ val flowInitiator = update.stateMachineInfo.initiator
val added: SimpleObjectProperty =
SimpleObjectProperty(StateMachineStatus.Added(update.id, update.stateMachineInfo.flowLogicClassName, flowInitiator))
list.add(added)
@@ -83,7 +85,7 @@ class StateMachineDataModel {
private val stateMachineDataList = stateMachineStatus.map {
val smStatus = it.value as StateMachineStatus.Added
val id = smStatus.id
- val progress = SimpleObjectProperty(progressEvents.get(id))
+ val progress = SimpleObjectProperty(progressEvents[id])
StateMachineData(id, smStatus.stateMachineName, smStatus.flowInitiator,
Pair(it, EasyBind.map(progress) { ProgressStatus(it?.message) }))
}
diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/TransactionDataModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/TransactionDataModel.kt
index 5865e7dffd..4f34590880 100644
--- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/TransactionDataModel.kt
+++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/TransactionDataModel.kt
@@ -58,7 +58,7 @@ data class PartiallyResolvedTransaction(
return PartiallyResolvedTransaction(
transaction = transaction,
inputs = transaction.inputs.map { stateRef ->
- val tx = inputTransactions.get(stateRef)
+ val tx = inputTransactions[stateRef]
if (tx == null) {
InputResolution.Unresolved(stateRef)
} else {
@@ -74,7 +74,7 @@ data class PartiallyResolvedTransaction(
val outputCount = transaction.coreTransaction.inputs.size
val stateRefs = (0 until outputCount).map { StateRef(transaction.id, it) }
stateRefs.map { stateRef ->
- val tx = inputTransactions.get(stateRef)
+ val tx = inputTransactions[stateRef]
if (tx == null) {
OutputResolution.Unresolved(stateRef)
} else {
@@ -94,6 +94,7 @@ class TransactionDataModel {
private val collectedTransactions = transactions.recordInSequence().distinctBy { it.id }
private val rpcProxy by observableValue(NodeMonitorModel::proxyObservable)
+ @Suppress("DEPRECATION")
val partiallyResolvedTransactions = collectedTransactions.map {
PartiallyResolvedTransaction.fromSignedTransaction(it,
it.inputs.map { stateRef ->
diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt
index 1d278ad1e0..87ecd1d0a6 100644
--- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt
+++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt
@@ -84,14 +84,12 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
@Before
fun setup() {
-
node = startNode(ALICE_NAME, rpcUsers = listOf(rpcUser))
- client = CordaRPCClient(node.internals.configuration.rpcOptions.address!!)
+ client = CordaRPCClient(node.internals.configuration.rpcOptions.address)
}
@Test
fun `flows draining mode can be enabled and queried`() {
-
asALoggerUser { rpcOps ->
val newValue = true
rpcOps.setFlowsDrainingModeEnabled(true)
@@ -104,7 +102,6 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
@Test
fun `flows draining mode can be disabled and queried`() {
-
asALoggerUser { rpcOps ->
rpcOps.setFlowsDrainingModeEnabled(true)
val newValue = false
@@ -118,7 +115,6 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
@Test
fun `node starts with flows draining mode disabled`() {
-
asALoggerUser { rpcOps ->
val defaultStartingMode = rpcOps.isFlowsDrainingModeEnabled()
@@ -127,14 +123,12 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
}
private fun login(username: String, password: String, externalTrace: Trace? = null, impersonatedActor: Actor? = null): CordaRPCConnection {
-
return client.start(username, password, externalTrace, impersonatedActor)
}
private fun asALoggerUser(action: (CordaRPCOps) -> Unit) {
-
login(rpcUser.username, rpcUser.password).use {
action(it.proxy)
}
}
-}
\ No newline at end of file
+}
diff --git a/core-deterministic/build.gradle b/core-deterministic/build.gradle
index 8f84a5d5ad..c2d2f65f79 100644
--- a/core-deterministic/build.gradle
+++ b/core-deterministic/build.gradle
@@ -90,6 +90,7 @@ task predeterminise(type: ProGuardTask) {
dontpreverify
dontobfuscate
dontoptimize
+ dontnote
printseeds
verbose
@@ -133,6 +134,7 @@ task determinise(type: ProGuardTask) {
keepattributes '*'
keepdirectories
dontobfuscate
+ dontnote
printseeds
verbose
@@ -178,7 +180,6 @@ task checkDeterminism(type: ProGuardTask, dependsOn: jdkTask) {
defaultTasks "determinise"
determinise.finalizedBy metafix
metafix.finalizedBy checkDeterminism
-assemble.dependsOn checkDeterminism
def deterministicJar = metafix.outputs.files.singleFile
artifacts {
diff --git a/core/src/main/kotlin/net/corda/core/flows/StateMachineRunId.kt b/core/src/main/kotlin/net/corda/core/flows/StateMachineRunId.kt
index db56f7b7a3..13d75d5fe9 100644
--- a/core/src/main/kotlin/net/corda/core/flows/StateMachineRunId.kt
+++ b/core/src/main/kotlin/net/corda/core/flows/StateMachineRunId.kt
@@ -18,10 +18,10 @@ import java.util.*
* A unique identifier for a single state machine run, valid across node restarts. Note that a single run always
* has at least one flow, but that flow may also invoke sub-flows: they all share the same run id.
*/
+@DeleteForDJVM
@CordaSerializable
data class StateMachineRunId(val uuid: UUID) {
companion object {
- @DeleteForDJVM
fun createRandom(): StateMachineRunId = StateMachineRunId(UUID.randomUUID())
}
diff --git a/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt b/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt
index d922d4dbf3..f83db058e5 100644
--- a/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt
+++ b/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt
@@ -11,6 +11,7 @@
package net.corda.core.internal
import co.paralleluniverse.fibers.Suspendable
+import net.corda.core.DeleteForDJVM
import net.corda.core.DoNotImplement
import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.InvocationContext
@@ -20,6 +21,7 @@ import net.corda.core.node.ServiceHub
import org.slf4j.Logger
/** This is an internal interface that is implemented by code in the node module. You should look at [FlowLogic]. */
+@DeleteForDJVM
@DoNotImplement
interface FlowStateMachine {
@Suspendable
diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt
index 12fbbc7f19..2c376a5d36 100644
--- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt
+++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt
@@ -52,7 +52,7 @@ data class StateMachineInfo @JvmOverloads constructor(
* An object representing information about the initiator of the flow. Note that this field is
* superceded by the [invocationContext] property, which has more detail.
*/
- @Deprecated("There is more info available using 'context'") val initiator: FlowInitiator,
+ @Deprecated("There is more info available using 'invocationContext'") val initiator: FlowInitiator,
/** A [DataFeed] of the current progress step as a human readable string, and updates to that string. */
val progressTrackerStepAndUpdates: DataFeed?,
/** An [InvocationContext] describing why and by whom the flow was started. */
diff --git a/core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt b/core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt
index b7217a017e..89d62e6cfb 100644
--- a/core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt
+++ b/core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt
@@ -12,11 +12,15 @@ package net.corda.core.node.services
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.DoNotImplement
+import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.SignableData
import net.corda.core.crypto.TransactionSignature
import net.corda.core.identity.PartyAndCertificate
+import java.security.KeyPair
+import java.security.PrivateKey
import java.security.PublicKey
+import java.security.cert.X509Certificate
/**
* The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example,
diff --git a/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt b/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt
index fc4788a213..4d5cf9e683 100644
--- a/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt
+++ b/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt
@@ -140,7 +140,7 @@ object MappedSchemaValidator {
fieldsFromOtherMappedSchema(schema) + methodsFromOtherMappedSchema(schema)
/** Returns true if [javax.persistence] annotation expect [javax.persistence.Transient] is found. */
- private inline fun hasJpaAnnotation(annotations: Array) =
+ private fun hasJpaAnnotation(annotations: Array) =
annotations.any { annotation -> annotation.toString().startsWith("@javax.persistence.") && annotation !is javax.persistence.Transient }
class SchemaCrossReferenceReport(private val schema: String, private val entity: String, private val referencedSchema: String,
diff --git a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt
index 202eb21278..e081e42aac 100644
--- a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt
+++ b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt
@@ -58,7 +58,7 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr
@DeleteForDJVM
constructor(componentGroups: List) : this(componentGroups, PrivacySalt())
- @Deprecated("Required only in some unit-tests and for backwards compatibility purposes.", ReplaceWith("WireTransaction(val componentGroups: List, override val privacySalt: PrivacySalt)"), DeprecationLevel.WARNING)
+ @Deprecated("Required only for backwards compatibility purposes.", ReplaceWith("WireTransaction(val componentGroups: List, override val privacySalt: PrivacySalt)"), DeprecationLevel.WARNING)
@DeleteForDJVM
constructor(inputs: List,
attachments: List,
diff --git a/core/src/test/kotlin/net/corda/core/contracts/ContractsDSLTests.kt b/core/src/test/kotlin/net/corda/core/contracts/ContractsDSLTests.kt
index 05087eb60f..61384a28c8 100644
--- a/core/src/test/kotlin/net/corda/core/contracts/ContractsDSLTests.kt
+++ b/core/src/test/kotlin/net/corda/core/contracts/ContractsDSLTests.kt
@@ -41,7 +41,8 @@ class ContractsDSLTests {
}
@RunWith(Parameterized::class)
- class RequireSingleCommandTests(private val testFunction: (Collection>) -> CommandWithParties, description: String) {
+ class RequireSingleCommandTests(private val testFunction: (Collection>) -> CommandWithParties,
+ @Suppress("UNUSED_PARAMETER") description: String) {
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{1}")
@@ -74,7 +75,8 @@ class ContractsDSLTests {
}
@RunWith(Parameterized::class)
- class SelectWithSingleInputsTests(private val testFunction: (Collection>, PublicKey?, AbstractParty?) -> Iterable>, description: String) {
+ class SelectWithSingleInputsTests(private val testFunction: (Collection>, PublicKey?, AbstractParty?) -> Iterable>,
+ @Suppress("UNUSED_PARAMETER") description: String) {
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{1}")
@@ -122,7 +124,8 @@ class ContractsDSLTests {
}
@RunWith(Parameterized::class)
- class SelectWithMultipleInputsTests(private val testFunction: (Collection>, Collection?, Collection?) -> Iterable>, description: String) {
+ class SelectWithMultipleInputsTests(private val testFunction: (Collection>, Collection?, Collection?) -> Iterable>,
+ @Suppress("UNUSED_PARAMETER") description: String) {
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{1}")
diff --git a/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt b/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt
index 0393f7aeab..7ff62ad728 100644
--- a/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt
+++ b/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt
@@ -30,6 +30,7 @@ import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.testing.internal.TEST_TX_TIME
+import net.corda.testing.internal.createWireTransaction
import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger
@@ -274,7 +275,7 @@ class PartialMerkleTreeTest {
timeWindow: TimeWindow? = null,
attachments: List = emptyList()
): WireTransaction {
- return WireTransaction(
+ return createWireTransaction(
inputs = testTx.inputs,
attachments = attachments,
outputs = testTx.outputs,
diff --git a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt
index e7b4895c81..589f16c3be 100644
--- a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt
+++ b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt
@@ -67,7 +67,7 @@ class AttachmentTests {
bobNode.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
// Insert an attachment into node zero's store directly.
val id = aliceNode.database.transaction {
- aliceNode.attachments.importAttachment(fakeAttachment().inputStream())
+ aliceNode.attachments.importAttachment(fakeAttachment().inputStream(), "test", null)
}
// Get node one to run a flow to fetch it and insert it.
@@ -120,7 +120,7 @@ class AttachmentTests {
val attachment = fakeAttachment()
// Insert an attachment into node zero's store directly.
val id = aliceNode.database.transaction {
- aliceNode.attachments.importAttachment(attachment.inputStream())
+ aliceNode.attachments.importAttachment(attachment.inputStream(), "test", null)
}
// Corrupt its store.
diff --git a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt
index 25ee774c48..466d51345d 100644
--- a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt
+++ b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt
@@ -156,7 +156,7 @@ class ResolveTransactionsFlowTest {
}
// TODO: this operation should not require an explicit transaction
val id = megaCorpNode.transaction {
- megaCorpNode.services.attachments.importAttachment(makeJar())
+ megaCorpNode.services.attachments.importAttachment(makeJar(), "test", null)
}
val stx2 = makeTransactions(withAttachment = id).second
val p = TestFlow(stx2, megaCorp)
@@ -211,6 +211,7 @@ class ResolveTransactionsFlowTest {
}
}
+ @Suppress("unused")
@InitiatedBy(TestFlow::class)
private class TestResponseFlow(val otherSideSession: FlowSession) : FlowLogic() {
@Suspendable
diff --git a/core/src/test/kotlin/net/corda/core/internal/TopologicalSortTest.kt b/core/src/test/kotlin/net/corda/core/internal/TopologicalSortTest.kt
index 1c4f76cad9..6237a1a019 100644
--- a/core/src/test/kotlin/net/corda/core/internal/TopologicalSortTest.kt
+++ b/core/src/test/kotlin/net/corda/core/internal/TopologicalSortTest.kt
@@ -21,10 +21,10 @@ import rx.Observable
import java.util.*
class TopologicalSortTest {
- class DummyTransaction(
+ class DummyTransaction constructor(
override val id: SecureHash,
override val inputs: List,
- val numberOfOutputs: Int,
+ @Suppress("CanBeParameter") private val numberOfOutputs: Int,
override val notary: Party
) : CoreTransaction() {
override val outputs: List> = (1..numberOfOutputs).map {
@@ -78,7 +78,7 @@ class TopologicalSortTest {
}
// Swap two random items
- transactions.combine(Generator.intRange(0, N - 1), Generator.intRange(0, N - 2)) { txs, i, j ->
+ transactions.combine(Generator.intRange(0, N - 1), Generator.intRange(0, N - 2)) { txs, i, _ ->
val k = 0 // if (i == j) i + 1 else j
val tmp = txs[i]
txs[i] = txs[k]
@@ -94,7 +94,7 @@ class TopologicalSortTest {
}
}
- fun checkTopologicallyOrdered(txs: List) {
+ private fun checkTopologicallyOrdered(txs: List) {
val outputs = HashSet()
for (tx in txs) {
if (!outputs.containsAll(tx.inputs)) {
diff --git a/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt b/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt
index 6f1620daa2..f57303780d 100644
--- a/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt
+++ b/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt
@@ -18,6 +18,7 @@ import net.corda.core.crypto.CompositeKey
import net.corda.core.identity.Party
import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.*
+import net.corda.testing.internal.createWireTransaction
import net.corda.testing.internal.rigorousMock
import org.junit.Rule
import org.junit.Test
@@ -63,7 +64,7 @@ class TransactionTests {
val cpub = ck.public
val c1 = CompositeKey.Builder().addKeys(apub, bpub).build(2)
val compKey = CompositeKey.Builder().addKeys(c1, cpub).build(1)
- val wtx = WireTransaction(
+ val wtx = createWireTransaction(
inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)),
attachments = emptyList(),
outputs = emptyList(),
@@ -89,7 +90,7 @@ class TransactionTests {
@Test
fun `signed transaction missing signatures`() {
- val wtx = WireTransaction(
+ val wtx = createWireTransaction(
inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)),
attachments = emptyList(),
outputs = emptyList(),
@@ -129,8 +130,8 @@ class TransactionTests {
}, DummyContract.PROGRAM_ID))
val id = SecureHash.randomSHA256()
val timeWindow: TimeWindow? = null
- val privacySalt: PrivacySalt = PrivacySalt()
- val transaction: LedgerTransaction = LedgerTransaction(
+ val privacySalt = PrivacySalt()
+ val transaction = LedgerTransaction(
inputs,
outputs,
commands,
@@ -147,7 +148,7 @@ class TransactionTests {
@Test
fun `transaction cannot have duplicate inputs`() {
val stateRef = StateRef(SecureHash.randomSHA256(), 0)
- fun buildTransaction() = WireTransaction(
+ fun buildTransaction() = createWireTransaction(
inputs = listOf(stateRef, stateRef),
attachments = emptyList(),
outputs = emptyList(),
@@ -170,7 +171,7 @@ class TransactionTests {
val attachments = emptyList()
val id = SecureHash.randomSHA256()
val timeWindow: TimeWindow? = null
- val privacySalt: PrivacySalt = PrivacySalt()
+ val privacySalt = PrivacySalt()
fun buildTransaction() = LedgerTransaction(
inputs,
outputs,
@@ -188,7 +189,7 @@ class TransactionTests {
@Test
fun `transactions with identical contents must have different ids`() {
val outputState = TransactionState(DummyContract.SingleOwnerState(0, ALICE), DummyContract.PROGRAM_ID, DUMMY_NOTARY)
- fun buildTransaction() = WireTransaction(
+ fun buildTransaction() = createWireTransaction(
inputs = emptyList(),
attachments = emptyList(),
outputs = listOf(outputState),
diff --git a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
index 436b2707b5..2c9ed7cf88 100644
--- a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
+++ b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
@@ -136,7 +136,7 @@ class IntegrationTestingTutorial : IntegrationTest() {
// move to Bob
parallel(
(1..numberOfStates).map { i ->
- expect(match = { it.moved() == i * 100 }) { update: Vault.Update ->
+ expect(match = { it.moved() == i * 100 }) { _: Vault.Update ->
}
}
),
@@ -154,7 +154,7 @@ class IntegrationTestingTutorial : IntegrationTest() {
}
}
- fun Vault.Update.moved(): Int {
+ private fun Vault.Update.moved(): Int {
val consumedSum = consumed.sumBy { it.state.data.amount.quantity.toInt() }
val producedSum = produced.sumBy { it.state.data.amount.quantity.toInt() }
return consumedSum - producedSum
diff --git a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java
index 5d33594b3a..aaca60ab22 100644
--- a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java
+++ b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java
@@ -40,6 +40,7 @@ import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
@@ -134,7 +135,7 @@ public class FlowCookbookJava {
// We retrieve a notary from the network map.
// DOCSTART 01
CordaX500Name notaryName = new CordaX500Name("Notary Service", "London", "GB");
- Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(notaryName);
+ Party specificNotary = Objects.requireNonNull(getServiceHub().getNetworkMapCache().getNotary(notaryName));
// Alternatively, we can pick an arbitrary notary from the notary
// list. However, it is always preferable to specify the notary
// explicitly, as the notary list might change when new notaries are
@@ -378,7 +379,7 @@ public class FlowCookbookJava {
// Or we can add the output state as a ``TransactionState``, which already specifies
// the output's contract and notary.
// DOCSTART 51
- TransactionState txState = new TransactionState(ourOutputState, DummyContract.PROGRAM_ID, specificNotary);
+ TransactionState txState = new TransactionState<>(ourOutputState, DummyContract.PROGRAM_ID, specificNotary);
// DOCEND 51
// Commands can be added as ``Command``s.
@@ -662,7 +663,7 @@ public class FlowCookbookJava {
}
@Override
- protected void checkTransaction(SignedTransaction stx) {
+ protected void checkTransaction(@NotNull SignedTransaction stx) {
requireThat(require -> {
// Any additional checking we see fit...
DummyState outputState = (DummyState) stx.getTx().getOutputs().get(0).getData();
diff --git a/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/contract/CommercialPaper.java b/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/contract/CommercialPaper.java
index 6d406ed5ae..249d9580dc 100644
--- a/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/contract/CommercialPaper.java
+++ b/docs/source/example-code/src/main/java/net/corda/docs/java/tutorial/contract/CommercialPaper.java
@@ -13,6 +13,7 @@ package net.corda.docs.java.tutorial.contract;
import net.corda.core.contracts.*;
import net.corda.core.transactions.LedgerTransaction;
import net.corda.core.transactions.LedgerTransaction.InOutGroup;
+import org.jetbrains.annotations.NotNull;
import java.time.Instant;
import java.util.Currency;
@@ -22,6 +23,7 @@ import static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
import static net.corda.core.contracts.ContractsDSL.requireThat;
import static net.corda.finance.utils.StateSumming.sumCashBy;
+@SuppressWarnings("unused")
public class CommercialPaper implements Contract {
// DOCSTART 1
public static final String IOU_CONTRACT_ID = "com.example.contract.IOUContract";
@@ -29,7 +31,7 @@ public class CommercialPaper implements Contract {
// DOCSTART 3
@Override
- public void verify(LedgerTransaction tx) {
+ public void verify(@NotNull LedgerTransaction tx) {
List> groups = tx.groupStates(State.class, State::withoutOwner);
CommandWithParties cmd = requireSingleCommand(tx.getCommands(), Commands.class);
// DOCEND 3
@@ -37,7 +39,7 @@ public class CommercialPaper implements Contract {
// DOCSTART 4
TimeWindow timeWindow = tx.getTimeWindow();
- for (InOutGroup group : groups) {
+ for (InOutGroup group : groups) {
List inputs = group.getInputs();
List outputs = group.getOutputs();
@@ -57,6 +59,7 @@ public class CommercialPaper implements Contract {
Amount> received = sumCashBy(tx.getOutputStates(), input.getOwner());
if (timeWindow == null) throw new IllegalArgumentException("Redemptions must be timestamped");
Instant time = timeWindow.getFromTime();
+ if (time == null) throw new IllegalArgumentException("Redemptions must have a from time");
requireThat(require -> {
require.using("the paper must have matured", time.isAfter(input.getMaturityDate()));
require.using("the received amount equals the face value", received == input.getFaceValue());
@@ -68,6 +71,7 @@ public class CommercialPaper implements Contract {
State output = outputs.get(0);
if (timeWindow == null) throw new IllegalArgumentException("Issuances must have a time-window");
Instant time = timeWindow.getUntilTime();
+ if (time == null) throw new IllegalArgumentException("Issuances must have an until time");
requireThat(require -> {
// Don't allow people to issue commercial paper under other entities identities.
require.using("output states are issued by a command signer", cmd.getSigners().contains(output.getIssuance().getParty().getOwningKey()));
diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt
index 03dc2eb7d4..8a09b9efce 100644
--- a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt
+++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt
@@ -50,6 +50,7 @@ enum class PrintOrVisualise {
Visualise
}
+@Suppress("DEPRECATION")
fun main(args: Array) {
require(args.isNotEmpty()) { "Usage: [Print|Visualise]" }
val printOrVisualise = PrintOrVisualise.valueOf(args[0])
@@ -109,6 +110,7 @@ fun main(args: Array) {
}
}
// END 5
+ Unit
}
}
diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt
index c50a70841f..a35b8803d8 100644
--- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt
+++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt
@@ -8,7 +8,7 @@
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
*/
-@file:Suppress("UNUSED_VARIABLE", "unused")
+@file:Suppress("UNUSED_VARIABLE", "unused", "DEPRECATION")
package net.corda.docs
diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/tearoffs/TutorialTearOffs.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/tearoffs/TutorialTearOffs.kt
index a33bede8fb..82054737a6 100644
--- a/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/tearoffs/TutorialTearOffs.kt
+++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/tearoffs/TutorialTearOffs.kt
@@ -8,6 +8,8 @@
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
*/
+@file:Suppress("UNUSED_VARIABLE")
+
package net.corda.docs.tutorial.tearoffs
import net.corda.core.contracts.Command
@@ -52,4 +54,4 @@ fun main(args: Array) {
} catch (e: FilteredTransactionVerificationException) {
throw MerkleTreeException("Rate Fix Oracle: Couldn't verify partial Merkle tree.")
}
-}
\ No newline at end of file
+}
diff --git a/docs/source/running-a-node.rst b/docs/source/running-a-node.rst
index faef8eb2bf..dbcf66bc2c 100644
--- a/docs/source/running-a-node.rst
+++ b/docs/source/running-a-node.rst
@@ -43,6 +43,27 @@ Optionally run the node's webserver as well by opening a terminal window in the
.. warning:: The node webserver is for testing purposes only and will be removed soon.
+Command-line options
+~~~~~~~~~~~~~~~~~~~~
+The node can optionally be started with the following command-line options:
+
+* ``--base-directory``: The node working directory where all the files are kept (default: ``.``)
+* ``--bootstrap-raft-cluster``: Bootstraps Raft cluster. The node forms a single node cluster (ignoring otherwise configured peer
+ addresses), acting as a seed for other nodes to join the cluster
+* ``--config-file``: The path to the config file (default: ``node.conf``)
+* ``--help``
+* ``--initial-registration``: Start initial node registration with Corda network to obtain certificate from the permissioning
+ server
+* ``--just-generate-node-info``: Perform the node start-up task necessary to generate its nodeInfo, save it to disk, then
+ quit
+* ``--log-to-console``: If set, prints logging to the console as well as to a file
+* ``--logging-level <[ERROR,WARN,INFO, DEBUG,TRACE]>``: Enable logging at this level and higher (default: INFO)
+* ``--network-root-truststore``: Network root trust store obtained from network operator
+* ``--network-root-truststore-password``: Network root trust store password obtained from network operator
+* ``--no-local-shell``: Do not start the embedded shell locally
+* ``--sshd``: Enables SSHD server for node administration
+* ``--version``: Print the version and exit
+
Enabling remote debugging
~~~~~~~~~~~~~~~~~~~~~~~~~
To enable remote debugging of the node, run the following from the terminal window:
@@ -61,8 +82,11 @@ This command line will start the node with JMX metrics accessible via HTTP on po
See :ref:`Monitoring your node ` for further details.
-Starting all nodes at once from the command line (native)
----------------------------------------------------------
+Starting all nodes at once from the command line
+------------------------------------------------
+
+Native
+~~~~~~
If you created your nodes using ``deployNodes``, a ``runnodes`` shell script (or batch file on Windows) will have been
generated to allow you to quickly start up all nodes and their webservers. ``runnodes`` should only be used for testing
purposes.
@@ -79,8 +103,8 @@ If you receive an ``OutOfMemoryError`` exception when interacting with the nodes
Java heap memory available to them, which you can do when running them individually. See
:ref:`starting-an-individual-corda-node`.
-Starting all nodes at once from the command line (docker-compose)
------------------------------------------------------------------
+docker-compose
+~~~~~~~~~~~~~~
If you created your nodes using ``Dockerform``, the ``docker-compose.yml`` file and corresponding ``Dockerfile`` for
nodes has been created and configured appropriately. Navigate to ``build/nodes`` directory and run ``docker-compose up``
command. This will startup nodes inside new, internal network.
diff --git a/docs/source/tutorial-cordapp.rst b/docs/source/tutorial-cordapp.rst
index 961b17c6dd..eba4a85348 100644
--- a/docs/source/tutorial-cordapp.rst
+++ b/docs/source/tutorial-cordapp.rst
@@ -411,32 +411,38 @@ For more information on the client RPC interface and how to build an RPC client
Running nodes across machines
-----------------------------
-The nodes can be split across different machines and configured to communicate across the network.
+The nodes can be configured to communicate as a network even when distributed across several machines:
-After deploying the nodes, navigate to the build folder (``kotlin-source/build/nodes``) and for each node that needs to
-be moved to another machine open its config file and change the Artemis messaging address to the IP address of the machine
-where the node will run (e.g. ``p2pAddress="10.18.0.166:10007"``).
+* Deploy the nodes as usual:
-These changes require new node-info files to be distributed amongst the nodes. Use the network bootstrapper tool
-(see :doc:`network-bootstrapper` for more information on this and how to built it) to update the files and have
-them distributed locally.
+ * Unix/Mac OSX: ``./gradlew deployNodes``
+ * Windows: ``gradlew.bat deployNodes``
-``java -jar network-bootstrapper.jar kotlin-source/build/nodes``
+* Navigate to the build folder (``kotlin-source/build/nodes``)
+* For each node, open its ``node.conf`` file and change ``localhost`` in its ``p2pAddress`` to the IP address of the machine
+ where the node will be run (e.g. ``p2pAddress="10.18.0.166:10007"``)
+* These changes require new node-info files to be distributed amongst the nodes. Use the network bootstrapper tool
+ (see :doc:`network-bootstrapper`) to update the files and have them distributed locally:
-Once that's done move the node folders to their designated machines (e.g. using a USB key). It is important that none of the
-nodes - including the notary - end up on more than one machine. Each computer should also have a copy of ``runnodes``
-and ``runnodes.bat``.
+ ``java -jar network-bootstrapper.jar kotlin-source/build/nodes``
-For example, you may end up with the following layout:
+* Move the node folders to their individual machines (e.g. using a USB key). It is important that none of the
+ nodes - including the notary - end up on more than one machine. Each computer should also have a copy of ``runnodes``
+ and ``runnodes.bat``.
-* Machine 1: ``Notary``, ``PartyA``, ``runnodes``, ``runnodes.bat``
-* Machine 2: ``PartyB``, ``PartyC``, ``runnodes``, ``runnodes.bat``
+ For example, you may end up with the following layout:
-After starting each node, the nodes will be able to see one another and agree IOUs among themselves.
+ * Machine 1: ``Notary``, ``PartyA``, ``runnodes``, ``runnodes.bat``
+ * Machine 2: ``PartyB``, ``PartyC``, ``runnodes``, ``runnodes.bat``
-.. note:: If you are using H2 and wish to use the same ``h2port`` value for all the nodes, then only assign them that
- value after the nodes have been moved to their machines. The initial bootstrapping process requires access to the nodes'
- databases and if they share the same H2 port then the process will fail.
+* After starting each node, the nodes will be able to see one another and agree IOUs among themselves
+
+.. warning:: The bootstrapper must be run **after** the ``node.conf`` files have been modified, but **before** the nodes
+ are distributed across machines. Otherwise, the nodes will not be able to communicate.
+
+.. note:: If you are using H2 and wish to use the same ``h2port`` value for two or more nodes, you must only assign them that
+ value after the nodes have been moved to their individual machines. The initial bootstrapping process requires access to the
+ nodes' databases and if two nodes share the same H2 port, the process will fail.
Testing and debugging
---------------------
diff --git a/experimental/avalanche/build.gradle b/experimental/avalanche/build.gradle
index ea6e2a4632..82cfd5135d 100644
--- a/experimental/avalanche/build.gradle
+++ b/experimental/avalanche/build.gradle
@@ -1,41 +1,23 @@
buildscript {
- ext.kotlin_version = '1.2.40'
-
repositories {
- mavenCentral()
jcenter()
}
dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.3'
+ classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version"
}
}
-plugins {
- id "org.jetbrains.kotlin.jvm"
- id 'com.github.johnrengelman.shadow' version '2.0.3'
- id 'java'
- id 'application'
-}
-repositories {
- mavenCentral()
-}
+apply plugin: 'kotlin'
+apply plugin: 'application'
+apply plugin: 'com.github.johnrengelman.shadow'
+
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
- compile group: 'info.picocli', name: 'picocli', version: '3.0.1'
- testCompile group: 'junit', name: 'junit', version: '4.12'
-}
-compileKotlin {
- kotlinOptions {
- jvmTarget = "1.8"
- }
-}
-compileTestKotlin {
- kotlinOptions {
- jvmTarget = "1.8"
- }
+ compile "info.picocli:picocli:3.0.1"
+ testCompile "junit:junit:$junit_version"
}
+
mainClassName = "net.corda.avalanche.MainKt"
shadowJar {
baseName = "avalanche"
diff --git a/experimental/behave/build.gradle b/experimental/behave/build.gradle
index 2aabc64c1e..f72ace5fbb 100644
--- a/experimental/behave/build.gradle
+++ b/experimental/behave/build.gradle
@@ -8,37 +8,18 @@
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
*/
-buildscript {
- ext.commonsio_version = '2.6'
- ext.commonslogging_version = '1.2'
- ext.cucumber_version = '1.2.5'
- ext.crash_version = 'cce5a00f114343c1145c1d7756e1dd6df3ea984e'
- ext.docker_client_version = '8.11.0'
-
- repositories {
- maven {
- jcenter()
- url 'https://jitpack.io'
- }
- }
-
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
+ext {
+ commonsio_version = '2.6'
+ cucumber_version = '1.2.5'
+ crash_version = 'cce5a00f114343c1145c1d7756e1dd6df3ea984e'
+ docker_client_version = '8.11.0'
}
group 'net.corda.behave'
-apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'net.corda.plugins.publish-utils'
-sourceCompatibility = 1.8
-
-repositories {
- mavenCentral()
-}
-
sourceSets {
behave {
kotlin {
@@ -89,6 +70,7 @@ dependencies {
compile "org.slf4j:log4j-over-slf4j:$slf4j_version"
compile "org.slf4j:jul-to-slf4j:$slf4j_version"
+ compile "org.slf4j:jcl-over-slf4j:$slf4j_version"
compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
compile "org.apache.logging.log4j:log4j-core:$log4j_version"
@@ -96,10 +78,9 @@ dependencies {
compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version"
// FastClasspathScanner: classpath scanning
- compile 'io.github.lukehutch:fast-classpath-scanner:2.12.3'
+ compile "io.github.lukehutch:fast-classpath-scanner:$fast_classpath_scanner_version"
compile "commons-io:commons-io:$commonsio_version"
- compile "commons-logging:commons-logging:$commonslogging_version"
compile "com.spotify:docker-client:$docker_client_version"
compile "io.reactivex:rxjava:$rxjava_version"
@@ -122,14 +103,6 @@ dependencies {
behaveCompile "info.cukes:cucumber-picocontainer:$cucumber_version"
}
-compileKotlin {
- kotlinOptions.jvmTarget = "1.8"
-}
-
-compileTestKotlin {
- kotlinOptions.jvmTarget = "1.8"
-}
-
test {
testLogging.showStandardStreams = true
}
diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt b/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt
index 0946c70fdd..b00eeb6991 100644
--- a/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt
+++ b/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt
@@ -11,19 +11,19 @@
package net.corda.behave.network
import net.corda.behave.database.DatabaseType
-import net.corda.behave.file.*
-import net.corda.behave.monitoring.PatternWatch
+import net.corda.behave.file.LogSource
+import net.corda.behave.file.currentDirectory
+import net.corda.behave.file.stagingRoot
+import net.corda.behave.file.tmpDirectory
import net.corda.behave.node.Distribution
import net.corda.behave.node.Node
import net.corda.behave.node.configuration.NotaryType
import net.corda.behave.process.Command
import net.corda.behave.process.JarCommand
import net.corda.core.CordaException
-import net.corda.core.CordaRuntimeException
import net.corda.core.internal.*
import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.minutes
-import net.corda.core.utilities.seconds
import java.io.Closeable
import java.nio.file.Files
import java.nio.file.Path
@@ -147,116 +147,8 @@ class Network private constructor(
* using Local signing and "Auto Approval" mode
*/
private fun bootstrapDoorman() {
-
// TODO: rework how we use the Doorman/NMS (now these are a separate product / distribution)
signalFailure("Bootstrapping a Corda Enterprise network using the Doorman is no longer supported; exiting ...")
- return
-
- // WARNING!! Need to use the correct bootstrapper
- // only if using OS nodes (need to choose the latest version)
- val r3node = nodes.values
- .find { it.config.distribution.type == Distribution.Type.CORDA_ENTERPRISE } ?: throw CordaRuntimeException("Missing R3 distribution node")
- val distribution = r3node.config.distribution
-
- // Copy over reference configuration files used in bootstrapping
- val source = doormanConfigDirectory
- val doormanTargetDirectory = targetDirectory / "doorman"
- source.toFile().copyRecursively(doormanTargetDirectory.toFile(), true)
-
- // Use master version of Bootstrapper
- val doormanJar = Distribution.R3_MASTER.doormanJar
- log.info("DoormanJar URL: $doormanJar\n")
-
- // 1. Create key stores for local signer
-
- // java -jar doorman-.jar --mode ROOT_KEYGEN
- log.info("Doorman target directory: $doormanTargetDirectory")
- runCommand(JarCommand(doormanJar,
- arrayOf("--config-file", "$doormanConfigDirectory/node-init.conf", "--mode", "ROOT_KEYGEN", "--trust-store-password", "password"),
- doormanTargetDirectory, timeout))
-
- // java -jar doorman-.jar --mode CA_KEYGEN
- runCommand(JarCommand(doormanJar,
- arrayOf("--config-file", "$doormanConfigDirectory/node-init.conf", "--mode", "CA_KEYGEN"),
- doormanTargetDirectory, timeout))
-
- // 2. Start the doorman service for notary registration
- doormanNMS = JarCommand(doormanJar,
- arrayOf("--config-file", "$doormanConfigDirectory/node-init.conf"),
- doormanTargetDirectory, timeout)
-
- val doormanCommand = runCommand(doormanNMS, noWait = true)
- log.info("Waiting for DoormanNMS to be alive")
-
- PatternWatch(doormanCommand.output, "Network management web services started on").await(30.seconds)
- log.info("DoormanNMS up and running")
-
- // Notary Nodes
- val notaryNodes = nodes.values.filter { it.config.notary.notaryType != NotaryType.NONE }
- notaryNodes.forEach { notaryNode ->
- val notaryTargetDirectory = targetDirectory / notaryNode.config.name
- log.info("Notary target directory: $notaryTargetDirectory")
-
- // 3. Create notary node and register with the doorman
- runCommand(JarCommand(distribution.cordaJar,
- arrayOf("--initial-registration",
- "--base-directory", "$notaryTargetDirectory",
- "--network-root-truststore", "../doorman/certificates/distribute-nodes/network-root-truststore.jks",
- "--network-root-truststore-password", "password"),
- notaryTargetDirectory, timeout))
-
- // 4. Generate node info files for notary nodes
- runCommand(JarCommand(distribution.cordaJar,
- arrayOf("--just-generate-node-info",
- "--base-directory", "$notaryTargetDirectory"),
- notaryTargetDirectory, timeout))
-
- // cp (or ln -s) nodeInfo* notary-node-info
- val nodeInfoFile = notaryTargetDirectory.toFile().listFiles { _, filename -> filename.matches("nodeInfo-.+".toRegex()) }.firstOrNull() ?: throw CordaRuntimeException("Missing notary nodeInfo file")
-
- Files.copy(nodeInfoFile.toPath(), (notaryTargetDirectory / "notary-node-info"), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING)
- }
-
- // exit Doorman process
- doormanCommand.interrupt()
- doormanCommand.waitFor()
-
- // 5. Add notary identities to the network parameters
-
- // 6. Load initial network parameters file for network map service
- val networkParamsConfig = if (notaryNodes.isEmpty()) "network-parameters-without-notary.conf" else "network-parameters.conf"
- val updateNetworkParams = JarCommand(doormanJar,
- arrayOf("--config-file", "$doormanTargetDirectory/node.conf", "--set-network-parameters", "$doormanTargetDirectory/$networkParamsConfig"),
- doormanTargetDirectory, timeout)
- runCommand(updateNetworkParams)
-
- // 7. Start a fully configured Doorman / NMS
- doormanNMS = JarCommand(doormanJar,
- arrayOf("--config-file", "$doormanConfigDirectory/node.conf"),
- doormanTargetDirectory, timeout)
-
- val doormanNMSCommand = runCommand(doormanNMS, noWait = true)
- log.info("Waiting for DoormanNMS to be alive")
-
- PatternWatch(doormanNMSCommand.output, "Network management web services started on").await(30.seconds)
- log.info("DoormanNMS up and running")
-
- // 8. Register other participant nodes
- val partyNodes = nodes.values.filter { it.config.notary.notaryType == NotaryType.NONE }
- partyNodes.forEach { partyNode ->
- val partyTargetDirectory = targetDirectory / partyNode.config.name
- log.info("Party target directory: $partyTargetDirectory")
-
- // 3. Create notary node and register with the doorman
- runCommand(JarCommand(distribution.cordaJar,
- arrayOf("--initial-registration",
- "--network-root-truststore", "../doorman/certificates/distribute-nodes/network-root-truststore.jks",
- "--network-root-truststore-password", "password",
- "--base-directory", "$partyTargetDirectory"),
- partyTargetDirectory, timeout))
- }
-
- isDoormanNMSRunning = true
}
private fun runCommand(command: Command, noWait: Boolean = false): Command {
@@ -446,7 +338,7 @@ class Network private constructor(
val rpcProxyPortNo = node.config.nodeInterface.rpcProxy
val pid = Files.lines(tmpDirectory / "rpcProxy-pid-$rpcProxyPortNo").findFirst().get()
// TODO: consider generic implementation to support non *nix platforms
- Command(listOf("kill", "-9", "$pid")).run()
+ Command(listOf("kill", "-9", pid)).run()
(tmpDirectory / "rpcProxy-pid-$rpcProxyPortNo").deleteIfExists()
}
catch (e: Exception) {
diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt
index f322d89d47..e0a6cb2614 100644
--- a/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt
+++ b/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt
@@ -14,7 +14,6 @@ import net.corda.behave.database.DatabaseConnection
import net.corda.behave.database.DatabaseType
import net.corda.behave.file.LogSource
import net.corda.behave.file.currentDirectory
-import net.corda.behave.file.stagingRoot
import net.corda.behave.monitoring.PatternWatch
import net.corda.behave.node.configuration.*
import net.corda.behave.process.JarCommand
@@ -31,8 +30,8 @@ import net.corda.core.internal.div
import net.corda.core.internal.exists
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.NetworkHostAndPort
-import net.corda.core.utilities.minutes
import net.corda.core.utilities.loggerFor
+import net.corda.core.utilities.minutes
import net.corda.core.utilities.seconds
import org.apache.commons.io.FileUtils
import java.net.InetAddress
@@ -45,7 +44,7 @@ import java.util.concurrent.CountDownLatch
*/
class Node(
val config: Configuration,
- val rootDirectory: Path = currentDirectory,
+ private val rootDirectory: Path = currentDirectory,
private val settings: ServiceSettings = ServiceSettings(),
val rpcProxy: Boolean = false,
val networkType: Distribution.Type
@@ -77,18 +76,6 @@ class Node(
private var haveDependenciesStopped = false
- fun describe(): String {
- val network = config.nodeInterface
- val database = config.database
- return """
- |Node Information: ${config.name}
- | - P2P: ${network.host}:${network.p2pPort}
- | - RPC: ${network.host}:${network.rpcPort}
- | - SSH: ${network.host}:${network.sshPort}
- | - DB: ${network.host}:${database.port} (${database.type})
- |""".trimMargin()
- }
-
fun configure() {
if (isConfigured) { return }
isConfigured = true
@@ -164,10 +151,6 @@ class Node(
}
}
- val nodeInfoGenerationOutput: LogSource by lazy {
- LogSource(logDirectory, "node-info-gen.log")
- }
-
val logOutput: LogSource by lazy {
val hostname = InetAddress.getLocalHost().hostName
LogSource(logDirectory, "node-$hostname.*.log")
@@ -387,10 +370,11 @@ class Node(
val name = name ?: error("Node name not set")
val directory = directory ?: error("Runtime directory not set")
// TODO: rework how we use the Doorman/NMS (now these are a separate product / distribution)
- val compatibilityZoneURL = null
- if (networkType == Distribution.Type.CORDA_ENTERPRISE && System.getProperty("USE_NETWORK_SERVICES") != null)
- "http://localhost:1300" // TODO: add additional USE_NETWORK_SERVICES_URL to specify location of existing operational environment to use.
- else null
+ val compatibilityZoneURL = if (networkType == Distribution.Type.CORDA_ENTERPRISE && System.getProperty("USE_NETWORK_SERVICES") != null) {
+ "http://localhost:1300" // TODO: add additional USE_NETWORK_SERVICES_URL to specify location of existing operational environment to use.
+ } else {
+ null
+ }
return Node(
Configuration(
name,
diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt
index 42581651d5..467e69bac2 100644
--- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt
+++ b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt
@@ -72,7 +72,7 @@ class ScenarioState {
inline fun withNetwork(action: ScenarioState.() -> T): T {
ensureNetworkIsRunning()
- return action()
+ return this.action()
}
inline fun withClient(nodeName: String, crossinline action: (CordaRPCOps) -> T): T {
diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt
index d2168d6f0d..5cd3e7e1e2 100644
--- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt
+++ b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt
@@ -10,34 +10,33 @@
package net.corda.behave.scenarios.helpers
-import net.corda.behave.logging.getLogger
import net.corda.behave.scenarios.ScenarioState
import net.corda.core.messaging.CordaRPCOps
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
abstract class Substeps(protected val state: ScenarioState) {
+ protected val log: Logger = LoggerFactory.getLogger(javaClass)
- protected val log = getLogger()
-
- protected fun withNetwork(action: ScenarioState.() -> Unit) =
- state.withNetwork(action)
+ protected fun withNetwork(action: ScenarioState.() -> Unit) = state.withNetwork(action)
protected fun withClient(nodeName: String, action: ScenarioState.(CordaRPCOps) -> T): T {
- return state.withClient(nodeName, {
- return@withClient try {
+ return state.withClient(nodeName) {
+ try {
action(state, it)
} catch (ex: Exception) {
- state.error(ex.message ?: "Failed to execute RPC call")
+ state.error(ex.message ?: "Failed to execute RPC call")
}
- })
+ }
}
protected fun withClientProxy(nodeName: String, action: ScenarioState.(CordaRPCOps) -> T): T {
- return state.withClientProxy(nodeName, {
- return@withClientProxy try {
+ return state.withClientProxy(nodeName) {
+ try {
action(state, it)
} catch (ex: Exception) {
- state.error(ex.message ?: "Failed to execute HTTP call")
+ state.error(ex.message ?: "Failed to execute HTTP call")
}
- })
+ }
}
-}
\ No newline at end of file
+}
diff --git a/experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt b/experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt
index 88161f4f07..631e288cd0 100644
--- a/experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt
+++ b/experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt
@@ -15,7 +15,6 @@ import org.junit.Test
import rx.observers.TestSubscriber
class CommandTests {
-
@Test
fun `successful command returns zero`() {
val exitCode = Command(listOf("ls", "/")).run()
diff --git a/experimental/build.gradle b/experimental/build.gradle
index 208626a909..0c7fdae1dd 100644
--- a/experimental/build.gradle
+++ b/experimental/build.gradle
@@ -34,7 +34,7 @@ dependencies {
compile project(':finance')
// ObjectWeb Asm: a library for synthesising and working with JVM bytecode.
- compile "org.ow2.asm:asm:5.0.4"
+ compile "org.ow2.asm:asm:$asm_version"
compile "com.google.guava:guava:$guava_version"
diff --git a/experimental/flow-hook/build.gradle b/experimental/flow-hook/build.gradle
index 84060b827c..ced3dbf488 100644
--- a/experimental/flow-hook/build.gradle
+++ b/experimental/flow-hook/build.gradle
@@ -34,7 +34,6 @@ repositories {
}
apply plugin: 'kotlin'
-apply plugin: 'kotlin-kapt'
apply plugin: 'idea'
description 'A javaagent to allow hooking into Kryo'
diff --git a/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FiberMonitor.kt b/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FiberMonitor.kt
index 64bce119ea..b4b4f80ef2 100644
--- a/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FiberMonitor.kt
+++ b/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FiberMonitor.kt
@@ -114,7 +114,6 @@ object FiberMonitor {
thread {
while (true) {
Thread.sleep(1000)
- this
}
}
}
diff --git a/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHook.kt b/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHook.kt
index 5ee9445482..d438fb4a1c 100644
--- a/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHook.kt
+++ b/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHook.kt
@@ -12,7 +12,7 @@ package net.corda.flowhook
import java.lang.instrument.Instrumentation
-@Suppress("UNUSED")
+@Suppress("UNUSED", "UNUSED_PARAMETER")
class FlowHookAgent {
companion object {
@JvmStatic
@@ -22,4 +22,3 @@ class FlowHookAgent {
}
}
}
-
diff --git a/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHookContainer.kt b/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHookContainer.kt
index f69a7fcf10..257bc99f65 100644
--- a/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHookContainer.kt
+++ b/experimental/flow-hook/src/main/kotlin/net/corda/flowhook/FlowHookContainer.kt
@@ -21,7 +21,7 @@ import org.apache.activemq.artemis.core.io.buffer.TimedBuffer
import java.sql.Connection
import java.util.concurrent.TimeUnit
-@Suppress("UNUSED")
+@Suppress("UNUSED", "UNUSED_PARAMETER")
object FlowHookContainer {
@JvmStatic
diff --git a/experimental/ha-testing/build.gradle b/experimental/ha-testing/build.gradle
index e9d0621f08..42355015ce 100644
--- a/experimental/ha-testing/build.gradle
+++ b/experimental/ha-testing/build.gradle
@@ -34,7 +34,6 @@ repositories {
}
apply plugin: 'kotlin'
-apply plugin: 'kotlin-kapt'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.cordapp'
diff --git a/experimental/ha-testing/src/main/kotlin/net/corda/haTesting/LinearStateScenarioRunner.kt b/experimental/ha-testing/src/main/kotlin/net/corda/haTesting/LinearStateScenarioRunner.kt
index 7328921004..efb39e6870 100644
--- a/experimental/ha-testing/src/main/kotlin/net/corda/haTesting/LinearStateScenarioRunner.kt
+++ b/experimental/ha-testing/src/main/kotlin/net/corda/haTesting/LinearStateScenarioRunner.kt
@@ -11,13 +11,11 @@ import java.util.concurrent.Callable
// Responsible for executing test scenario for a single node executing `LinearStateBatchNotariseFlow` and verifying the results
class LinearStateScenarioRunner(options: OptionSet) : AbstractScenarioRunner(options), Callable {
-
companion object {
private val logger = contextLogger()
}
override fun call(): Boolean {
-
scenarioInitialized()
try {
@@ -42,6 +40,7 @@ class LinearStateScenarioRunner(options: OptionSet) : AbstractScenarioRunner(opt
}
}
+ @Suppress("UNUSED_PARAMETER")
private fun verifyResultsAndStatesTally(results: MutableList, states: Vault.Page): Boolean {
// Unfortunately, there is absolutely nothing in `LinearStateBatchNotariseFlow.Result` which can link it to the original transaction
return true
diff --git a/experimental/kryo-hook/build.gradle b/experimental/kryo-hook/build.gradle
index b53acdf939..37f343064e 100644
--- a/experimental/kryo-hook/build.gradle
+++ b/experimental/kryo-hook/build.gradle
@@ -8,33 +8,11 @@
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
*/
-buildscript {
- // For sharing constants between builds
- Properties constants = new Properties()
- file("$projectDir/../../constants.properties").withInputStream { constants.load(it) }
-
- ext.kotlin_version = constants.getProperty("kotlinVersion")
- ext.javaassist_version = "3.12.1.GA"
-
- repositories {
- mavenLocal()
- mavenCentral()
- jcenter()
- }
-
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-repositories {
- mavenLocal()
- mavenCentral()
- jcenter()
+ext {
+ javaassist_version = "3.12.1.GA"
}
apply plugin: 'kotlin'
-apply plugin: 'kotlin-kapt'
apply plugin: 'idea'
description 'A javaagent to allow hooking into Kryo'
diff --git a/experimental/quasar-hook/build.gradle b/experimental/quasar-hook/build.gradle
index ba297a284e..3c532eabf1 100644
--- a/experimental/quasar-hook/build.gradle
+++ b/experimental/quasar-hook/build.gradle
@@ -8,33 +8,11 @@
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
*/
-buildscript {
- // For sharing constants between builds
- Properties constants = new Properties()
- file("$projectDir/../../constants.properties").withInputStream { constants.load(it) }
-
- ext.kotlin_version = constants.getProperty("kotlinVersion")
- ext.javaassist_version = "3.12.1.GA"
-
- repositories {
- mavenLocal()
- mavenCentral()
- jcenter()
- }
-
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-repositories {
- mavenLocal()
- mavenCentral()
- jcenter()
+ext {
+ javaassist_version = "3.12.1.GA"
}
apply plugin: 'kotlin'
-apply plugin: 'kotlin-kapt'
apply plugin: 'idea'
description 'A javaagent to allow hooking into the instrumentation by Quasar'
diff --git a/experimental/src/main/kotlin/net/corda/finance/contracts/universal/PrettyPrint.kt b/experimental/src/main/kotlin/net/corda/finance/contracts/universal/PrettyPrint.kt
index a23b91e0ce..d1f08ff87e 100644
--- a/experimental/src/main/kotlin/net/corda/finance/contracts/universal/PrettyPrint.kt
+++ b/experimental/src/main/kotlin/net/corda/finance/contracts/universal/PrettyPrint.kt
@@ -12,12 +12,12 @@ package net.corda.finance.contracts.universal
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.Party
+import net.corda.core.internal.uncheckedCast
import java.math.BigDecimal
import java.security.PublicKey
import java.time.Instant
private class PrettyPrint(arr : Arrangement) {
-
val parties = involvedParties(arr)
private val sb = StringBuilder()
@@ -26,21 +26,21 @@ private class PrettyPrint(arr : Arrangement) {
private var atStart = true
private fun print(msg: String) {
if (atStart)
- repeat(indentLevel, { sb.append(' ') })
+ repeat(indentLevel) { sb.append(' ') }
sb.append(msg)
atStart = false
}
private fun println(message: Any?) {
if (atStart)
- repeat(indentLevel, { sb.append(' ') })
+ repeat(indentLevel) { sb.append(' ') }
sb.appendln(message)
atStart = true
}
private fun print(msg: Any?) {
if (atStart)
- repeat(indentLevel, { sb.append(' ') })
+ repeat(indentLevel) { sb.append(' ') }
sb.append(msg)
atStart = false
}
@@ -55,8 +55,7 @@ private class PrettyPrint(arr : Arrangement) {
val partyMap = mutableMapOf()
val usedPartyNames = mutableSetOf()
- fun createPartyName(party : Party) : String
- {
+ fun createPartyName(party : Party): String {
val parts = party.name.organisation.toLowerCase().split(' ')
var camelName = parts.drop(1).fold(parts.first()) {
@@ -79,38 +78,38 @@ private class PrettyPrint(arr : Arrangement) {
}
}
- fun prettyPrint(per: Perceivable, x: Boolean? = null) {
+ fun prettyPrintBoolean(per: Perceivable) {
when (per) {
is Const -> print("\"${per.value}\"")
is PerceivableOr -> {
- prettyPrint(per.left)
+ prettyPrintBoolean(per.left)
print(" or ")
- prettyPrint(per.right)
+ prettyPrintBoolean(per.right)
}
is PerceivableAnd -> {
- prettyPrint(per.left)
+ prettyPrintBoolean(per.left)
print(" and ")
- prettyPrint(per.right)
+ prettyPrintBoolean(per.right)
}
is TimePerceivable -> {
when (per.cmp) {
Comparison.GT, Comparison.GTE -> {
print("after(")
- prettyPrint(per.instant)
+ prettyPrintInstant(per.instant)
print(")")
}
Comparison.LT, Comparison.LTE -> {
print("before(")
- prettyPrint(per.instant)
+ prettyPrintInstant(per.instant)
print(")")
}
}
}
is PerceivableComparison<*> -> {
when (per.type) {
- BigDecimal::class.java -> prettyPrint(per.left as Perceivable)
- Instant::class.java -> prettyPrint(per.left as Perceivable)
- Boolean::class.java -> prettyPrint(per.left as Perceivable)
+ BigDecimal::class.java -> prettyPrintBigDecimal(uncheckedCast(per.left))
+ Instant::class.java -> prettyPrintInstant(uncheckedCast(per.left))
+ Boolean::class.java -> prettyPrintBoolean(uncheckedCast(per.left))
}
when (per.cmp) {
Comparison.GT -> print(" > ")
@@ -119,9 +118,9 @@ private class PrettyPrint(arr : Arrangement) {
Comparison.LTE -> print(" <= ")
}
when (per.type) {
- BigDecimal::class.java -> prettyPrint(per.right as Perceivable)
- Instant::class.java -> prettyPrint(per.right as Perceivable)
- Boolean::class.java -> prettyPrint(per.right as Perceivable)
+ BigDecimal::class.java -> prettyPrintBigDecimal(uncheckedCast(per.right))
+ Instant::class.java -> prettyPrintInstant(uncheckedCast(per.right))
+ Boolean::class.java -> prettyPrintBoolean(uncheckedCast(per.right))
}
}
is TerminalEvent -> print("TerminalEvent(${partyMap[per.reference.owningKey]}, \"${per.source}\")")
@@ -130,7 +129,7 @@ private class PrettyPrint(arr : Arrangement) {
}
}
- fun prettyPrint(per: Perceivable, x: Instant? = null) {
+ fun prettyPrintInstant(per: Perceivable) {
when (per) {
is Const -> print("\"${per.value}\"")
is StartDate -> print("startDate")
@@ -139,34 +138,33 @@ private class PrettyPrint(arr : Arrangement) {
}
}
- fun prettyPrint(per: Perceivable, x: BigDecimal? = null) {
+ fun prettyPrintBigDecimal(per: Perceivable) {
when (per) {
is PerceivableOperation -> {
- prettyPrint(per.left)
+ prettyPrintBigDecimal(per.left)
when (per.op) {
Operation.PLUS -> print(" + ")
Operation.MINUS -> print(" - ")
Operation.DIV -> print(" / ")
Operation.TIMES -> print(" * ")
- else -> print(per.op)
}
- prettyPrint(per.right)
+ prettyPrintBigDecimal(per.right)
}
is UnaryPlus -> {
print("(")
- prettyPrint(per.arg)
+ prettyPrintBigDecimal(per.arg)
print(".).plus()")
}
is Const -> print(per.value)
is Interest -> {
print("Interest(")
- prettyPrint(per.amount)
+ prettyPrintBigDecimal(per.amount)
print(", \"${per.dayCountConvention}\", ")
- prettyPrint(per.amount)
+ prettyPrintBigDecimal(per.amount)
print(", ")
- prettyPrint(per.start)
+ prettyPrintInstant(per.start)
print(", ")
- prettyPrint(per.end)
+ prettyPrintInstant(per.end)
print(")")
}
is CurrencyCross -> print("${per.foreign}/${per.domestic}")
@@ -175,7 +173,6 @@ private class PrettyPrint(arr : Arrangement) {
}
fun prettyPrint(arr: Arrangement) {
-
when (arr) {
is Zero -> println("zero")
is RollOut -> {
@@ -193,7 +190,7 @@ private class PrettyPrint(arr : Arrangement) {
is Continuation -> println("next()")
is Obligation -> {
print("${partyMap[arr.from.owningKey]}.gives( ${partyMap[arr.to.owningKey]}, ")
- prettyPrint(arr.amount)
+ prettyPrintBigDecimal(arr.amount)
println(", ${arr.currency})")
}
is Actions -> {
@@ -201,7 +198,7 @@ private class PrettyPrint(arr : Arrangement) {
indent {
for ((name, condition, arrangement) in arr.actions) {
print("\"$name\".givenThat(")
- prettyPrint(condition)
+ prettyPrintBoolean(condition)
println(") {")
indent {
prettyPrint(arrangement)
diff --git a/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt b/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt
index 3df91ffc48..af5a1f8acc 100644
--- a/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt
+++ b/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt
@@ -46,46 +46,45 @@ class UniversalContract : Contract {
class Split(val ratio: BigDecimal) : Commands
}
- fun eval(@Suppress("UNUSED_PARAMETER") tx: LedgerTransaction, expr: Perceivable): Instant? = when (expr) {
+ fun evalInstant(expr: Perceivable): Instant? = when (expr) {
is Const -> expr.value
is StartDate -> null
is EndDate -> null
else -> throw Error("Unable to evaluate")
}
- fun eval(tx: LedgerTransaction, expr: Perceivable): Boolean = when (expr) {
- is PerceivableAnd -> eval(tx, expr.left) && eval(tx, expr.right)
- is PerceivableOr -> eval(tx, expr.left) || eval(tx, expr.right)
+ fun evalBoolean(tx: LedgerTransaction, expr: Perceivable): Boolean = when (expr) {
+ is PerceivableAnd -> evalBoolean(tx, expr.left) && evalBoolean(tx, expr.right)
+ is PerceivableOr -> evalBoolean(tx, expr.left) || evalBoolean(tx, expr.right)
is Const -> expr.value
is TimePerceivable -> when (expr.cmp) {
- Comparison.LTE -> tx.timeWindow!!.fromTime!! <= eval(tx, expr.instant)
- Comparison.GTE -> tx.timeWindow!!.untilTime!! >= eval(tx, expr.instant)
+ Comparison.LTE -> tx.timeWindow!!.fromTime!! <= evalInstant(expr.instant)
+ Comparison.GTE -> tx.timeWindow!!.untilTime!! >= evalInstant(expr.instant)
else -> throw NotImplementedError("eval special")
}
is ActorPerceivable -> tx.commands.single().signers.contains(expr.actor.owningKey)
else -> throw NotImplementedError("eval - Boolean - " + expr.javaClass.name)
}
- fun eval(tx: LedgerTransaction, expr: Perceivable): BigDecimal =
+ fun evalBigDecimal(tx: LedgerTransaction, expr: Perceivable): BigDecimal =
when (expr) {
is Const -> expr.value
is UnaryPlus -> {
- val x = eval(tx, expr.arg)
+ val x = evalBigDecimal(tx, expr.arg)
if (x > BigDecimal.ZERO)
x
else
BigDecimal.ZERO
}
is PerceivableOperation -> {
- val l = eval(tx, expr.left)
- val r = eval(tx, expr.right)
+ val l = evalBigDecimal(tx, expr.left)
+ val r = evalBigDecimal(tx, expr.right)
when (expr.op) {
Operation.DIV -> l / r
Operation.MINUS -> l - r
Operation.PLUS -> l + r
Operation.TIMES -> l * r
- else -> throw NotImplementedError("eval - amount - operation " + expr.op)
}
}
is Fixing -> {
@@ -93,8 +92,8 @@ class UniversalContract : Contract {
0.0.bd
}
is Interest -> {
- val a = eval(tx, expr.amount)
- val i = eval(tx, expr.interest)
+ val a = evalBigDecimal(tx, expr.amount)
+ val i = evalBigDecimal(tx, expr.interest)
//TODO
@@ -105,7 +104,7 @@ class UniversalContract : Contract {
fun validateImmediateTransfers(tx: LedgerTransaction, arrangement: Arrangement): Arrangement = when (arrangement) {
is Obligation -> {
- val amount = eval(tx, arrangement.amount)
+ val amount = evalBigDecimal(tx, arrangement.amount)
requireThat { "transferred quantity is non-negative" using (amount >= BigDecimal.ZERO) }
Obligation(const(amount), arrangement.currency, arrangement.from, arrangement.to)
}
@@ -220,7 +219,7 @@ class UniversalContract : Contract {
"action must have a time-window" using (tx.timeWindow != null)
// "action must be authorized" by (cmd.signers.any { action.actors.any { party -> party.owningKey == it } })
// todo perhaps merge these two requirements?
- "condition must be met" using (eval(tx, action.condition))
+ "condition must be met" using evalBoolean(tx, action.condition)
}
// verify that any resulting transfers can be resolved
@@ -297,7 +296,7 @@ class UniversalContract : Contract {
perceivable.dayCountConvention, replaceFixing(tx, perceivable.interest, fixings, unusedFixings),
perceivable.start, perceivable.end))
is Fixing -> {
- val dt = eval(tx, perceivable.date)
+ val dt = evalInstant(perceivable.date)
if (dt != null && fixings.containsKey(FixOf(perceivable.source, dt.toLocalDate(), perceivable.tenor))) {
unusedFixings.remove(FixOf(perceivable.source, dt.toLocalDate(), perceivable.tenor))
uncheckedCast(Const(fixings[FixOf(perceivable.source, dt.toLocalDate(), perceivable.tenor)]!!))
diff --git a/experimental/src/test/kotlin/net/corda/finance/contracts/universal/IRS.kt b/experimental/src/test/kotlin/net/corda/finance/contracts/universal/IRS.kt
index cbfbca3382..6c47849690 100644
--- a/experimental/src/test/kotlin/net/corda/finance/contracts/universal/IRS.kt
+++ b/experimental/src/test/kotlin/net/corda/finance/contracts/universal/IRS.kt
@@ -24,13 +24,12 @@ class IRS {
@Rule
@JvmField
val testSerialization = SerializationEnvironmentRule()
- val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
- val notional = 50.M
- val currency = EUR
-
- val tradeDate: LocalDate = LocalDate.of(2016, 9, 1)
+ private val testTxTime1: Instant = Instant.parse("2017-09-02T12:00:00.00Z")
+ private val notional = 50.M
+ private val currency = EUR
+ private val tradeDate: LocalDate = LocalDate.of(2016, 9, 1)
/*
@@ -43,7 +42,7 @@ class IRS {
*/
- val contractInitial = arrange {
+ private val contractInitial = arrange {
rollOut("2016-09-01".ld, "2018-09-01".ld, Frequency.Quarterly) {
actions {
(acmeCorp or highStreetBank) may {
@@ -62,7 +61,8 @@ class IRS {
}
}
}
- val contractAfterFixingFirst = arrange {
+
+ private val contractAfterFixingFirst = arrange {
actions {
(acmeCorp or highStreetBank) may {
val floating = interest(notional, "act/365", 1.0.bd, "2016-09-01", "2016-12-01")
@@ -93,15 +93,15 @@ class IRS {
rollOut("2016-12-01".ld, "2018-09-01".ld, Frequency.Quarterly) {
actions {
(acmeCorp or highStreetBank) may {
- val floating = interest(notional, "act/365", fix("LIBOR", start, Tenor("3M")), start, end)
- val fixed = interest(notional, "act/365", 0.5.bd, start, end)
+ val nextFloating = interest(notional, "act/365", fix("LIBOR", start, Tenor("3M")), start, end)
+ val nextFixed = interest(notional, "act/365", 0.5.bd, start, end)
"pay floating" anytime {
- highStreetBank.owes(acmeCorp, floating - fixed, currency)
+ highStreetBank.owes(acmeCorp, nextFloating - nextFixed, currency)
next()
}
"pay fixed" anytime {
- highStreetBank.owes(acmeCorp, fixed - floating, currency)
+ highStreetBank.owes(acmeCorp, nextFixed - nextFloating, currency)
next()
}
}
@@ -112,7 +112,7 @@ class IRS {
}
}
- val contractAfterExecutionFirst = arrange {
+ private val contractAfterExecutionFirst = arrange {
rollOut("2016-12-01".ld, "2018-09-01".ld, Frequency.Quarterly) {
actions {
(acmeCorp or highStreetBank) may {
@@ -132,19 +132,20 @@ class IRS {
}
}
- val paymentFirst = arrange { highStreetBank.owes(acmeCorp, 250.K, EUR) }
+ private val paymentFirst = arrange { highStreetBank.owes(acmeCorp, 250.K, EUR) }
- val stateInitial = UniversalContract.State(listOf(DUMMY_NOTARY), contractInitial)
+ private val stateInitial = UniversalContract.State(listOf(DUMMY_NOTARY), contractInitial)
- val stateAfterFixingFirst = UniversalContract.State(listOf(DUMMY_NOTARY), contractAfterFixingFirst)
- val stateAfterExecutionFirst = UniversalContract.State(listOf(DUMMY_NOTARY), contractAfterExecutionFirst)
+ private val stateAfterFixingFirst = UniversalContract.State(listOf(DUMMY_NOTARY), contractAfterFixingFirst)
+ private val stateAfterExecutionFirst = UniversalContract.State(listOf(DUMMY_NOTARY), contractAfterExecutionFirst)
+
+ private val statePaymentFirst = UniversalContract.State(listOf(DUMMY_NOTARY), paymentFirst)
- val statePaymentFirst = UniversalContract.State(listOf(DUMMY_NOTARY), paymentFirst)
@Test
fun issue() {
transaction {
output(UNIVERSAL_PROGRAM_ID, stateInitial)
- timeWindow(TEST_TX_TIME_1)
+ timeWindow(testTxTime1)
tweak {
command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
@@ -160,7 +161,7 @@ class IRS {
transaction {
input(UNIVERSAL_PROGRAM_ID, stateInitial)
output(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
- timeWindow(TEST_TX_TIME_1)
+ timeWindow(testTxTime1)
tweak {
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
@@ -200,7 +201,7 @@ class IRS {
input(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
output(UNIVERSAL_PROGRAM_ID, stateAfterExecutionFirst)
output(UNIVERSAL_PROGRAM_ID, statePaymentFirst)
- timeWindow(TEST_TX_TIME_1)
+ timeWindow(testTxTime1)
tweak {
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionOracleImpl.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionOracleImpl.kt
index c9c68f1413..111b6045b7 100644
--- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionOracleImpl.kt
+++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionOracleImpl.kt
@@ -27,8 +27,8 @@ class CashSelectionOracleImpl : AbstractCashSelection(maxRetries = 16, retrySlee
private val log = contextLogger()
}
- override fun isCompatible(metaData: DatabaseMetaData): Boolean {
- return metaData.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true)
+ override fun isCompatible(metadata: DatabaseMetaData): Boolean {
+ return metadata.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true)
}
override fun toString() = "${this::class.qualifiedName} for '$JDBC_DRIVER_NAME'"
diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionSQLServerImpl.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionSQLServerImpl.kt
index fa2578c4c8..6e3e76051e 100644
--- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionSQLServerImpl.kt
+++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionSQLServerImpl.kt
@@ -16,7 +16,6 @@ import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.contextLogger
-import net.corda.core.utilities.toBase58String
import java.sql.Connection
import java.sql.DatabaseMetaData
import java.sql.ResultSet
@@ -32,8 +31,8 @@ class CashSelectionSQLServerImpl : AbstractCashSelection(maxRetries = 16, retryS
private val log = contextLogger()
}
- override fun isCompatible(metaData: DatabaseMetaData): Boolean {
- return metaData.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true)
+ override fun isCompatible(metadata: DatabaseMetaData): Boolean {
+ return metadata.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true)
}
override fun toString() = "${this::class.qualifiedName} for '$JDBC_DRIVER_NAME'"
diff --git a/launcher/src/main/kotlin/net/corda/launcher/Launcher.kt b/launcher/src/main/kotlin/net/corda/launcher/Launcher.kt
index 445dee7f4c..4b21edb7de 100644
--- a/launcher/src/main/kotlin/net/corda/launcher/Launcher.kt
+++ b/launcher/src/main/kotlin/net/corda/launcher/Launcher.kt
@@ -8,7 +8,6 @@ import java.nio.file.Paths
import kotlin.system.exitProcess
fun main(args: Array) {
-
if (args.isEmpty()) {
println("Usage: launcher [args]")
exitProcess(0)
@@ -54,15 +53,14 @@ fun main(args: Array) {
@Suppress("unchecked")
private fun fixBaseDirArg(args: Array, nodeBaseDirFromArgs: Path): Array {
val baseDirIdx = args.indexOf("--base-directory")
- if (baseDirIdx != -1){
- args[baseDirIdx+1] = nodeBaseDirFromArgs.toString()
- return args
+ return if (baseDirIdx != -1) {
+ // Replace the arg that follows, i.e. --base-directory X
+ // TODO This will not work for --base-directory=X
+ args[baseDirIdx + 1] = nodeBaseDirFromArgs.toString()
+ args
+ } else {
+ args + listOf("--base-directory", nodeBaseDirFromArgs.toString())
}
-
- val argsWithBaseDir = args.copyOf(args.size + 2)
- argsWithBaseDir[argsWithBaseDir.lastIndex - 1] = "--base-directory"
- argsWithBaseDir[argsWithBaseDir.lastIndex] = nodeBaseDirFromArgs.toString()
- return argsWithBaseDir as Array
}
private fun setupClassLoader(nodeBaseDir: Path): ClassLoader {
diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt
index 8964cb0faa..9591a95907 100644
--- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt
+++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt
@@ -35,6 +35,8 @@ import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.KType
+import kotlin.reflect.full.createInstance
+import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.jvmErasure
@@ -42,6 +44,17 @@ import kotlin.reflect.jvm.jvmErasure
@Target(AnnotationTarget.PROPERTY)
annotation class OldConfig(val value: String)
+/**
+ * This annotation can be used to provide ConfigParser for the class,
+ * the [parseAs] method will use the provided parser instead of data class constructs to parse the object.
+ */
+@Target(AnnotationTarget.CLASS)
+annotation class CustomConfigParser(val parser: KClass>)
+
+interface ConfigParser {
+ fun parse(config: Config): T
+}
+
const val CUSTOM_NODE_PROPERTIES_ROOT = "custom"
// TODO Move other config parsing to use parseAs and remove this
@@ -50,7 +63,10 @@ operator fun Config.getValue(receiver: Any, metadata: KProperty<*>): T
}
fun Config.parseAs(clazz: KClass, onUnknownKeys: ((Set, logger: Logger) -> Unit) = UnknownConfigKeysPolicy.FAIL::handle, nestedPath: String? = null): T {
- require(clazz.isData) { "Only Kotlin data classes can be parsed. Offending: ${clazz.qualifiedName}" }
+ // Use custom parser if provided, instead of treating the object as data class.
+ clazz.findAnnotation()?.let { return uncheckedCast(it.parser.createInstance().parse(this)) }
+
+ require(clazz.isData) { "Only Kotlin data classes or class annotated with CustomConfigParser can be parsed. Offending: ${clazz.qualifiedName}" }
val constructor = clazz.primaryConstructor!!
val parameters = constructor.parameters
val parameterNames = parameters.flatMap { param ->
diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt
index 05e985ab42..130219f706 100644
--- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt
+++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt
@@ -237,6 +237,36 @@ class ConfigParsingTest {
}
}
+ @Test
+ fun `parse with provided parser`() {
+ val type1Config = mapOf("type" to "1", "value" to "type 1 value")
+ val type2Config = mapOf("type" to "2", "value" to "type 2 value")
+
+ val configuration = config("values" to listOf(type1Config, type2Config))
+ val objects = configuration.parseAs()
+
+ assertThat(objects.values).containsExactly(TestObject.Type1("type 1 value"), TestObject.Type2("type 2 value"))
+ }
+
+ class TestParser : ConfigParser {
+ override fun parse(config: Config): TestObject {
+ val type = config.getInt("type")
+ return when (type) {
+ 1 -> config.parseAs(onUnknownKeys = UnknownConfigKeysPolicy.IGNORE::handle)
+ 2 -> config.parseAs(onUnknownKeys = UnknownConfigKeysPolicy.IGNORE::handle)
+ else -> throw IllegalArgumentException("Unsupported Object type : '$type'")
+ }
+ }
+ }
+
+ data class TestObjects(val values: List)
+
+ @CustomConfigParser(TestParser::class)
+ sealed class TestObject {
+ data class Type1(val value: String) : TestObject()
+ data class Type2(val value: String) : TestObject()
+ }
+
private inline fun , reified L : ListData, V : Any> testPropertyType(
value1: V,
value2: V,
@@ -320,6 +350,7 @@ class ConfigParsingTest {
require(positive > 0) { "$positive is not positive" }
}
}
+
data class OldData(
@OldConfig("oldValue")
val newValue: String)
diff --git a/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt b/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt
index b70f5654f2..c8d0f2beb1 100644
--- a/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt
+++ b/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt
@@ -63,6 +63,7 @@ class AuthDBTests : NodeBasedTest() {
private lateinit var client: CordaRPCClient
private lateinit var db: UsersDB
+ @Suppress("MemberVisibilityCanBePrivate")
@Parameterized.Parameter
lateinit var passwordEncryption: PasswordEncryption
@@ -110,7 +111,7 @@ class AuthDBTests : NodeBasedTest() {
)
node = startNode(ALICE_NAME, rpcUsers = emptyList(), configOverrides = securityConfig)
- client = CordaRPCClient(node.internals.configuration.rpcOptions.address!!)
+ client = CordaRPCClient(node.internals.configuration.rpcOptions.address)
}
@Test
@@ -243,9 +244,8 @@ private data class RoleAndPermissions(val role: String, val permissions: List = emptyList(), roleAndPermissions: List = emptyList()) : AutoCloseable {
+ val jdbcUrl = "jdbc:h2:mem:$name;DB_CLOSE_DELAY=-1"
companion object {
const val DB_CREATE_SCHEMA = """
@@ -295,11 +295,7 @@ private class UsersDB : AutoCloseable {
}
}
- constructor(name: String,
- users: List = emptyList(),
- roleAndPermissions: List = emptyList()) {
-
- jdbcUrl = "jdbc:h2:mem:$name;DB_CLOSE_DELAY=-1"
+ init {
dataSource = DataSourceFactory.createDataSource(Properties().apply {
put("dataSourceClassName", "org.h2.jdbcx.JdbcDataSource")
put("dataSource.url", jdbcUrl)
@@ -307,11 +303,9 @@ private class UsersDB : AutoCloseable {
session {
it.execute(DB_CREATE_SCHEMA)
}
-
require(users.map { it.username }.toSet().size == users.size) {
"Duplicate username in input"
}
-
users.forEach { insert(it) }
roleAndPermissions.forEach { insert(it) }
}
diff --git a/node/src/integration-test/kotlin/net/corda/node/services/MySQLNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/MySQLNotaryServiceTests.kt
index 63c72ca297..48113eed2a 100644
--- a/node/src/integration-test/kotlin/net/corda/node/services/MySQLNotaryServiceTests.kt
+++ b/node/src/integration-test/kotlin/net/corda/node/services/MySQLNotaryServiceTests.kt
@@ -257,7 +257,7 @@ class MySQLNotaryServiceTests : IntegrationTest() {
}
private fun createNotaryNode(): InternalMockNetwork.MockNode {
- val dataStoreProperties = makeTestDataSourceProperties(configSupplier = { _, _ -> ConfigFactory.empty() }, fallBackConfigSupplier = ::inMemoryH2DataSourceConfig).apply {
+ val dataStoreProperties = makeInternalTestDataSourceProperties(configSupplier = { ConfigFactory.empty() }).apply {
setProperty("autoCommit", "false")
}
return mockNet.createUnstartedNode(
diff --git a/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt b/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt
index 7235b6d0b3..4f08356c64 100644
--- a/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt
+++ b/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt
@@ -32,7 +32,6 @@ import net.corda.testing.internal.DEV_ROOT_CA
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.node.NotarySpec
-import net.corda.testing.node.internal.CompatibilityZoneParams
import net.corda.testing.node.internal.SharedCompatibilityZoneParams
import net.corda.testing.node.internal.internalDriver
import net.corda.testing.node.internal.network.NetworkMapServer
@@ -64,7 +63,6 @@ class NodeRegistrationTest : IntegrationTest() {
private val notaryName = CordaX500Name("NotaryService", "Zurich", "CH")
private val aliceName = CordaX500Name("Alice", "London", "GB")
private val genevieveName = CordaX500Name("Genevieve", "London", "GB")
- private val log = contextLogger()
}
@Rule
@@ -82,7 +80,7 @@ class NodeRegistrationTest : IntegrationTest() {
pollInterval = 1.seconds,
hostAndPort = portAllocation.nextHostAndPort(),
myHostNameValue = "localhost",
- additionalServices = registrationHandler)
+ additionalServices = *arrayOf(registrationHandler))
serverHostAndPort = server.start()
}
diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt
index 9e802d4342..b88068edde 100644
--- a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt
+++ b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt
@@ -78,7 +78,7 @@ class MQSecurityAsNodeTest : P2PMQSecurityTest() {
@Test
fun `login to a non ssl port as a node user`() {
- val attacker = clientTo(alice.internals.configuration.rpcOptions.address!!, sslConfiguration = null)
+ val attacker = clientTo(alice.internals.configuration.rpcOptions.address, sslConfiguration = null)
assertThatExceptionOfType(ActiveMQSecurityException::class.java).isThrownBy {
attacker.start(NODE_P2P_USER, NODE_P2P_USER, enableSSL = false)
}
@@ -86,7 +86,7 @@ class MQSecurityAsNodeTest : P2PMQSecurityTest() {
@Test
fun `login to a non ssl port as a peer user`() {
- val attacker = clientTo(alice.internals.configuration.rpcOptions.address!!, sslConfiguration = null)
+ val attacker = clientTo(alice.internals.configuration.rpcOptions.address, sslConfiguration = null)
assertThatExceptionOfType(ActiveMQSecurityException::class.java).isThrownBy {
attacker.start(PEER_USER, PEER_USER, enableSSL = false) // Login as a peer
}
diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsRPCTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsRPCTest.kt
index cdbfbed0c8..928591c53a 100644
--- a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsRPCTest.kt
+++ b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsRPCTest.kt
@@ -18,7 +18,7 @@ import org.junit.Test
*/
class MQSecurityAsRPCTest : RPCMQSecurityTest() {
override fun createAttacker(): SimpleMQClient {
- return clientTo(alice.internals.configuration.rpcOptions.address!!)
+ return clientTo(alice.internals.configuration.rpcOptions.address)
}
@Test
diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt
index c415e25208..eb5d18c562 100644
--- a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt
+++ b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt
@@ -41,6 +41,7 @@ import net.corda.testing.node.internal.NodeBasedTest
import net.corda.testing.node.internal.startFlow
import org.apache.activemq.artemis.api.core.ActiveMQNonExistentQueueException
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
+import org.apache.activemq.artemis.api.core.RoutingType
import org.apache.activemq.artemis.api.core.SimpleString
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.ClassRule
@@ -125,9 +126,9 @@ abstract class MQSecurityTest : NodeBasedTest() {
}
fun loginToRPCAndGetClientQueue(): String {
- loginToRPC(alice.internals.configuration.rpcOptions.address!!, rpcUser)
+ loginToRPC(alice.internals.configuration.rpcOptions.address, rpcUser)
val clientQueueQuery = SimpleString("${RPCApi.RPC_CLIENT_QUEUE_NAME_PREFIX}.${rpcUser.username}.*")
- val client = clientTo(alice.internals.configuration.rpcOptions.address!!)
+ val client = clientTo(alice.internals.configuration.rpcOptions.address)
client.start(rpcUser.username, rpcUser.password, false)
return client.session.addressQuery(clientQueueQuery).queueNames.single().toString()
}
@@ -140,7 +141,7 @@ abstract class MQSecurityTest : NodeBasedTest() {
fun assertTempQueueCreationAttackFails(queue: String) {
assertAttackFails(queue, "CREATE_NON_DURABLE_QUEUE") {
- attacker.session.createTemporaryQueue(queue, queue)
+ attacker.session.createTemporaryQueue(queue, RoutingType.MULTICAST, queue)
}
// Double-check
assertThatExceptionOfType(ActiveMQNonExistentQueueException::class.java).isThrownBy {
@@ -157,7 +158,7 @@ abstract class MQSecurityTest : NodeBasedTest() {
fun assertNonTempQueueCreationAttackFails(queue: String, durable: Boolean) {
val permission = if (durable) "CREATE_DURABLE_QUEUE" else "CREATE_NON_DURABLE_QUEUE"
assertAttackFails(queue, permission) {
- attacker.session.createQueue(queue, queue, durable)
+ attacker.session.createQueue(queue, RoutingType.MULTICAST, queue, durable)
}
// Double-check
assertThatExceptionOfType(ActiveMQNonExistentQueueException::class.java).isThrownBy {
diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt
index 622976d72a..72d0ac9ef7 100644
--- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt
+++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt
@@ -14,11 +14,10 @@ import com.typesafe.config.Config
import com.typesafe.config.ConfigException
import net.corda.core.context.AuthServiceId
import net.corda.core.identity.CordaX500Name
-import net.corda.core.internal.div
+import net.corda.core.internal.TimedFlow
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.seconds
-import net.corda.node.internal.artemis.CertificateChainCheckPolicy
import net.corda.node.services.config.rpc.NodeRpcOptions
import net.corda.nodeapi.BrokerRpcSslOptions
import net.corda.nodeapi.internal.config.NodeSSLConfiguration
@@ -51,6 +50,7 @@ interface NodeConfiguration : NodeSSLConfiguration {
val devModeOptions: DevModeOptions?
val compatibilityZoneURL: URL?
val networkServices: NetworkServicesConfig?
+ @Suppress("DEPRECATION")
val certificateChainCheckPolicies: List
val verifierType: VerifierType
val flowTimeout: FlowTimeoutConfiguration
@@ -237,6 +237,7 @@ data class NodeConfigurationImpl(
override val messagingServerExternal: Boolean = (messagingServerAddress != null),
override val enterpriseConfiguration: EnterpriseConfiguration,
override val notary: NotaryConfig?,
+ @Suppress("DEPRECATION")
@Deprecated("Do not configure")
override val certificateChainCheckPolicies: List = emptyList(),
override val devMode: Boolean = false,
@@ -413,6 +414,7 @@ data class NodeConfigurationImpl(
}
// Check for usage of deprecated config
+ @Suppress("DEPRECATION")
if(certificateChainCheckPolicies.isNotEmpty()) {
logger.warn("""You are configuring certificateChainCheckPolicies. This is a setting that is not used, and will be removed in a future version.
|Please contact the R3 team on the public slack to discuss your use case.
@@ -467,18 +469,7 @@ enum class CertChainPolicyType {
}
@Deprecated("Do not use")
-data class CertChainPolicyConfig(val role: String, private val policy: CertChainPolicyType, private val trustedAliases: Set) {
- val certificateChainCheckPolicy: CertificateChainCheckPolicy
- get() {
- return when (policy) {
- CertChainPolicyType.Any -> CertificateChainCheckPolicy.Any
- CertChainPolicyType.RootMustMatch -> CertificateChainCheckPolicy.RootMustMatch
- CertChainPolicyType.LeafMustMatch -> CertificateChainCheckPolicy.LeafMustMatch
- CertChainPolicyType.MustContainOneOf -> CertificateChainCheckPolicy.MustContainOneOf(trustedAliases)
- CertChainPolicyType.UsernameMustMatch -> CertificateChainCheckPolicy.UsernameMustMatchCommonName
- }
- }
-}
+data class CertChainPolicyConfig(val role: String, private val policy: CertChainPolicyType, private val trustedAliases: Set)
// Supported types of authentication/authorization data providers
enum class AuthDataSourceType {
@@ -515,8 +506,6 @@ data class SecurityConfiguration(val authService: SecurityConfiguration.AuthServ
}
}
- fun copyWithAdditionalUser(user: User) = AuthService(dataSource.copyWithAdditionalUser(user), id, options)
-
// Optional components: cache
data class Options(val cache: Options.Cache?) {
@@ -544,12 +533,6 @@ data class SecurityConfiguration(val authService: SecurityConfiguration.AuthServ
AuthDataSourceType.DB -> require(users == null && connection != null)
}
}
-
- fun copyWithAdditionalUser(user: User): DataSource {
- val extendedList = this.users?.toMutableList() ?: mutableListOf()
- extendedList.add(user)
- return DataSource(this.type, this.passwordEncryption, this.connection, listOf(*extendedList.toTypedArray()))
- }
}
companion object {
diff --git a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt
index 942638dc40..fdff52392a 100644
--- a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt
+++ b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt
@@ -34,7 +34,7 @@ import javax.annotation.concurrent.ThreadSafe
*/
// TODO There is duplicated logic between this and PersistentIdentityService
@ThreadSafe
-class InMemoryIdentityService(identities: List = emptyList(),
+class InMemoryIdentityService(identities: List = emptyList(),
override val trustRoot: X509Certificate) : SingletonSerializeAsToken(), IdentityService {
companion object {
private val log = contextLogger()
diff --git a/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt b/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt
index cea86aac2c..2d86992bf7 100644
--- a/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt
+++ b/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt
@@ -63,7 +63,7 @@ class E2ETestKeyManagementService(val identityService: IdentityService,
}
override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate {
- return freshCertificate(identityService, freshKey(), identity, getSigner(identity.owningKey), revocationEnabled)
+ return freshCertificate(identityService, freshKey(), identity, getSigner(identity.owningKey))
}
private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey))
diff --git a/node/src/main/kotlin/net/corda/node/services/keys/KMSUtils.kt b/node/src/main/kotlin/net/corda/node/services/keys/KMSUtils.kt
index 8ec7cebf4d..350ad4ee05 100644
--- a/node/src/main/kotlin/net/corda/node/services/keys/KMSUtils.kt
+++ b/node/src/main/kotlin/net/corda/node/services/keys/KMSUtils.kt
@@ -40,8 +40,7 @@ import java.time.Duration
fun freshCertificate(identityService: IdentityService,
subjectPublicKey: PublicKey,
issuer: PartyAndCertificate,
- issuerSigner: ContentSigner,
- revocationEnabled: Boolean = false): PartyAndCertificate {
+ issuerSigner: ContentSigner): PartyAndCertificate {
val issuerRole = CertRole.extract(issuer.certificate)
require(issuerRole == CertRole.LEGAL_IDENTITY) { "Confidential identities can only be issued from well known identities, provided issuer ${issuer.name} has role $issuerRole" }
val issuerCert = issuer.certificate
diff --git a/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt b/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt
index a39ff6140b..c569c71f3b 100644
--- a/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt
+++ b/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt
@@ -98,8 +98,9 @@ class PersistentKeyManagementService(val identityService: IdentityService,
return keyPair.public
}
- override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate =
- freshCertificate(identityService, freshKey(), identity, getSigner(identity.owningKey), revocationEnabled)
+ override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate {
+ return freshCertificate(identityService, freshKey(), identity, getSigner(identity.owningKey))
+ }
private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey))
diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/RunOnceService.kt b/node/src/main/kotlin/net/corda/node/services/persistence/RunOnceService.kt
index ab1ca72da1..f91d6d9191 100644
--- a/node/src/main/kotlin/net/corda/node/services/persistence/RunOnceService.kt
+++ b/node/src/main/kotlin/net/corda/node/services/persistence/RunOnceService.kt
@@ -16,6 +16,7 @@ import net.corda.node.utilities.AffinityExecutor
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import org.hibernate.Session
+import org.hibernate.query.NativeQuery
import java.io.Serializable
import java.sql.SQLTransientConnectionException
import java.time.Duration
@@ -132,7 +133,7 @@ class RunOnceService(private val database: CordaPersistence, private val machine
private fun insertMutualExclusion(session: Session) {
val query = session.createNativeQuery("INSERT INTO $TABLE VALUES ('X', :machineName, :pid, CURRENT_TIMESTAMP, :version)", MutualExclusion::class.java)
- query.unwrap(org.hibernate.SQLQuery::class.java).addSynchronizedEntityClass(MutualExclusion::class.java)
+ query.unwrap(NativeQuery::class.java).addSynchronizedEntityClass(MutualExclusion::class.java)
query.setParameter("pid", pid)
query.setParameter("machineName", machineName)
query.setParameter("version", 0)
diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/MultiThreadedStateMachineManager.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/MultiThreadedStateMachineManager.kt
index 2d3816fc8c..a3ab52e4e8 100644
--- a/node/src/main/kotlin/net/corda/node/services/statemachine/MultiThreadedStateMachineManager.kt
+++ b/node/src/main/kotlin/net/corda/node/services/statemachine/MultiThreadedStateMachineManager.kt
@@ -70,7 +70,7 @@ class MultiThreadedStateMachineManager(
val checkpointStorage: CheckpointStorage,
val executor: ExecutorService,
val database: CordaPersistence,
- val secureRandom: SecureRandom,
+ private val secureRandom: SecureRandom,
private val unfinishedFibers: ReusableLatch = ReusableLatch(),
private val classloader: ClassLoader = MultiThreadedStateMachineManager::class.java.classLoader
) : StateMachineManager, StateMachineManagerInternal {
@@ -158,7 +158,7 @@ class MultiThreadedStateMachineManager(
}
serviceHub.networkMapCache.nodeReady.then {
resumeRestoredFlows(fibers)
- flowMessaging.start { receivedMessage, deduplicationHandler ->
+ flowMessaging.start { _, deduplicationHandler ->
lifeCycle.requireState(State.STARTED, StateMachineStoppedException("Flow cannot be started. State machine is stopped.")) {
deliverExternalEvent(deduplicationHandler.externalCause)
}
@@ -306,10 +306,10 @@ class MultiThreadedStateMachineManager(
}
private fun checkQuasarJavaAgentPresence() {
- check(SuspendableHelper.isJavaAgentActive(), {
+ check(SuspendableHelper.isJavaAgentActive()) {
"""Missing the '-javaagent' JVM argument. Make sure you run the tests with the Quasar java agent attached to your JVM.
#See https://docs.corda.net/troubleshooting.html - 'Fiber classes not instrumented' for more details.""".trimMargin("#")
- })
+ }
}
private fun decrementLiveFibers() {
@@ -324,8 +324,7 @@ class MultiThreadedStateMachineManager(
return checkpointStorage.getAllCheckpoints().map { (id, serializedCheckpoint) ->
// If a flow is added before start() then don't attempt to restore it
if (concurrentBox.content.flows.containsKey(id)) return@map null
- val checkpoint = deserializeCheckpoint(serializedCheckpoint)
- if (checkpoint == null) return@map null
+ val checkpoint = deserializeCheckpoint(serializedCheckpoint) ?: return@map null
createFlowFromCheckpoint(
id = id,
checkpoint = checkpoint,
@@ -440,7 +439,7 @@ class MultiThreadedStateMachineManager(
val flowId = sessionToFlow[recipientId]
if (flowId == null) {
deduplicationHandler.afterDatabaseTransaction()
- if (sessionMessage.payload is EndSessionMessage) {
+ if (sessionMessage.payload === EndSessionMessage) {
logger.debug {
"Got ${EndSessionMessage::class.java.simpleName} for " +
"unknown session $recipientId, discarding..."
@@ -537,12 +536,6 @@ class MultiThreadedStateMachineManager(
isStartIdempotent: Boolean
): CordaFuture> {
val flowId = StateMachineRunId.createRandom()
- val deduplicationSeed = when (flowStart) {
- FlowStart.Explicit -> flowId.uuid.toString()
- is FlowStart.Initiated ->
- "${flowStart.initiatingMessage.initiatorSessionId.toLong}-" +
- "${flowStart.initiatingMessage.initiationEntropy}"
- }
// Before we construct the state machine state by freezing the FlowLogic we need to make sure that lazy properties
// have access to the fiber (and thereby the service hub)
@@ -553,7 +546,7 @@ class MultiThreadedStateMachineManager(
val frozenFlowLogic = (flowLogic as FlowLogic<*>).serialize(context = checkpointSerializationContext!!)
val flowCorDappVersion = FlowStateMachineImpl.createSubFlowVersion(serviceHub.cordappProvider.getCordappForFlow(flowLogic), serviceHub.myInfo.platformVersion)
- val initialCheckpoint = Checkpoint.create(invocationContext, flowStart, flowLogic.javaClass, frozenFlowLogic, ourIdentity, deduplicationSeed, flowCorDappVersion).getOrThrow()
+ val initialCheckpoint = Checkpoint.create(invocationContext, flowStart, flowLogic.javaClass, frozenFlowLogic, ourIdentity, flowCorDappVersion).getOrThrow()
val startedFuture = openFuture()
val initialState = StateMachineState(
checkpoint = initialCheckpoint,
@@ -721,7 +714,7 @@ class MultiThreadedStateMachineManager(
private fun addAndStartFlow(id: StateMachineRunId, flow: Flow) {
val checkpoint = flow.fiber.snapshot().checkpoint
for (sessionId in getFlowSessionIds(checkpoint)) {
- sessionToFlow.put(sessionId, id)
+ sessionToFlow[sessionId] = id
}
concurrentBox.concurrent {
val oldFlow = flows.put(id, flow)
diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt
index ca4c67da37..cc63a6c809 100644
--- a/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt
+++ b/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt
@@ -66,10 +66,10 @@ import kotlin.streams.toList
@ThreadSafe
class SingleThreadedStateMachineManager(
val serviceHub: ServiceHubInternal,
- val checkpointStorage: CheckpointStorage,
+ private val checkpointStorage: CheckpointStorage,
val executor: ExecutorService,
val database: CordaPersistence,
- val secureRandom: SecureRandom,
+ private val secureRandom: SecureRandom,
private val unfinishedFibers: ReusableLatch = ReusableLatch(),
private val classloader: ClassLoader = SingleThreadedStateMachineManager::class.java.classLoader
) : StateMachineManager, StateMachineManagerInternal {
@@ -145,7 +145,7 @@ class SingleThreadedStateMachineManager(
}
serviceHub.networkMapCache.nodeReady.then {
resumeRestoredFlows(fibers)
- flowMessaging.start { receivedMessage, deduplicationHandler ->
+ flowMessaging.start { _, deduplicationHandler ->
executor.execute {
deliverExternalEvent(deduplicationHandler.externalCause)
}
@@ -296,10 +296,10 @@ class SingleThreadedStateMachineManager(
}
private fun checkQuasarJavaAgentPresence() {
- check(SuspendableHelper.isJavaAgentActive(), {
+ check(SuspendableHelper.isJavaAgentActive()) {
"""Missing the '-javaagent' JVM argument. Make sure you run the tests with the Quasar java agent attached to your JVM.
#See https://docs.corda.net/troubleshooting.html - 'Fiber classes not instrumented' for more details.""".trimMargin("#")
- })
+ }
}
private fun decrementLiveFibers() {
@@ -314,8 +314,7 @@ class SingleThreadedStateMachineManager(
return checkpointStorage.getAllCheckpoints().map { (id, serializedCheckpoint) ->
// If a flow is added before start() then don't attempt to restore it
mutex.locked { if (flows.containsKey(id)) return@map null }
- val checkpoint = deserializeCheckpoint(serializedCheckpoint)
- if (checkpoint == null) return@map null
+ val checkpoint = deserializeCheckpoint(serializedCheckpoint) ?: return@map null
logger.debug { "Restored $checkpoint" }
createFlowFromCheckpoint(
id = id,
@@ -534,12 +533,6 @@ class SingleThreadedStateMachineManager(
isStartIdempotent: Boolean
): CordaFuture> {
val flowId = StateMachineRunId.createRandom()
- val deduplicationSeed = when (flowStart) {
- FlowStart.Explicit -> flowId.uuid.toString()
- is FlowStart.Initiated ->
- "${flowStart.initiatingMessage.initiatorSessionId.toLong}-" +
- "${flowStart.initiatingMessage.initiationEntropy}"
- }
// Before we construct the state machine state by freezing the FlowLogic we need to make sure that lazy properties
// have access to the fiber (and thereby the service hub)
@@ -551,7 +544,7 @@ class SingleThreadedStateMachineManager(
val flowCorDappVersion = createSubFlowVersion(serviceHub.cordappProvider.getCordappForFlow(flowLogic), serviceHub.myInfo.platformVersion)
- val initialCheckpoint = Checkpoint.create(invocationContext, flowStart, flowLogic.javaClass, frozenFlowLogic, ourIdentity, deduplicationSeed, flowCorDappVersion).getOrThrow()
+ val initialCheckpoint = Checkpoint.create(invocationContext, flowStart, flowLogic.javaClass, frozenFlowLogic, ourIdentity, flowCorDappVersion).getOrThrow()
val startedFuture = openFuture()
val initialState = StateMachineState(
checkpoint = initialCheckpoint,
diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/StaffedFlowHospital.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/StaffedFlowHospital.kt
index 2779cee916..75493c1cfb 100644
--- a/node/src/main/kotlin/net/corda/node/services/statemachine/StaffedFlowHospital.kt
+++ b/node/src/main/kotlin/net/corda/node/services/statemachine/StaffedFlowHospital.kt
@@ -2,6 +2,7 @@ package net.corda.node.services.statemachine
import net.corda.core.flows.StateMachineRunId
import net.corda.core.internal.ThreadBox
+import net.corda.core.internal.TimedFlow
import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.messaging.DataFeed
import net.corda.core.utilities.contextLogger
@@ -100,12 +101,6 @@ class StaffedFlowHospital {
private data class ConsultationReport(val error: Throwable, val diagnosis: Diagnosis, val by: List)
- /**
- * The flow running in [flowFiber] has cleaned, possibly as a result of a flow hospital resume.
- */
- // It's okay for flows to be cleaned... we fix them now!
- fun flowCleaned(flowFiber: FlowFiber) = Unit
-
/**
* The flow has been removed from the state machine.
*/
diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineState.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineState.kt
index 64337624a6..fa2ebc9285 100644
--- a/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineState.kt
+++ b/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineState.kt
@@ -79,7 +79,6 @@ data class Checkpoint(
flowLogicClass: Class>,
frozenFlowLogic: SerializedBytes>,
ourIdentity: Party,
- deduplicationSeed: String,
subFlowVersion: SubFlowVersion
): Try {
return SubFlow.create(flowLogicClass, subFlowVersion).map { topLevelSubFlow ->
diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/interceptors/HospitalisingInterceptor.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/interceptors/HospitalisingInterceptor.kt
index a94c865440..f2389f1570 100644
--- a/node/src/main/kotlin/net/corda/node/services/statemachine/interceptors/HospitalisingInterceptor.kt
+++ b/node/src/main/kotlin/net/corda/node/services/statemachine/interceptors/HospitalisingInterceptor.kt
@@ -55,9 +55,7 @@ class HospitalisingInterceptor(
when (nextState.checkpoint.errorState) {
is ErrorState.Clean -> {
- if (hospitalisedFlows.remove(fiber.id) != null) {
- flowHospital.flowCleaned(fiber)
- }
+ hospitalisedFlows.remove(fiber.id)
}
is ErrorState.Errored -> {
val exceptionsToHandle = nextState.checkpoint.errorState.errors.map { it.exception }
diff --git a/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt b/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt
index 58912b3638..e0dff1589b 100644
--- a/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt
+++ b/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt
@@ -86,7 +86,7 @@ abstract class AppendOnlyPersistentMapBase(
Transactional.Committed(value)
} else {
// Some database transactions, including us, writing, with readers seeing whatever is in the database and writers seeing the (in memory) value.
- Transactional.InFlight(this, key, { loadValue(key) }).apply { alsoWrite(value) }
+ Transactional.InFlight(this, key, _readerValueLoader = { loadValue(key) }).apply { alsoWrite(value) }
}
}
@@ -156,13 +156,13 @@ abstract class AppendOnlyPersistentMapBase(
}
// Helpers to know if transaction(s) are currently writing the given key.
- protected fun weAreWriting(key: K): Boolean = pendingKeys.get(key)?.contains(contextTransaction) ?: false
- protected fun anyoneWriting(key: K): Boolean = pendingKeys.get(key)?.isNotEmpty() ?: false
+ protected fun weAreWriting(key: K): Boolean = pendingKeys[key]?.contains(contextTransaction) ?: false
+ protected fun anyoneWriting(key: K): Boolean = pendingKeys[key]?.isNotEmpty() ?: false
// Indicate this database transaction is a writer of this key.
private fun addPendingKey(key: K, databaseTransaction: DatabaseTransaction): Boolean {
var added = true
- pendingKeys.compute(key) { k, oldSet ->
+ pendingKeys.compute(key) { _, oldSet ->
if (oldSet == null) {
val newSet = HashSet(0)
newSet += databaseTransaction
@@ -177,7 +177,7 @@ abstract class AppendOnlyPersistentMapBase(
// Remove this database transaction as a writer of this key, because the transaction committed or rolled back.
private fun removePendingKey(key: K, databaseTransaction: DatabaseTransaction) {
- pendingKeys.compute(key) { k, oldSet ->
+ pendingKeys.compute(key) { _, oldSet ->
if (oldSet == null) {
oldSet
} else {
@@ -209,7 +209,7 @@ abstract class AppendOnlyPersistentMapBase(
}
// No one can see it.
- class Missing() : Transactional() {
+ class Missing : Transactional() {
override val value: T
get() = throw NoSuchElementException("Not present")
override val isPresent: Boolean
@@ -238,7 +238,7 @@ abstract class AppendOnlyPersistentMapBase(
fun alsoWrite(_value: T) {
// Make the lazy loader the writers see actually just return the value that has been set.
- writerValueLoader.set({ _value })
+ writerValueLoader.set { _value }
// We make all these vals so that the lambdas do not need a reference to this, and so the onCommit only has a weak ref to the value.
// We want this so that the cache could evict the value (due to memory constraints etc) without the onCommit callback
// retaining what could be a large memory footprint object.
@@ -252,10 +252,9 @@ abstract class AppendOnlyPersistentMapBase(
// and then stop saying the transaction is writing the key.
tx.onCommit {
if (strongComitted.compareAndSet(false, true)) {
- val dereferencedKey = strongKey
val dereferencedValue = weakValue.get()
if (dereferencedValue != null) {
- strongMap.cache.put(dereferencedKey, Committed(dereferencedValue))
+ strongMap.cache.put(strongKey, Committed(dereferencedValue))
}
}
strongMap.removePendingKey(strongKey, tx)
@@ -272,7 +271,7 @@ abstract class AppendOnlyPersistentMapBase(
private fun loadAsWriter(): T {
val _value = writerValueLoader.get()()
if (writerValueLoader.get() == _writerValueLoader) {
- writerValueLoader.set({ _value })
+ writerValueLoader.set { _value }
}
return _value
}
@@ -282,7 +281,7 @@ abstract class AppendOnlyPersistentMapBase(
private fun loadAsReader(): T? {
val _value = readerValueLoader.get()()
if (readerValueLoader.get() == _readerValueLoader) {
- readerValueLoader.set({ _value })
+ readerValueLoader.set { _value }
}
return _value
}
@@ -320,7 +319,7 @@ open class AppendOnlyPersistentMap(
toPersistentEntity,
persistentEntityClass) {
//TODO determine cacheBound based on entity class later or with node config allowing tuning, or using some heuristic based on heap size
- override val cache = NonInvalidatingCache>(
+ override val cache = NonInvalidatingCache(
bound = cacheBound,
loadFunction = { key: K ->
// This gets called if a value is read and the cache has no Transactional for this key yet.
@@ -331,10 +330,10 @@ open class AppendOnlyPersistentMap(
// If someone is writing (but not us)
// For those not writing, the value cannot be seen.
// For those writing, they need to re-load the value from the database (which their database transaction CAN see).
- Transactional.InFlight(this, key, { null }, { loadValue(key)!! })
+ Transactional.InFlight(this, key, { null }, { loadValue(key)!! })
} else {
// If no one is writing, then the value does not exist.
- Transactional.Missing()
+ Transactional.Missing()
}
} else {
// A value was found
@@ -342,10 +341,10 @@ open class AppendOnlyPersistentMap(
// If we are writing, it might not be globally visible, and was evicted from the cache.
// For those not writing, they need to check the database again.
// For those writing, they can see the value found.
- Transactional.InFlight(this, key, { loadValue(key) }, { value })
+ Transactional.InFlight(this, key, { loadValue(key) }, { value })
} else {
// If no one is writing, then make it globally visible.
- Transactional.Committed(value)
+ Transactional.Committed(value)
}
}
})
@@ -364,26 +363,22 @@ class WeightBasedAppendOnlyPersistentMap(
fromPersistentEntity,
toPersistentEntity,
persistentEntityClass) {
- override val cache = NonInvalidatingWeightBasedCache>(
+ override val cache = NonInvalidatingWeightBasedCache(
maxWeight = maxWeight,
- weigher = object : Weigher> {
- override fun weigh(key: K, value: Transactional): Int {
- return weighingFunc(key, value)
- }
- },
+ weigher = Weigher { key, value -> weighingFunc(key, value) },
loadFunction = { key: K ->
val value: V? = loadValue(key)
if (value == null) {
if (anyoneWriting(key)) {
- Transactional.InFlight(this, key, { null }, { loadValue(key)!! })
+ Transactional.InFlight(this, key, { null }, { loadValue(key)!! })
} else {
- Transactional.Missing()
+ Transactional.Missing()
}
} else {
if (weAreWriting(key)) {
- Transactional.InFlight(this, key, { loadValue(key) }, { value })
+ Transactional.InFlight(this, key, { loadValue(key) }, { value })
} else {
- Transactional.Committed(value)
+ Transactional.Committed(value)
}
}
})
diff --git a/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java b/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java
index 042c935fee..7fa27bdbc3 100644
--- a/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java
+++ b/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java
@@ -46,9 +46,6 @@ import org.junit.Rule;
import org.junit.Test;
import rx.Observable;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.cert.CertificateException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -80,7 +77,7 @@ public class VaultQueryJavaTests {
private CordaPersistence database;
@Before
- public void setUp() throws CertificateException, InvalidAlgorithmParameterException {
+ public void setUp() {
List cordappPackages = asList(
"net.corda.testing.internal.vault",
"net.corda.finance.contracts.asset",
@@ -101,14 +98,10 @@ public class VaultQueryJavaTests {
}
@After
- public void cleanUp() throws IOException {
+ public void cleanUp() {
database.close();
}
- /**
- * Sample Vault Query API tests
- */
-
/**
* Static queryBy() tests
*/
@@ -119,6 +112,7 @@ public class VaultQueryJavaTests {
FieldInfo currency = getField("currency", SampleCashSchemaV2.PersistentCashState.class);
CriteriaExpression.AggregateFunctionExpression