Enabled warnings as errors (#3514)

This commit is contained in:
Shams Asari 2018-07-04 17:17:27 +01:00 committed by GitHub
parent 68d0826563
commit 244167d3e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 349 additions and 441 deletions

2
.idea/compiler.xml generated
View File

@ -127,6 +127,8 @@
<module name="mock_test" target="1.8" /> <module name="mock_test" target="1.8" />
<module name="network-bootstrapper_main" target="1.8" /> <module name="network-bootstrapper_main" target="1.8" />
<module name="network-bootstrapper_test" target="1.8" /> <module name="network-bootstrapper_test" target="1.8" />
<module name="network-verifier_main" target="1.8" />
<module name="network-verifier_test" target="1.8" />
<module name="network-visualiser_main" target="1.8" /> <module name="network-visualiser_main" target="1.8" />
<module name="network-visualiser_test" target="1.8" /> <module name="network-visualiser_test" target="1.8" />
<module name="node-api_main" target="1.8" /> <module name="node-api_main" target="1.8" />

View File

@ -172,6 +172,7 @@ allprojects {
jvmTarget = "1.8" jvmTarget = "1.8"
javaParameters = true // Useful for reflection. javaParameters = true // Useful for reflection.
freeCompilerArgs = ['-Xjvm-default=compatibility'] freeCompilerArgs = ['-Xjvm-default=compatibility']
allWarningsAsErrors = true
} }
} }

View File

@ -3,7 +3,6 @@ package net.corda.client.jfx
import net.corda.client.jfx.model.NodeMonitorModel import net.corda.client.jfx.model.NodeMonitorModel
import net.corda.client.jfx.model.ProgressTrackingEvent import net.corda.client.jfx.model.ProgressTrackingEvent
import net.corda.core.context.InvocationOrigin import net.corda.core.context.InvocationOrigin
import net.corda.core.contracts.Amount
import net.corda.core.contracts.ContractState import net.corda.core.contracts.ContractState
import net.corda.core.crypto.isFulfilledBy import net.corda.core.crypto.isFulfilledBy
import net.corda.core.crypto.keys import net.corda.core.crypto.keys
@ -22,12 +21,9 @@ import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS 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.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.all
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.* import net.corda.testing.core.*
import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
@ -54,18 +50,7 @@ class NodeMonitorModelTest {
private fun setup(runTest: () -> Unit) { private fun setup(runTest: () -> Unit) {
driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"))) { driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"))) {
val cashUser = User("user1", "test", permissions = setOf( val cashUser = User("user1", "test", permissions = setOf(all()))
startFlow<CashIssueFlow>(),
startFlow<CashPaymentFlow>(),
startFlow<CashExitFlow>(),
invokeRpc(CordaRPCOps::notaryIdentities),
invokeRpc("vaultTrackBy"),
invokeRpc("vaultQueryBy"),
invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed),
invokeRpc(CordaRPCOps::stateMachineRecordedTransactionMappingFeed),
invokeRpc(CordaRPCOps::stateMachinesFeed),
invokeRpc(CordaRPCOps::networkMapFeed))
)
val aliceNodeHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(cashUser)).getOrThrow() val aliceNodeHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(cashUser)).getOrThrow()
aliceNode = aliceNodeHandle.nodeInfo aliceNode = aliceNodeHandle.nodeInfo
newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo } newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
@ -114,11 +99,7 @@ class NodeMonitorModelTest {
@Test @Test
fun `cash issue works end to end`() = setup { fun `cash issue works end to end`() = setup {
rpc.startFlow(::CashIssueFlow, rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryParty)
Amount(100, USD),
OpaqueBytes(ByteArray(1, { 1 })),
notaryParty
)
vaultUpdates.expectEvents(isStrict = false) { vaultUpdates.expectEvents(isStrict = false) {
sequence( sequence(

View File

@ -101,12 +101,12 @@ class NodeMonitorModel : AutoCloseable {
* TODO provide an unsubscribe mechanism * TODO provide an unsubscribe mechanism
*/ */
fun register(nodeHostAndPort: NetworkHostAndPort, username: String, password: String) { fun register(nodeHostAndPort: NetworkHostAndPort, username: String, password: String) {
// `retryableStateMachineUpdatesSubject` will change it's upstream subscriber in case of RPC connection failure, this `Observable` should // `retryableStateMachineUpdatesSubject` will change it's upstream subscriber in case of RPC connection failure, this `Observable` should
// never produce an error. // never produce an error.
// `stateMachineUpdatesSubject` will stay firmly subscribed to `retryableStateMachineUpdatesSubject` // `stateMachineUpdatesSubject` will stay firmly subscribed to `retryableStateMachineUpdatesSubject`
retryableStateMachineUpdatesSubject.subscribe(stateMachineUpdatesSubject) retryableStateMachineUpdatesSubject.subscribe(stateMachineUpdatesSubject)
@Suppress("DEPRECATION")
// Proxy may change during re-connect, ensure that subject wiring accurately reacts to this activity. // Proxy may change during re-connect, ensure that subject wiring accurately reacts to this activity.
proxyObservable.addListener { _, _, wrapper -> proxyObservable.addListener { _, _, wrapper ->
if (wrapper != null) { if (wrapper != null) {

View File

@ -48,7 +48,7 @@ data class PartiallyResolvedTransaction(
return PartiallyResolvedTransaction( return PartiallyResolvedTransaction(
transaction = transaction, transaction = transaction,
inputs = transaction.inputs.map { stateRef -> inputs = transaction.inputs.map { stateRef ->
val tx = inputTransactions.get(stateRef) val tx = inputTransactions[stateRef]
if (tx == null) { if (tx == null) {
InputResolution.Unresolved(stateRef) InputResolution.Unresolved(stateRef)
} else { } else {
@ -64,7 +64,7 @@ data class PartiallyResolvedTransaction(
val outputCount = transaction.coreTransaction.inputs.size val outputCount = transaction.coreTransaction.inputs.size
val stateRefs = (0 until outputCount).map { StateRef(transaction.id, it) } val stateRefs = (0 until outputCount).map { StateRef(transaction.id, it) }
stateRefs.map { stateRef -> stateRefs.map { stateRef ->
val tx = inputTransactions.get(stateRef) val tx = inputTransactions[stateRef]
if (tx == null) { if (tx == null) {
OutputResolution.Unresolved(stateRef) OutputResolution.Unresolved(stateRef)
} else { } else {
@ -84,6 +84,7 @@ class TransactionDataModel {
private val collectedTransactions = transactions.recordInSequence().distinctBy { it.id } private val collectedTransactions = transactions.recordInSequence().distinctBy { it.id }
private val rpcProxy by observableValue(NodeMonitorModel::proxyObservable) private val rpcProxy by observableValue(NodeMonitorModel::proxyObservable)
@Suppress("DEPRECATION")
val partiallyResolvedTransactions = collectedTransactions.map { val partiallyResolvedTransactions = collectedTransactions.map {
PartiallyResolvedTransaction.fromSignedTransaction(it, PartiallyResolvedTransaction.fromSignedTransaction(it,
it.inputs.map { stateRef -> it.inputs.map { stateRef ->

View File

@ -54,14 +54,12 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
@Before @Before
fun setup() { fun setup() {
node = startNode(ALICE_NAME, rpcUsers = listOf(rpcUser)) node = startNode(ALICE_NAME, rpcUsers = listOf(rpcUser))
client = CordaRPCClient(node.internals.configuration.rpcOptions.address!!) client = CordaRPCClient(node.internals.configuration.rpcOptions.address)
} }
@Test @Test
fun `flows draining mode can be enabled and queried`() { fun `flows draining mode can be enabled and queried`() {
asALoggerUser { rpcOps -> asALoggerUser { rpcOps ->
val newValue = true val newValue = true
rpcOps.setFlowsDrainingModeEnabled(true) rpcOps.setFlowsDrainingModeEnabled(true)
@ -74,7 +72,6 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
@Test @Test
fun `flows draining mode can be disabled and queried`() { fun `flows draining mode can be disabled and queried`() {
asALoggerUser { rpcOps -> asALoggerUser { rpcOps ->
rpcOps.setFlowsDrainingModeEnabled(true) rpcOps.setFlowsDrainingModeEnabled(true)
val newValue = false val newValue = false
@ -88,7 +85,6 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
@Test @Test
fun `node starts with flows draining mode disabled`() { fun `node starts with flows draining mode disabled`() {
asALoggerUser { rpcOps -> asALoggerUser { rpcOps ->
val defaultStartingMode = rpcOps.isFlowsDrainingModeEnabled() val defaultStartingMode = rpcOps.isFlowsDrainingModeEnabled()
@ -97,14 +93,12 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract
} }
private fun login(username: String, password: String, externalTrace: Trace? = null, impersonatedActor: Actor? = null): CordaRPCConnection { private fun login(username: String, password: String, externalTrace: Trace? = null, impersonatedActor: Actor? = null): CordaRPCConnection {
return client.start(username, password, externalTrace, impersonatedActor) return client.start(username, password, externalTrace, impersonatedActor)
} }
private fun asALoggerUser(action: (CordaRPCOps) -> Unit) { private fun asALoggerUser(action: (CordaRPCOps) -> Unit) {
login(rpcUser.username, rpcUser.password).use { login(rpcUser.username, rpcUser.password).use {
action(it.proxy) action(it.proxy)
} }
} }
} }

View File

@ -2,11 +2,15 @@ package net.corda.core.node.services
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.DoNotImplement import net.corda.core.DoNotImplement
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.SignableData import net.corda.core.crypto.SignableData
import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.TransactionSignature
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey 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, * The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example,

View File

@ -122,7 +122,7 @@ object MappedSchemaValidator {
fieldsFromOtherMappedSchema(schema) + methodsFromOtherMappedSchema(schema) fieldsFromOtherMappedSchema(schema) + methodsFromOtherMappedSchema(schema)
/** Returns true if [javax.persistence] annotation expect [javax.persistence.Transient] is found. */ /** Returns true if [javax.persistence] annotation expect [javax.persistence.Transient] is found. */
private inline fun hasJpaAnnotation(annotations: Array<Annotation>) = private fun hasJpaAnnotation(annotations: Array<Annotation>) =
annotations.any { annotation -> annotation.toString().startsWith("@javax.persistence.") && annotation !is javax.persistence.Transient } 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, class SchemaCrossReferenceReport(private val schema: String, private val entity: String, private val referencedSchema: String,

View File

@ -48,7 +48,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
@DeleteForDJVM @DeleteForDJVM
constructor(componentGroups: List<ComponentGroup>) : this(componentGroups, PrivacySalt()) constructor(componentGroups: List<ComponentGroup>) : this(componentGroups, PrivacySalt())
@Deprecated("Required only in some unit-tests and for backwards compatibility purposes.", ReplaceWith("WireTransaction(val componentGroups: List<ComponentGroup>, override val privacySalt: PrivacySalt)"), DeprecationLevel.WARNING) @Deprecated("Required only for backwards compatibility purposes.", ReplaceWith("WireTransaction(val componentGroups: List<ComponentGroup>, override val privacySalt: PrivacySalt)"), DeprecationLevel.WARNING)
@DeleteForDJVM @DeleteForDJVM
constructor(inputs: List<StateRef>, constructor(inputs: List<StateRef>,
attachments: List<SecureHash>, attachments: List<SecureHash>,

View File

@ -31,7 +31,8 @@ class ContractsDSLTests {
} }
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class RequireSingleCommandTests(private val testFunction: (Collection<CommandWithParties<CommandData>>) -> CommandWithParties<CommandData>, description: String) { class RequireSingleCommandTests(private val testFunction: (Collection<CommandWithParties<CommandData>>) -> CommandWithParties<CommandData>,
@Suppress("UNUSED_PARAMETER") description: String) {
companion object { companion object {
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "{1}") @Parameterized.Parameters(name = "{1}")
@ -64,7 +65,8 @@ class ContractsDSLTests {
} }
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class SelectWithSingleInputsTests(private val testFunction: (Collection<CommandWithParties<CommandData>>, PublicKey?, AbstractParty?) -> Iterable<CommandWithParties<CommandData>>, description: String) { class SelectWithSingleInputsTests(private val testFunction: (Collection<CommandWithParties<CommandData>>, PublicKey?, AbstractParty?) -> Iterable<CommandWithParties<CommandData>>,
@Suppress("UNUSED_PARAMETER") description: String) {
companion object { companion object {
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "{1}") @Parameterized.Parameters(name = "{1}")
@ -112,7 +114,8 @@ class ContractsDSLTests {
} }
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class SelectWithMultipleInputsTests(private val testFunction: (Collection<CommandWithParties<CommandData>>, Collection<PublicKey>?, Collection<Party>?) -> Iterable<CommandWithParties<CommandData>>, description: String) { class SelectWithMultipleInputsTests(private val testFunction: (Collection<CommandWithParties<CommandData>>, Collection<PublicKey>?, Collection<Party>?) -> Iterable<CommandWithParties<CommandData>>,
@Suppress("UNUSED_PARAMETER") description: String) {
companion object { companion object {
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "{1}") @Parameterized.Parameters(name = "{1}")

View File

@ -20,6 +20,7 @@ import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.testing.internal.TEST_TX_TIME import net.corda.testing.internal.TEST_TX_TIME
import net.corda.testing.internal.createWireTransaction
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger import net.corda.testing.node.ledger
@ -264,7 +265,7 @@ class PartialMerkleTreeTest {
timeWindow: TimeWindow? = null, timeWindow: TimeWindow? = null,
attachments: List<SecureHash> = emptyList() attachments: List<SecureHash> = emptyList()
): WireTransaction { ): WireTransaction {
return WireTransaction( return createWireTransaction(
inputs = testTx.inputs, inputs = testTx.inputs,
attachments = attachments, attachments = attachments,
outputs = testTx.outputs, outputs = testTx.outputs,

View File

@ -57,7 +57,7 @@ class AttachmentTests {
bobNode.registerInitiatedFlow(FetchAttachmentsResponse::class.java) bobNode.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
// Insert an attachment into node zero's store directly. // Insert an attachment into node zero's store directly.
val id = aliceNode.database.transaction { 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. // Get node one to run a flow to fetch it and insert it.
@ -110,7 +110,7 @@ class AttachmentTests {
val attachment = fakeAttachment() val attachment = fakeAttachment()
// Insert an attachment into node zero's store directly. // Insert an attachment into node zero's store directly.
val id = aliceNode.database.transaction { val id = aliceNode.database.transaction {
aliceNode.attachments.importAttachment(attachment.inputStream()) aliceNode.attachments.importAttachment(attachment.inputStream(), "test", null)
} }
// Corrupt its store. // Corrupt its store.

View File

@ -146,7 +146,7 @@ class ResolveTransactionsFlowTest {
} }
// TODO: this operation should not require an explicit transaction // TODO: this operation should not require an explicit transaction
val id = megaCorpNode.transaction { val id = megaCorpNode.transaction {
megaCorpNode.services.attachments.importAttachment(makeJar()) megaCorpNode.services.attachments.importAttachment(makeJar(), "test", null)
} }
val stx2 = makeTransactions(withAttachment = id).second val stx2 = makeTransactions(withAttachment = id).second
val p = TestFlow(stx2, megaCorp) val p = TestFlow(stx2, megaCorp)
@ -201,6 +201,7 @@ class ResolveTransactionsFlowTest {
} }
} }
@Suppress("unused")
@InitiatedBy(TestFlow::class) @InitiatedBy(TestFlow::class)
private class TestResponseFlow(val otherSideSession: FlowSession) : FlowLogic<Void?>() { private class TestResponseFlow(val otherSideSession: FlowSession) : FlowLogic<Void?>() {
@Suspendable @Suspendable

View File

@ -21,10 +21,10 @@ import rx.Observable
import java.util.* import java.util.*
class TopologicalSortTest { class TopologicalSortTest {
class DummyTransaction( class DummyTransaction constructor(
override val id: SecureHash, override val id: SecureHash,
override val inputs: List<StateRef>, override val inputs: List<StateRef>,
val numberOfOutputs: Int, @Suppress("CanBeParameter") private val numberOfOutputs: Int,
override val notary: Party override val notary: Party
) : CoreTransaction() { ) : CoreTransaction() {
override val outputs: List<TransactionState<ContractState>> = (1..numberOfOutputs).map { override val outputs: List<TransactionState<ContractState>> = (1..numberOfOutputs).map {
@ -78,7 +78,7 @@ class TopologicalSortTest {
} }
// Swap two random items // 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 k = 0 // if (i == j) i + 1 else j
val tmp = txs[i] val tmp = txs[i]
txs[i] = txs[k] txs[i] = txs[k]
@ -94,7 +94,7 @@ class TopologicalSortTest {
} }
} }
fun checkTopologicallyOrdered(txs: List<SignedTransaction>) { private fun checkTopologicallyOrdered(txs: List<SignedTransaction>) {
val outputs = HashSet<StateRef>() val outputs = HashSet<StateRef>()
for (tx in txs) { for (tx in txs) {
if (!outputs.containsAll(tx.inputs)) { if (!outputs.containsAll(tx.inputs)) {

View File

@ -8,6 +8,7 @@ import net.corda.core.crypto.CompositeKey
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.* import net.corda.testing.core.*
import net.corda.testing.internal.createWireTransaction
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -53,7 +54,7 @@ class TransactionTests {
val cpub = ck.public val cpub = ck.public
val c1 = CompositeKey.Builder().addKeys(apub, bpub).build(2) val c1 = CompositeKey.Builder().addKeys(apub, bpub).build(2)
val compKey = CompositeKey.Builder().addKeys(c1, cpub).build(1) val compKey = CompositeKey.Builder().addKeys(c1, cpub).build(1)
val wtx = WireTransaction( val wtx = createWireTransaction(
inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)), inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)),
attachments = emptyList(), attachments = emptyList(),
outputs = emptyList(), outputs = emptyList(),
@ -79,7 +80,7 @@ class TransactionTests {
@Test @Test
fun `signed transaction missing signatures`() { fun `signed transaction missing signatures`() {
val wtx = WireTransaction( val wtx = createWireTransaction(
inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)), inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)),
attachments = emptyList(), attachments = emptyList(),
outputs = emptyList(), outputs = emptyList(),
@ -119,8 +120,8 @@ class TransactionTests {
}, DummyContract.PROGRAM_ID)) }, DummyContract.PROGRAM_ID))
val id = SecureHash.randomSHA256() val id = SecureHash.randomSHA256()
val timeWindow: TimeWindow? = null val timeWindow: TimeWindow? = null
val privacySalt: PrivacySalt = PrivacySalt() val privacySalt = PrivacySalt()
val transaction: LedgerTransaction = LedgerTransaction( val transaction = LedgerTransaction(
inputs, inputs,
outputs, outputs,
commands, commands,
@ -137,7 +138,7 @@ class TransactionTests {
@Test @Test
fun `transaction cannot have duplicate inputs`() { fun `transaction cannot have duplicate inputs`() {
val stateRef = StateRef(SecureHash.randomSHA256(), 0) val stateRef = StateRef(SecureHash.randomSHA256(), 0)
fun buildTransaction() = WireTransaction( fun buildTransaction() = createWireTransaction(
inputs = listOf(stateRef, stateRef), inputs = listOf(stateRef, stateRef),
attachments = emptyList(), attachments = emptyList(),
outputs = emptyList(), outputs = emptyList(),
@ -160,7 +161,7 @@ class TransactionTests {
val attachments = emptyList<Attachment>() val attachments = emptyList<Attachment>()
val id = SecureHash.randomSHA256() val id = SecureHash.randomSHA256()
val timeWindow: TimeWindow? = null val timeWindow: TimeWindow? = null
val privacySalt: PrivacySalt = PrivacySalt() val privacySalt = PrivacySalt()
fun buildTransaction() = LedgerTransaction( fun buildTransaction() = LedgerTransaction(
inputs, inputs,
outputs, outputs,
@ -178,7 +179,7 @@ class TransactionTests {
@Test @Test
fun `transactions with identical contents must have different ids`() { fun `transactions with identical contents must have different ids`() {
val outputState = TransactionState(DummyContract.SingleOwnerState(0, ALICE), DummyContract.PROGRAM_ID, DUMMY_NOTARY) val outputState = TransactionState(DummyContract.SingleOwnerState(0, ALICE), DummyContract.PROGRAM_ID, DUMMY_NOTARY)
fun buildTransaction() = WireTransaction( fun buildTransaction() = createWireTransaction(
inputs = emptyList(), inputs = emptyList(),
attachments = emptyList(), attachments = emptyList(),
outputs = listOf(outputState), outputs = listOf(outputState),

View File

@ -40,6 +40,7 @@ enum class PrintOrVisualise {
Visualise Visualise
} }
@Suppress("DEPRECATION")
fun main(args: Array<String>) { fun main(args: Array<String>) {
require(args.isNotEmpty()) { "Usage: <binary> [Print|Visualise]" } require(args.isNotEmpty()) { "Usage: <binary> [Print|Visualise]" }
val printOrVisualise = PrintOrVisualise.valueOf(args[0]) val printOrVisualise = PrintOrVisualise.valueOf(args[0])
@ -99,6 +100,7 @@ fun main(args: Array<String>) {
} }
} }
// END 5 // END 5
Unit
} }
} }

View File

@ -1,4 +1,4 @@
@file:Suppress("UNUSED_VARIABLE", "unused") @file:Suppress("UNUSED_VARIABLE", "unused", "DEPRECATION")
package net.corda.docs package net.corda.docs

View File

@ -1,3 +1,5 @@
@file:Suppress("DEPRECATION")
package net.corda.docs package net.corda.docs
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable

View File

@ -1,3 +1,5 @@
@file:Suppress("UNUSED_VARIABLE")
package net.corda.docs.tutorial.tearoffs package net.corda.docs.tutorial.tearoffs
import net.corda.core.contracts.Command import net.corda.core.contracts.Command
@ -42,4 +44,4 @@ fun main(args: Array<String>) {
} catch (e: FilteredTransactionVerificationException) { } catch (e: FilteredTransactionVerificationException) {
throw MerkleTreeException("Rate Fix Oracle: Couldn't verify partial Merkle tree.") throw MerkleTreeException("Rate Fix Oracle: Couldn't verify partial Merkle tree.")
} }
} }

View File

@ -2,22 +2,21 @@ package net.corda.behave.scenarios.helpers
import net.corda.behave.scenarios.ScenarioState import net.corda.behave.scenarios.ScenarioState
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.contextLogger import org.slf4j.Logger
import org.slf4j.LoggerFactory
abstract class Substeps(protected val state: ScenarioState) { abstract class Substeps(protected val state: ScenarioState) {
protected val log: Logger = LoggerFactory.getLogger(javaClass)
protected val log = contextLogger() protected fun withNetwork(action: ScenarioState.() -> Unit) = state.withNetwork(action)
protected fun withNetwork(action: ScenarioState.() -> Unit) =
state.withNetwork(action)
protected fun <T> withClient(nodeName: String, action: ScenarioState.(CordaRPCOps) -> T): T { protected fun <T> withClient(nodeName: String, action: ScenarioState.(CordaRPCOps) -> T): T {
return state.withClient(nodeName, { return state.withClient(nodeName) {
return@withClient try { try {
action(state, it) action(state, it)
} catch (ex: Exception) { } catch (ex: Exception) {
state.error<T>(ex.message ?: "Failed to execute RPC call") state.error(ex.message ?: "Failed to execute RPC call")
} }
}) }
} }
} }

View File

@ -5,7 +5,6 @@ import org.junit.Test
import rx.observers.TestSubscriber import rx.observers.TestSubscriber
class CommandTests { class CommandTests {
@Test @Test
fun `successful command returns zero`() { fun `successful command returns zero`() {
val exitCode = Command(listOf("ls", "/")).run() val exitCode = Command(listOf("ls", "/")).run()
@ -21,7 +20,7 @@ class CommandTests {
@Test @Test
fun `output stream for command can be observed`() { fun `output stream for command can be observed`() {
val subscriber = TestSubscriber<String>() val subscriber = TestSubscriber<String>()
val exitCode = Command(listOf("ls", "/")).use(subscriber) { _, output -> val exitCode = Command(listOf("ls", "/")).use(subscriber) { _, _ ->
subscriber.awaitTerminalEvent() subscriber.awaitTerminalEvent()
subscriber.assertCompleted() subscriber.assertCompleted()
subscriber.assertNoErrors() subscriber.assertNoErrors()

View File

@ -3,7 +3,6 @@ ext {
} }
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'
apply plugin: 'idea' apply plugin: 'idea'
description 'A javaagent to allow hooking into Kryo' description 'A javaagent to allow hooking into Kryo'

View File

@ -3,7 +3,6 @@ ext {
} }
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'
apply plugin: 'idea' apply plugin: 'idea'
description 'A javaagent to allow hooking into the instrumentation by Quasar' description 'A javaagent to allow hooking into the instrumentation by Quasar'

View File

@ -2,12 +2,12 @@ package net.corda.finance.contracts.universal
import net.corda.core.crypto.toStringShort import net.corda.core.crypto.toStringShort
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.uncheckedCast
import java.math.BigDecimal import java.math.BigDecimal
import java.security.PublicKey import java.security.PublicKey
import java.time.Instant import java.time.Instant
private class PrettyPrint(arr : Arrangement) { private class PrettyPrint(arr : Arrangement) {
val parties = involvedParties(arr) val parties = involvedParties(arr)
private val sb = StringBuilder() private val sb = StringBuilder()
@ -16,21 +16,21 @@ private class PrettyPrint(arr : Arrangement) {
private var atStart = true private var atStart = true
private fun print(msg: String) { private fun print(msg: String) {
if (atStart) if (atStart)
repeat(indentLevel, { sb.append(' ') }) repeat(indentLevel) { sb.append(' ') }
sb.append(msg) sb.append(msg)
atStart = false atStart = false
} }
private fun println(message: Any?) { private fun println(message: Any?) {
if (atStart) if (atStart)
repeat(indentLevel, { sb.append(' ') }) repeat(indentLevel) { sb.append(' ') }
sb.appendln(message) sb.appendln(message)
atStart = true atStart = true
} }
private fun print(msg: Any?) { private fun print(msg: Any?) {
if (atStart) if (atStart)
repeat(indentLevel, { sb.append(' ') }) repeat(indentLevel) { sb.append(' ') }
sb.append(msg) sb.append(msg)
atStart = false atStart = false
} }
@ -45,8 +45,7 @@ private class PrettyPrint(arr : Arrangement) {
val partyMap = mutableMapOf<PublicKey, String>() val partyMap = mutableMapOf<PublicKey, String>()
val usedPartyNames = mutableSetOf<String>() val usedPartyNames = mutableSetOf<String>()
fun createPartyName(party : Party) : String fun createPartyName(party : Party): String {
{
val parts = party.name.organisation.toLowerCase().split(' ') val parts = party.name.organisation.toLowerCase().split(' ')
var camelName = parts.drop(1).fold(parts.first()) { var camelName = parts.drop(1).fold(parts.first()) {
@ -69,38 +68,38 @@ private class PrettyPrint(arr : Arrangement) {
} }
} }
fun prettyPrint(per: Perceivable<Boolean>, x: Boolean? = null) { fun prettyPrintBoolean(per: Perceivable<Boolean>) {
when (per) { when (per) {
is Const -> print("\"${per.value}\"") is Const -> print("\"${per.value}\"")
is PerceivableOr -> { is PerceivableOr -> {
prettyPrint(per.left) prettyPrintBoolean(per.left)
print(" or ") print(" or ")
prettyPrint(per.right) prettyPrintBoolean(per.right)
} }
is PerceivableAnd -> { is PerceivableAnd -> {
prettyPrint(per.left) prettyPrintBoolean(per.left)
print(" and ") print(" and ")
prettyPrint(per.right) prettyPrintBoolean(per.right)
} }
is TimePerceivable -> { is TimePerceivable -> {
when (per.cmp) { when (per.cmp) {
Comparison.GT, Comparison.GTE -> { Comparison.GT, Comparison.GTE -> {
print("after(") print("after(")
prettyPrint(per.instant) prettyPrintInstant(per.instant)
print(")") print(")")
} }
Comparison.LT, Comparison.LTE -> { Comparison.LT, Comparison.LTE -> {
print("before(") print("before(")
prettyPrint(per.instant) prettyPrintInstant(per.instant)
print(")") print(")")
} }
} }
} }
is PerceivableComparison<*> -> { is PerceivableComparison<*> -> {
when (per.type) { when (per.type) {
BigDecimal::class.java -> prettyPrint(per.left as Perceivable<BigDecimal>) BigDecimal::class.java -> prettyPrintBigDecimal(uncheckedCast(per.left))
Instant::class.java -> prettyPrint(per.left as Perceivable<Instant>) Instant::class.java -> prettyPrintInstant(uncheckedCast(per.left))
Boolean::class.java -> prettyPrint(per.left as Perceivable<Boolean>) Boolean::class.java -> prettyPrintBoolean(uncheckedCast(per.left))
} }
when (per.cmp) { when (per.cmp) {
Comparison.GT -> print(" > ") Comparison.GT -> print(" > ")
@ -109,9 +108,9 @@ private class PrettyPrint(arr : Arrangement) {
Comparison.LTE -> print(" <= ") Comparison.LTE -> print(" <= ")
} }
when (per.type) { when (per.type) {
BigDecimal::class.java -> prettyPrint(per.right as Perceivable<BigDecimal>) BigDecimal::class.java -> prettyPrintBigDecimal(uncheckedCast(per.right))
Instant::class.java -> prettyPrint(per.right as Perceivable<Instant>) Instant::class.java -> prettyPrintInstant(uncheckedCast(per.right))
Boolean::class.java -> prettyPrint(per.right as Perceivable<Boolean>) Boolean::class.java -> prettyPrintBoolean(uncheckedCast(per.right))
} }
} }
is TerminalEvent -> print("TerminalEvent(${partyMap[per.reference.owningKey]}, \"${per.source}\")") is TerminalEvent -> print("TerminalEvent(${partyMap[per.reference.owningKey]}, \"${per.source}\")")
@ -120,7 +119,7 @@ private class PrettyPrint(arr : Arrangement) {
} }
} }
fun prettyPrint(per: Perceivable<Instant>, x: Instant? = null) { fun prettyPrintInstant(per: Perceivable<Instant>) {
when (per) { when (per) {
is Const -> print("\"${per.value}\"") is Const -> print("\"${per.value}\"")
is StartDate -> print("startDate") is StartDate -> print("startDate")
@ -129,34 +128,33 @@ private class PrettyPrint(arr : Arrangement) {
} }
} }
fun prettyPrint(per: Perceivable<BigDecimal>, x: BigDecimal? = null) { fun prettyPrintBigDecimal(per: Perceivable<BigDecimal>) {
when (per) { when (per) {
is PerceivableOperation<BigDecimal> -> { is PerceivableOperation<BigDecimal> -> {
prettyPrint(per.left) prettyPrintBigDecimal(per.left)
when (per.op) { when (per.op) {
Operation.PLUS -> print(" + ") Operation.PLUS -> print(" + ")
Operation.MINUS -> print(" - ") Operation.MINUS -> print(" - ")
Operation.DIV -> print(" / ") Operation.DIV -> print(" / ")
Operation.TIMES -> print(" * ") Operation.TIMES -> print(" * ")
else -> print(per.op)
} }
prettyPrint(per.right) prettyPrintBigDecimal(per.right)
} }
is UnaryPlus -> { is UnaryPlus -> {
print("(") print("(")
prettyPrint(per.arg) prettyPrintBigDecimal(per.arg)
print(".).plus()") print(".).plus()")
} }
is Const -> print(per.value) is Const -> print(per.value)
is Interest -> { is Interest -> {
print("Interest(") print("Interest(")
prettyPrint(per.amount) prettyPrintBigDecimal(per.amount)
print(", \"${per.dayCountConvention}\", ") print(", \"${per.dayCountConvention}\", ")
prettyPrint(per.amount) prettyPrintBigDecimal(per.amount)
print(", ") print(", ")
prettyPrint(per.start) prettyPrintInstant(per.start)
print(", ") print(", ")
prettyPrint(per.end) prettyPrintInstant(per.end)
print(")") print(")")
} }
is CurrencyCross -> print("${per.foreign}/${per.domestic}") is CurrencyCross -> print("${per.foreign}/${per.domestic}")
@ -165,7 +163,6 @@ private class PrettyPrint(arr : Arrangement) {
} }
fun prettyPrint(arr: Arrangement) { fun prettyPrint(arr: Arrangement) {
when (arr) { when (arr) {
is Zero -> println("zero") is Zero -> println("zero")
is RollOut -> { is RollOut -> {
@ -183,7 +180,7 @@ private class PrettyPrint(arr : Arrangement) {
is Continuation -> println("next()") is Continuation -> println("next()")
is Obligation -> { is Obligation -> {
print("${partyMap[arr.from.owningKey]}.gives( ${partyMap[arr.to.owningKey]}, ") print("${partyMap[arr.from.owningKey]}.gives( ${partyMap[arr.to.owningKey]}, ")
prettyPrint(arr.amount) prettyPrintBigDecimal(arr.amount)
println(", ${arr.currency})") println(", ${arr.currency})")
} }
is Actions -> { is Actions -> {
@ -191,7 +188,7 @@ private class PrettyPrint(arr : Arrangement) {
indent { indent {
for ((name, condition, arrangement) in arr.actions) { for ((name, condition, arrangement) in arr.actions) {
print("\"$name\".givenThat(") print("\"$name\".givenThat(")
prettyPrint(condition) prettyPrintBoolean(condition)
println(") {") println(") {")
indent { indent {
prettyPrint(arrangement) prettyPrint(arrangement)

View File

@ -36,46 +36,45 @@ class UniversalContract : Contract {
class Split(val ratio: BigDecimal) : Commands class Split(val ratio: BigDecimal) : Commands
} }
fun eval(@Suppress("UNUSED_PARAMETER") tx: LedgerTransaction, expr: Perceivable<Instant>): Instant? = when (expr) { fun evalInstant(expr: Perceivable<Instant>): Instant? = when (expr) {
is Const -> expr.value is Const -> expr.value
is StartDate -> null is StartDate -> null
is EndDate -> null is EndDate -> null
else -> throw Error("Unable to evaluate") else -> throw Error("Unable to evaluate")
} }
fun eval(tx: LedgerTransaction, expr: Perceivable<Boolean>): Boolean = when (expr) { fun evalBoolean(tx: LedgerTransaction, expr: Perceivable<Boolean>): Boolean = when (expr) {
is PerceivableAnd -> eval(tx, expr.left) && eval(tx, expr.right) is PerceivableAnd -> evalBoolean(tx, expr.left) && evalBoolean(tx, expr.right)
is PerceivableOr -> eval(tx, expr.left) || eval(tx, expr.right) is PerceivableOr -> evalBoolean(tx, expr.left) || evalBoolean(tx, expr.right)
is Const<Boolean> -> expr.value is Const<Boolean> -> expr.value
is TimePerceivable -> when (expr.cmp) { is TimePerceivable -> when (expr.cmp) {
Comparison.LTE -> tx.timeWindow!!.fromTime!! <= eval(tx, expr.instant) Comparison.LTE -> tx.timeWindow!!.fromTime!! <= evalInstant(expr.instant)
Comparison.GTE -> tx.timeWindow!!.untilTime!! >= eval(tx, expr.instant) Comparison.GTE -> tx.timeWindow!!.untilTime!! >= evalInstant(expr.instant)
else -> throw NotImplementedError("eval special") else -> throw NotImplementedError("eval special")
} }
is ActorPerceivable -> tx.commands.single().signers.contains(expr.actor.owningKey) is ActorPerceivable -> tx.commands.single().signers.contains(expr.actor.owningKey)
else -> throw NotImplementedError("eval - Boolean - " + expr.javaClass.name) else -> throw NotImplementedError("eval - Boolean - " + expr.javaClass.name)
} }
fun eval(tx: LedgerTransaction, expr: Perceivable<BigDecimal>): BigDecimal = fun evalBigDecimal(tx: LedgerTransaction, expr: Perceivable<BigDecimal>): BigDecimal =
when (expr) { when (expr) {
is Const<BigDecimal> -> expr.value is Const<BigDecimal> -> expr.value
is UnaryPlus -> { is UnaryPlus -> {
val x = eval(tx, expr.arg) val x = evalBigDecimal(tx, expr.arg)
if (x > BigDecimal.ZERO) if (x > BigDecimal.ZERO)
x x
else else
BigDecimal.ZERO BigDecimal.ZERO
} }
is PerceivableOperation -> { is PerceivableOperation -> {
val l = eval(tx, expr.left) val l = evalBigDecimal(tx, expr.left)
val r = eval(tx, expr.right) val r = evalBigDecimal(tx, expr.right)
when (expr.op) { when (expr.op) {
Operation.DIV -> l / r Operation.DIV -> l / r
Operation.MINUS -> l - r Operation.MINUS -> l - r
Operation.PLUS -> l + r Operation.PLUS -> l + r
Operation.TIMES -> l * r Operation.TIMES -> l * r
else -> throw NotImplementedError("eval - amount - operation " + expr.op)
} }
} }
is Fixing -> { is Fixing -> {
@ -83,8 +82,8 @@ class UniversalContract : Contract {
0.0.bd 0.0.bd
} }
is Interest -> { is Interest -> {
val a = eval(tx, expr.amount) val a = evalBigDecimal(tx, expr.amount)
val i = eval(tx, expr.interest) val i = evalBigDecimal(tx, expr.interest)
//TODO //TODO
@ -95,7 +94,7 @@ class UniversalContract : Contract {
fun validateImmediateTransfers(tx: LedgerTransaction, arrangement: Arrangement): Arrangement = when (arrangement) { fun validateImmediateTransfers(tx: LedgerTransaction, arrangement: Arrangement): Arrangement = when (arrangement) {
is Obligation -> { is Obligation -> {
val amount = eval(tx, arrangement.amount) val amount = evalBigDecimal(tx, arrangement.amount)
requireThat { "transferred quantity is non-negative" using (amount >= BigDecimal.ZERO) } requireThat { "transferred quantity is non-negative" using (amount >= BigDecimal.ZERO) }
Obligation(const(amount), arrangement.currency, arrangement.from, arrangement.to) Obligation(const(amount), arrangement.currency, arrangement.from, arrangement.to)
} }
@ -210,7 +209,7 @@ class UniversalContract : Contract {
"action must have a time-window" using (tx.timeWindow != null) "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 } }) // "action must be authorized" by (cmd.signers.any { action.actors.any { party -> party.owningKey == it } })
// todo perhaps merge these two requirements? // 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 // verify that any resulting transfers can be resolved
@ -287,7 +286,7 @@ class UniversalContract : Contract {
perceivable.dayCountConvention, replaceFixing(tx, perceivable.interest, fixings, unusedFixings), perceivable.dayCountConvention, replaceFixing(tx, perceivable.interest, fixings, unusedFixings),
perceivable.start, perceivable.end)) perceivable.start, perceivable.end))
is Fixing -> { 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))) { if (dt != null && fixings.containsKey(FixOf(perceivable.source, dt.toLocalDate(), perceivable.tenor))) {
unusedFixings.remove(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)]!!)) uncheckedCast(Const(fixings[FixOf(perceivable.source, dt.toLocalDate(), perceivable.tenor)]!!))

View File

@ -14,13 +14,12 @@ class IRS {
@Rule @Rule
@JvmField @JvmField
val testSerialization = SerializationEnvironmentRule() val testSerialization = SerializationEnvironmentRule()
val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
val notional = 50.M private val testTxTime1: Instant = Instant.parse("2017-09-02T12:00:00.00Z")
val currency = EUR private val notional = 50.M
private val currency = EUR
val tradeDate: LocalDate = LocalDate.of(2016, 9, 1)
private val tradeDate: LocalDate = LocalDate.of(2016, 9, 1)
/* /*
@ -33,7 +32,7 @@ class IRS {
*/ */
val contractInitial = arrange { private val contractInitial = arrange {
rollOut("2016-09-01".ld, "2018-09-01".ld, Frequency.Quarterly) { rollOut("2016-09-01".ld, "2018-09-01".ld, Frequency.Quarterly) {
actions { actions {
(acmeCorp or highStreetBank) may { (acmeCorp or highStreetBank) may {
@ -52,7 +51,8 @@ class IRS {
} }
} }
} }
val contractAfterFixingFirst = arrange {
private val contractAfterFixingFirst = arrange {
actions { actions {
(acmeCorp or highStreetBank) may { (acmeCorp or highStreetBank) may {
val floating = interest(notional, "act/365", 1.0.bd, "2016-09-01", "2016-12-01") val floating = interest(notional, "act/365", 1.0.bd, "2016-09-01", "2016-12-01")
@ -83,15 +83,15 @@ class IRS {
rollOut("2016-12-01".ld, "2018-09-01".ld, Frequency.Quarterly) { rollOut("2016-12-01".ld, "2018-09-01".ld, Frequency.Quarterly) {
actions { actions {
(acmeCorp or highStreetBank) may { (acmeCorp or highStreetBank) may {
val floating = interest(notional, "act/365", fix("LIBOR", start, Tenor("3M")), start, end) val nextFloating = interest(notional, "act/365", fix("LIBOR", start, Tenor("3M")), start, end)
val fixed = interest(notional, "act/365", 0.5.bd, start, end) val nextFixed = interest(notional, "act/365", 0.5.bd, start, end)
"pay floating" anytime { "pay floating" anytime {
highStreetBank.owes(acmeCorp, floating - fixed, currency) highStreetBank.owes(acmeCorp, nextFloating - nextFixed, currency)
next() next()
} }
"pay fixed" anytime { "pay fixed" anytime {
highStreetBank.owes(acmeCorp, fixed - floating, currency) highStreetBank.owes(acmeCorp, nextFixed - nextFloating, currency)
next() next()
} }
} }
@ -102,7 +102,7 @@ class IRS {
} }
} }
val contractAfterExecutionFirst = arrange { private val contractAfterExecutionFirst = arrange {
rollOut("2016-12-01".ld, "2018-09-01".ld, Frequency.Quarterly) { rollOut("2016-12-01".ld, "2018-09-01".ld, Frequency.Quarterly) {
actions { actions {
(acmeCorp or highStreetBank) may { (acmeCorp or highStreetBank) may {
@ -122,19 +122,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) private val stateAfterFixingFirst = UniversalContract.State(listOf(DUMMY_NOTARY), contractAfterFixingFirst)
val stateAfterExecutionFirst = UniversalContract.State(listOf(DUMMY_NOTARY), contractAfterExecutionFirst) 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 @Test
fun issue() { fun issue() {
transaction { transaction {
output(UNIVERSAL_PROGRAM_ID, stateInitial) output(UNIVERSAL_PROGRAM_ID, stateInitial)
timeWindow(TEST_TX_TIME_1) timeWindow(testTxTime1)
tweak { tweak {
command(acmeCorp.owningKey, UniversalContract.Commands.Issue()) command(acmeCorp.owningKey, UniversalContract.Commands.Issue())
@ -150,7 +151,7 @@ class IRS {
transaction { transaction {
input(UNIVERSAL_PROGRAM_ID, stateInitial) input(UNIVERSAL_PROGRAM_ID, stateInitial)
output(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst) output(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
timeWindow(TEST_TX_TIME_1) timeWindow(testTxTime1)
tweak { tweak {
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name")) command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))
@ -190,7 +191,7 @@ class IRS {
input(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst) input(UNIVERSAL_PROGRAM_ID, stateAfterFixingFirst)
output(UNIVERSAL_PROGRAM_ID, stateAfterExecutionFirst) output(UNIVERSAL_PROGRAM_ID, stateAfterExecutionFirst)
output(UNIVERSAL_PROGRAM_ID, statePaymentFirst) output(UNIVERSAL_PROGRAM_ID, statePaymentFirst)
timeWindow(TEST_TX_TIME_1) timeWindow(testTxTime1)
tweak { tweak {
command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name")) command(highStreetBank.owningKey, UniversalContract.Commands.Action("some undefined name"))

View File

@ -47,6 +47,7 @@ class AuthDBTests : NodeBasedTest() {
fun encFormats() = arrayOf(PasswordEncryption.NONE, PasswordEncryption.SHIRO_1_CRYPT) fun encFormats() = arrayOf(PasswordEncryption.NONE, PasswordEncryption.SHIRO_1_CRYPT)
} }
@Suppress("MemberVisibilityCanBePrivate")
@Parameterized.Parameter @Parameterized.Parameter
lateinit var passwordEncryption: PasswordEncryption lateinit var passwordEncryption: PasswordEncryption
@ -94,7 +95,7 @@ class AuthDBTests : NodeBasedTest() {
) )
node = startNode(ALICE_NAME, rpcUsers = emptyList(), configOverrides = securityConfig) node = startNode(ALICE_NAME, rpcUsers = emptyList(), configOverrides = securityConfig)
client = CordaRPCClient(node.internals.configuration.rpcOptions.address!!) client = CordaRPCClient(node.internals.configuration.rpcOptions.address)
} }
@Test @Test
@ -227,9 +228,8 @@ private data class RoleAndPermissions(val role: String, val permissions: List<St
/* /*
* Manage in-memory DB mocking a users database with the schema expected by Node's security manager * Manage in-memory DB mocking a users database with the schema expected by Node's security manager
*/ */
private class UsersDB : AutoCloseable { private class UsersDB(name: String, users: List<UserAndRoles> = emptyList(), roleAndPermissions: List<RoleAndPermissions> = emptyList()) : AutoCloseable {
val jdbcUrl = "jdbc:h2:mem:$name;DB_CLOSE_DELAY=-1"
val jdbcUrl: String
companion object { companion object {
const val DB_CREATE_SCHEMA = """ const val DB_CREATE_SCHEMA = """
@ -279,11 +279,7 @@ private class UsersDB : AutoCloseable {
} }
} }
constructor(name: String, init {
users: List<UserAndRoles> = emptyList(),
roleAndPermissions: List<RoleAndPermissions> = emptyList()) {
jdbcUrl = "jdbc:h2:mem:$name;DB_CLOSE_DELAY=-1"
dataSource = DataSourceFactory.createDataSource(Properties().apply { dataSource = DataSourceFactory.createDataSource(Properties().apply {
put("dataSourceClassName", "org.h2.jdbcx.JdbcDataSource") put("dataSourceClassName", "org.h2.jdbcx.JdbcDataSource")
put("dataSource.url", jdbcUrl) put("dataSource.url", jdbcUrl)
@ -291,11 +287,9 @@ private class UsersDB : AutoCloseable {
session { session {
it.execute(DB_CREATE_SCHEMA) it.execute(DB_CREATE_SCHEMA)
} }
require(users.map { it.username }.toSet().size == users.size) { require(users.map { it.username }.toSet().size == users.size) {
"Duplicate username in input" "Duplicate username in input"
} }
users.forEach { insert(it) } users.forEach { insert(it) }
roleAndPermissions.forEach { insert(it) } roleAndPermissions.forEach { insert(it) }
} }

View File

@ -20,7 +20,6 @@ import net.corda.testing.core.singleIdentity
import net.corda.testing.driver.PortAllocation import net.corda.testing.driver.PortAllocation
import net.corda.testing.internal.DEV_ROOT_CA import net.corda.testing.internal.DEV_ROOT_CA
import net.corda.testing.node.NotarySpec 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.SharedCompatibilityZoneParams
import net.corda.testing.node.internal.internalDriver import net.corda.testing.node.internal.internalDriver
import net.corda.testing.node.internal.network.NetworkMapServer import net.corda.testing.node.internal.network.NetworkMapServer
@ -51,7 +50,6 @@ class NodeRegistrationTest {
private val notaryName = CordaX500Name("NotaryService", "Zurich", "CH") private val notaryName = CordaX500Name("NotaryService", "Zurich", "CH")
private val aliceName = CordaX500Name("Alice", "London", "GB") private val aliceName = CordaX500Name("Alice", "London", "GB")
private val genevieveName = CordaX500Name("Genevieve", "London", "GB") private val genevieveName = CordaX500Name("Genevieve", "London", "GB")
private val log = contextLogger()
} }
@Rule @Rule
@ -69,7 +67,7 @@ class NodeRegistrationTest {
pollInterval = 1.seconds, pollInterval = 1.seconds,
hostAndPort = portAllocation.nextHostAndPort(), hostAndPort = portAllocation.nextHostAndPort(),
myHostNameValue = "localhost", myHostNameValue = "localhost",
additionalServices = registrationHandler) additionalServices = *arrayOf(registrationHandler))
serverHostAndPort = server.start() serverHostAndPort = server.start()
} }

View File

@ -68,7 +68,7 @@ class MQSecurityAsNodeTest : P2PMQSecurityTest() {
@Test @Test
fun `login to a non ssl port as a node user`() { 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 { assertThatExceptionOfType(ActiveMQSecurityException::class.java).isThrownBy {
attacker.start(NODE_P2P_USER, NODE_P2P_USER, enableSSL = false) attacker.start(NODE_P2P_USER, NODE_P2P_USER, enableSSL = false)
} }
@ -76,7 +76,7 @@ class MQSecurityAsNodeTest : P2PMQSecurityTest() {
@Test @Test
fun `login to a non ssl port as a peer user`() { 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 { assertThatExceptionOfType(ActiveMQSecurityException::class.java).isThrownBy {
attacker.start(PEER_USER, PEER_USER, enableSSL = false) // Login as a peer attacker.start(PEER_USER, PEER_USER, enableSSL = false) // Login as a peer
} }

View File

@ -8,7 +8,7 @@ import org.junit.Test
*/ */
class MQSecurityAsRPCTest : RPCMQSecurityTest() { class MQSecurityAsRPCTest : RPCMQSecurityTest() {
override fun createAttacker(): SimpleMQClient { override fun createAttacker(): SimpleMQClient {
return clientTo(alice.internals.configuration.rpcOptions.address!!) return clientTo(alice.internals.configuration.rpcOptions.address)
} }
@Test @Test

View File

@ -29,6 +29,7 @@ import net.corda.testing.node.internal.NodeBasedTest
import net.corda.testing.node.internal.startFlow import net.corda.testing.node.internal.startFlow
import org.apache.activemq.artemis.api.core.ActiveMQNonExistentQueueException import org.apache.activemq.artemis.api.core.ActiveMQNonExistentQueueException
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException 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.apache.activemq.artemis.api.core.SimpleString
import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After import org.junit.After
@ -111,9 +112,9 @@ abstract class MQSecurityTest : NodeBasedTest() {
} }
fun loginToRPCAndGetClientQueue(): String { 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 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) client.start(rpcUser.username, rpcUser.password, false)
return client.session.addressQuery(clientQueueQuery).queueNames.single().toString() return client.session.addressQuery(clientQueueQuery).queueNames.single().toString()
} }
@ -126,7 +127,7 @@ abstract class MQSecurityTest : NodeBasedTest() {
fun assertTempQueueCreationAttackFails(queue: String) { fun assertTempQueueCreationAttackFails(queue: String) {
assertAttackFails(queue, "CREATE_NON_DURABLE_QUEUE") { assertAttackFails(queue, "CREATE_NON_DURABLE_QUEUE") {
attacker.session.createTemporaryQueue(queue, queue) attacker.session.createTemporaryQueue(queue, RoutingType.MULTICAST, queue)
} }
// Double-check // Double-check
assertThatExceptionOfType(ActiveMQNonExistentQueueException::class.java).isThrownBy { assertThatExceptionOfType(ActiveMQNonExistentQueueException::class.java).isThrownBy {
@ -143,7 +144,7 @@ abstract class MQSecurityTest : NodeBasedTest() {
fun assertNonTempQueueCreationAttackFails(queue: String, durable: Boolean) { fun assertNonTempQueueCreationAttackFails(queue: String, durable: Boolean) {
val permission = if (durable) "CREATE_DURABLE_QUEUE" else "CREATE_NON_DURABLE_QUEUE" val permission = if (durable) "CREATE_DURABLE_QUEUE" else "CREATE_NON_DURABLE_QUEUE"
assertAttackFails(queue, permission) { assertAttackFails(queue, permission) {
attacker.session.createQueue(queue, queue, durable) attacker.session.createQueue(queue, RoutingType.MULTICAST, queue, durable)
} }
// Double-check // Double-check
assertThatExceptionOfType(ActiveMQNonExistentQueueException::class.java).isThrownBy { assertThatExceptionOfType(ActiveMQNonExistentQueueException::class.java).isThrownBy {

View File

@ -4,11 +4,10 @@ import com.typesafe.config.Config
import com.typesafe.config.ConfigException import com.typesafe.config.ConfigException
import net.corda.core.context.AuthServiceId import net.corda.core.context.AuthServiceId
import net.corda.core.identity.CordaX500Name 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.NetworkHostAndPort
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.internal.artemis.CertificateChainCheckPolicy
import net.corda.node.services.config.rpc.NodeRpcOptions import net.corda.node.services.config.rpc.NodeRpcOptions
import net.corda.nodeapi.BrokerRpcSslOptions import net.corda.nodeapi.BrokerRpcSslOptions
import net.corda.nodeapi.internal.config.NodeSSLConfiguration import net.corda.nodeapi.internal.config.NodeSSLConfiguration
@ -40,6 +39,7 @@ interface NodeConfiguration : NodeSSLConfiguration {
val devModeOptions: DevModeOptions? val devModeOptions: DevModeOptions?
val compatibilityZoneURL: URL? val compatibilityZoneURL: URL?
val networkServices: NetworkServicesConfig? val networkServices: NetworkServicesConfig?
@Suppress("DEPRECATION")
val certificateChainCheckPolicies: List<CertChainPolicyConfig> val certificateChainCheckPolicies: List<CertChainPolicyConfig>
val verifierType: VerifierType val verifierType: VerifierType
val flowTimeout: FlowTimeoutConfiguration val flowTimeout: FlowTimeoutConfiguration
@ -179,6 +179,7 @@ data class NodeConfigurationImpl(
override val messagingServerAddress: NetworkHostAndPort?, override val messagingServerAddress: NetworkHostAndPort?,
override val messagingServerExternal: Boolean = (messagingServerAddress != null), override val messagingServerExternal: Boolean = (messagingServerAddress != null),
override val notary: NotaryConfig?, override val notary: NotaryConfig?,
@Suppress("DEPRECATION")
@Deprecated("Do not configure") @Deprecated("Do not configure")
override val certificateChainCheckPolicies: List<CertChainPolicyConfig> = emptyList(), override val certificateChainCheckPolicies: List<CertChainPolicyConfig> = emptyList(),
override val devMode: Boolean = false, override val devMode: Boolean = false,
@ -329,6 +330,7 @@ data class NodeConfigurationImpl(
require(security == null || rpcUsers.isEmpty()) { require(security == null || rpcUsers.isEmpty()) {
"Cannot specify both 'rpcUsers' and 'security' in configuration" "Cannot specify both 'rpcUsers' and 'security' in configuration"
} }
@Suppress("DEPRECATION")
if(certificateChainCheckPolicies.isNotEmpty()) { 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. 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. |Please contact the R3 team on the public slack to discuss your use case.
@ -383,18 +385,7 @@ enum class CertChainPolicyType {
} }
@Deprecated("Do not use") @Deprecated("Do not use")
data class CertChainPolicyConfig(val role: String, private val policy: CertChainPolicyType, private val trustedAliases: Set<String>) { data class CertChainPolicyConfig(val role: String, private val policy: CertChainPolicyType, private val trustedAliases: Set<String>)
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
}
}
}
// Supported types of authentication/authorization data providers // Supported types of authentication/authorization data providers
enum class AuthDataSourceType { enum class AuthDataSourceType {
@ -431,8 +422,6 @@ data class SecurityConfiguration(val authService: SecurityConfiguration.AuthServ
} }
} }
fun copyWithAdditionalUser(user: User) = AuthService(dataSource.copyWithAdditionalUser(user), id, options)
// Optional components: cache // Optional components: cache
data class Options(val cache: Options.Cache?) { data class Options(val cache: Options.Cache?) {
@ -460,12 +449,6 @@ data class SecurityConfiguration(val authService: SecurityConfiguration.AuthServ
AuthDataSourceType.DB -> require(users == null && connection != null) 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 { companion object {
@ -485,4 +468,4 @@ data class SecurityConfiguration(val authService: SecurityConfiguration.AuthServ
id = AuthServiceId("NODE_CONFIG")) id = AuthServiceId("NODE_CONFIG"))
} }
} }
} }

View File

@ -24,7 +24,7 @@ import javax.annotation.concurrent.ThreadSafe
*/ */
// TODO There is duplicated logic between this and PersistentIdentityService // TODO There is duplicated logic between this and PersistentIdentityService
@ThreadSafe @ThreadSafe
class InMemoryIdentityService(identities: List<out PartyAndCertificate> = emptyList(), class InMemoryIdentityService(identities: List<PartyAndCertificate> = emptyList(),
override val trustRoot: X509Certificate) : SingletonSerializeAsToken(), IdentityService { override val trustRoot: X509Certificate) : SingletonSerializeAsToken(), IdentityService {
companion object { companion object {
private val log = contextLogger() private val log = contextLogger()

View File

@ -53,7 +53,7 @@ class E2ETestKeyManagementService(val identityService: IdentityService,
} }
override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate { 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)) private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey))

View File

@ -30,8 +30,7 @@ import java.time.Duration
fun freshCertificate(identityService: IdentityService, fun freshCertificate(identityService: IdentityService,
subjectPublicKey: PublicKey, subjectPublicKey: PublicKey,
issuer: PartyAndCertificate, issuer: PartyAndCertificate,
issuerSigner: ContentSigner, issuerSigner: ContentSigner): PartyAndCertificate {
revocationEnabled: Boolean = false): PartyAndCertificate {
val issuerRole = CertRole.extract(issuer.certificate) 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" } 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 val issuerCert = issuer.certificate

View File

@ -87,8 +87,9 @@ class PersistentKeyManagementService(val identityService: IdentityService,
return keyPair.public return keyPair.public
} }
override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate = override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate {
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)) private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey))

View File

@ -56,10 +56,10 @@ import kotlin.streams.toList
@ThreadSafe @ThreadSafe
class SingleThreadedStateMachineManager( class SingleThreadedStateMachineManager(
val serviceHub: ServiceHubInternal, val serviceHub: ServiceHubInternal,
val checkpointStorage: CheckpointStorage, private val checkpointStorage: CheckpointStorage,
val executor: ExecutorService, val executor: ExecutorService,
val database: CordaPersistence, val database: CordaPersistence,
val secureRandom: SecureRandom, private val secureRandom: SecureRandom,
private val unfinishedFibers: ReusableLatch = ReusableLatch(), private val unfinishedFibers: ReusableLatch = ReusableLatch(),
private val classloader: ClassLoader = SingleThreadedStateMachineManager::class.java.classLoader private val classloader: ClassLoader = SingleThreadedStateMachineManager::class.java.classLoader
) : StateMachineManager, StateMachineManagerInternal { ) : StateMachineManager, StateMachineManagerInternal {
@ -135,7 +135,7 @@ class SingleThreadedStateMachineManager(
} }
serviceHub.networkMapCache.nodeReady.then { serviceHub.networkMapCache.nodeReady.then {
resumeRestoredFlows(fibers) resumeRestoredFlows(fibers)
flowMessaging.start { receivedMessage, deduplicationHandler -> flowMessaging.start { _, deduplicationHandler ->
executor.execute { executor.execute {
deliverExternalEvent(deduplicationHandler.externalCause) deliverExternalEvent(deduplicationHandler.externalCause)
} }
@ -286,10 +286,10 @@ class SingleThreadedStateMachineManager(
} }
private fun checkQuasarJavaAgentPresence() { 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. """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("#") #See https://docs.corda.net/troubleshooting.html - 'Fiber classes not instrumented' for more details.""".trimMargin("#")
}) }
} }
private fun decrementLiveFibers() { private fun decrementLiveFibers() {
@ -304,8 +304,7 @@ class SingleThreadedStateMachineManager(
return checkpointStorage.getAllCheckpoints().map { (id, serializedCheckpoint) -> return checkpointStorage.getAllCheckpoints().map { (id, serializedCheckpoint) ->
// If a flow is added before start() then don't attempt to restore it // If a flow is added before start() then don't attempt to restore it
mutex.locked { if (flows.containsKey(id)) return@map null } mutex.locked { if (flows.containsKey(id)) return@map null }
val checkpoint = deserializeCheckpoint(serializedCheckpoint) val checkpoint = deserializeCheckpoint(serializedCheckpoint) ?: return@map null
if (checkpoint == null) return@map null
logger.debug { "Restored $checkpoint" } logger.debug { "Restored $checkpoint" }
createFlowFromCheckpoint( createFlowFromCheckpoint(
id = id, id = id,
@ -524,12 +523,6 @@ class SingleThreadedStateMachineManager(
isStartIdempotent: Boolean isStartIdempotent: Boolean
): CordaFuture<FlowStateMachine<A>> { ): CordaFuture<FlowStateMachine<A>> {
val flowId = StateMachineRunId.createRandom() 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 // 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) // have access to the fiber (and thereby the service hub)
@ -541,7 +534,7 @@ class SingleThreadedStateMachineManager(
val flowCorDappVersion = createSubFlowVersion(serviceHub.cordappProvider.getCordappForFlow(flowLogic), serviceHub.myInfo.platformVersion) 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<Unit>() val startedFuture = openFuture<Unit>()
val initialState = StateMachineState( val initialState = StateMachineState(
checkpoint = initialCheckpoint, checkpoint = initialCheckpoint,

View File

@ -2,6 +2,7 @@ package net.corda.node.services.statemachine
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.internal.TimedFlow
import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.utilities.contextLogger 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<Staff>) private data class ConsultationReport(val error: Throwable, val diagnosis: Diagnosis, val by: List<Staff>)
/**
* 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. * The flow has been removed from the state machine.
*/ */

View File

@ -69,7 +69,6 @@ data class Checkpoint(
flowLogicClass: Class<FlowLogic<*>>, flowLogicClass: Class<FlowLogic<*>>,
frozenFlowLogic: SerializedBytes<FlowLogic<*>>, frozenFlowLogic: SerializedBytes<FlowLogic<*>>,
ourIdentity: Party, ourIdentity: Party,
deduplicationSeed: String,
subFlowVersion: SubFlowVersion subFlowVersion: SubFlowVersion
): Try<Checkpoint> { ): Try<Checkpoint> {
return SubFlow.create(flowLogicClass, subFlowVersion).map { topLevelSubFlow -> return SubFlow.create(flowLogicClass, subFlowVersion).map { topLevelSubFlow ->

View File

@ -45,9 +45,7 @@ class HospitalisingInterceptor(
when (nextState.checkpoint.errorState) { when (nextState.checkpoint.errorState) {
is ErrorState.Clean -> { is ErrorState.Clean -> {
if (hospitalisedFlows.remove(fiber.id) != null) { hospitalisedFlows.remove(fiber.id)
flowHospital.flowCleaned(fiber)
}
} }
is ErrorState.Errored -> { is ErrorState.Errored -> {
val exceptionsToHandle = nextState.checkpoint.errorState.errors.map { it.exception } val exceptionsToHandle = nextState.checkpoint.errorState.errors.map { it.exception }

View File

@ -76,7 +76,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
Transactional.Committed(value) Transactional.Committed(value)
} else { } else {
// Some database transactions, including us, writing, with readers seeing whatever is in the database and writers seeing the (in memory) value. // 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) }
} }
} }
@ -146,13 +146,13 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
} }
// Helpers to know if transaction(s) are currently writing the given key. // 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 weAreWriting(key: K): Boolean = pendingKeys[key]?.contains(contextTransaction) ?: false
protected fun anyoneWriting(key: K): Boolean = pendingKeys.get(key)?.isNotEmpty() ?: false protected fun anyoneWriting(key: K): Boolean = pendingKeys[key]?.isNotEmpty() ?: false
// Indicate this database transaction is a writer of this key. // Indicate this database transaction is a writer of this key.
private fun addPendingKey(key: K, databaseTransaction: DatabaseTransaction): Boolean { private fun addPendingKey(key: K, databaseTransaction: DatabaseTransaction): Boolean {
var added = true var added = true
pendingKeys.compute(key) { k, oldSet -> pendingKeys.compute(key) { _, oldSet ->
if (oldSet == null) { if (oldSet == null) {
val newSet = HashSet<DatabaseTransaction>(0) val newSet = HashSet<DatabaseTransaction>(0)
newSet += databaseTransaction newSet += databaseTransaction
@ -167,7 +167,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
// Remove this database transaction as a writer of this key, because the transaction committed or rolled back. // Remove this database transaction as a writer of this key, because the transaction committed or rolled back.
private fun removePendingKey(key: K, databaseTransaction: DatabaseTransaction) { private fun removePendingKey(key: K, databaseTransaction: DatabaseTransaction) {
pendingKeys.compute(key) { k, oldSet -> pendingKeys.compute(key) { _, oldSet ->
if (oldSet == null) { if (oldSet == null) {
oldSet oldSet
} else { } else {
@ -199,7 +199,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
} }
// No one can see it. // No one can see it.
class Missing<T>() : Transactional<T>() { class Missing<T> : Transactional<T>() {
override val value: T override val value: T
get() = throw NoSuchElementException("Not present") get() = throw NoSuchElementException("Not present")
override val isPresent: Boolean override val isPresent: Boolean
@ -228,7 +228,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
fun alsoWrite(_value: T) { fun alsoWrite(_value: T) {
// Make the lazy loader the writers see actually just return the value that has been set. // 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 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 // 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. // retaining what could be a large memory footprint object.
@ -242,10 +242,9 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
// and then stop saying the transaction is writing the key. // and then stop saying the transaction is writing the key.
tx.onCommit { tx.onCommit {
if (strongComitted.compareAndSet(false, true)) { if (strongComitted.compareAndSet(false, true)) {
val dereferencedKey = strongKey
val dereferencedValue = weakValue.get() val dereferencedValue = weakValue.get()
if (dereferencedValue != null) { if (dereferencedValue != null) {
strongMap.cache.put(dereferencedKey, Committed(dereferencedValue)) strongMap.cache.put(strongKey, Committed(dereferencedValue))
} }
} }
strongMap.removePendingKey(strongKey, tx) strongMap.removePendingKey(strongKey, tx)
@ -262,7 +261,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
private fun loadAsWriter(): T { private fun loadAsWriter(): T {
val _value = writerValueLoader.get()() val _value = writerValueLoader.get()()
if (writerValueLoader.get() == _writerValueLoader) { if (writerValueLoader.get() == _writerValueLoader) {
writerValueLoader.set({ _value }) writerValueLoader.set { _value }
} }
return _value return _value
} }
@ -272,7 +271,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
private fun loadAsReader(): T? { private fun loadAsReader(): T? {
val _value = readerValueLoader.get()() val _value = readerValueLoader.get()()
if (readerValueLoader.get() == _readerValueLoader) { if (readerValueLoader.get() == _readerValueLoader) {
readerValueLoader.set({ _value }) readerValueLoader.set { _value }
} }
return _value return _value
} }
@ -310,7 +309,7 @@ open class AppendOnlyPersistentMap<K, V, E, out EK>(
toPersistentEntity, toPersistentEntity,
persistentEntityClass) { persistentEntityClass) {
//TODO determine cacheBound based on entity class later or with node config allowing tuning, or using some heuristic based on heap size //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<K, Transactional<V>>( override val cache = NonInvalidatingCache(
bound = cacheBound, bound = cacheBound,
loadFunction = { key: K -> loadFunction = { key: K ->
// This gets called if a value is read and the cache has no Transactional for this key yet. // This gets called if a value is read and the cache has no Transactional for this key yet.
@ -321,10 +320,10 @@ open class AppendOnlyPersistentMap<K, V, E, out EK>(
// If someone is writing (but not us) // If someone is writing (but not us)
// For those not writing, the value cannot be seen. // 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). // For those writing, they need to re-load the value from the database (which their database transaction CAN see).
Transactional.InFlight<K, V>(this, key, { null }, { loadValue(key)!! }) Transactional.InFlight(this, key, { null }, { loadValue(key)!! })
} else { } else {
// If no one is writing, then the value does not exist. // If no one is writing, then the value does not exist.
Transactional.Missing<V>() Transactional.Missing()
} }
} else { } else {
// A value was found // A value was found
@ -332,10 +331,10 @@ open class AppendOnlyPersistentMap<K, V, E, out EK>(
// If we are writing, it might not be globally visible, and was evicted from the cache. // 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 not writing, they need to check the database again.
// For those writing, they can see the value found. // For those writing, they can see the value found.
Transactional.InFlight<K, V>(this, key, { loadValue(key) }, { value }) Transactional.InFlight(this, key, { loadValue(key) }, { value })
} else { } else {
// If no one is writing, then make it globally visible. // If no one is writing, then make it globally visible.
Transactional.Committed<V>(value) Transactional.Committed(value)
} }
} }
}) })
@ -354,26 +353,22 @@ class WeightBasedAppendOnlyPersistentMap<K, V, E, out EK>(
fromPersistentEntity, fromPersistentEntity,
toPersistentEntity, toPersistentEntity,
persistentEntityClass) { persistentEntityClass) {
override val cache = NonInvalidatingWeightBasedCache<K, Transactional<V>>( override val cache = NonInvalidatingWeightBasedCache(
maxWeight = maxWeight, maxWeight = maxWeight,
weigher = object : Weigher<K, Transactional<V>> { weigher = Weigher { key, value -> weighingFunc(key, value) },
override fun weigh(key: K, value: Transactional<V>): Int {
return weighingFunc(key, value)
}
},
loadFunction = { key: K -> loadFunction = { key: K ->
val value: V? = loadValue(key) val value: V? = loadValue(key)
if (value == null) { if (value == null) {
if (anyoneWriting(key)) { if (anyoneWriting(key)) {
Transactional.InFlight<K, V>(this, key, { null }, { loadValue(key)!! }) Transactional.InFlight(this, key, { null }, { loadValue(key)!! })
} else { } else {
Transactional.Missing<V>() Transactional.Missing()
} }
} else { } else {
if (weAreWriting(key)) { if (weAreWriting(key)) {
Transactional.InFlight<K, V>(this, key, { loadValue(key) }, { value }) Transactional.InFlight(this, key, { loadValue(key) }, { value })
} else { } else {
Transactional.Committed<V>(value) Transactional.Committed(value)
} }
} }
}) })

View File

@ -35,9 +35,6 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import rx.Observable; import rx.Observable;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.cert.CertificateException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -69,7 +66,7 @@ public class VaultQueryJavaTests {
private CordaPersistence database; private CordaPersistence database;
@Before @Before
public void setUp() throws CertificateException, InvalidAlgorithmParameterException { public void setUp() {
List<String> cordappPackages = asList("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName()); List<String> cordappPackages = asList("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName());
IdentityService identitySvc = makeTestIdentityService(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity()); IdentityService identitySvc = makeTestIdentityService(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity());
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices( Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(
@ -85,14 +82,10 @@ public class VaultQueryJavaTests {
} }
@After @After
public void cleanUp() throws IOException { public void cleanUp() {
database.close(); database.close();
} }
/**
* Sample Vault Query API tests
*/
/** /**
* Static queryBy() tests * Static queryBy() tests
*/ */
@ -103,6 +96,7 @@ public class VaultQueryJavaTests {
FieldInfo currency = getField("currency", SampleCashSchemaV2.PersistentCashState.class); FieldInfo currency = getField("currency", SampleCashSchemaV2.PersistentCashState.class);
CriteriaExpression.AggregateFunctionExpression<Object, Boolean> expression = sum(quantity, singletonList(currency), Sort.Direction.ASC); CriteriaExpression.AggregateFunctionExpression<Object, Boolean> expression = sum(quantity, singletonList(currency), Sort.Direction.ASC);
@SuppressWarnings("unchecked")
VaultCustomQueryCriteria<SampleCashSchemaV2.PersistentCashState> criteria = new VaultCustomQueryCriteria(expression, Vault.StateStatus.UNCONSUMED, null); VaultCustomQueryCriteria<SampleCashSchemaV2.PersistentCashState> criteria = new VaultCustomQueryCriteria(expression, Vault.StateStatus.UNCONSUMED, null);
database.transaction(tx -> vaultService.queryBy(FungibleAsset.class, criteria)); database.transaction(tx -> vaultService.queryBy(FungibleAsset.class, criteria));
@ -115,13 +109,14 @@ public class VaultQueryJavaTests {
FieldInfo stateRef = getField("stateRef", SampleCashSchemaV2.PersistentCashState.class); FieldInfo stateRef = getField("stateRef", SampleCashSchemaV2.PersistentCashState.class);
CriteriaExpression.AggregateFunctionExpression<Object, Boolean> expression = sum(quantity, asList(currency, stateRef), Sort.Direction.ASC); CriteriaExpression.AggregateFunctionExpression<Object, Boolean> expression = sum(quantity, asList(currency, stateRef), Sort.Direction.ASC);
@SuppressWarnings("unchecked")
VaultCustomQueryCriteria<SampleCashSchemaV2.PersistentCashState> criteria = new VaultCustomQueryCriteria(expression, Vault.StateStatus.UNCONSUMED, null); VaultCustomQueryCriteria<SampleCashSchemaV2.PersistentCashState> criteria = new VaultCustomQueryCriteria(expression, Vault.StateStatus.UNCONSUMED, null);
database.transaction(tx -> vaultService.queryBy(FungibleAsset.class, criteria)); database.transaction(tx -> vaultService.queryBy(FungibleAsset.class, criteria));
} }
@Test @Test
public void unconsumedLinearStates() throws VaultQueryException { public void unconsumedLinearStates() {
database.transaction(tx -> { database.transaction(tx -> {
vaultFiller.fillWithSomeTestLinearStates(3); vaultFiller.fillWithSomeTestLinearStates(3);
return tx; return tx;
@ -193,7 +188,7 @@ public class VaultQueryJavaTests {
} }
@Test @Test
public void consumedDealStatesPagedSorted() throws VaultQueryException { public void consumedDealStatesPagedSorted() {
List<String> dealIds = asList("123", "456", "789"); List<String> dealIds = asList("123", "456", "789");
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Triple<StateAndRef<LinearState>, UniqueIdentifier, Vault<DealState>> ids = Triple<StateAndRef<LinearState>, UniqueIdentifier, Vault<DealState>> ids =
@ -304,7 +299,6 @@ public class VaultQueryJavaTests {
DataFeed<Vault.Page<ContractState>, Vault.Update<ContractState>> results = vaultService.trackBy(ContractState.class, criteria); DataFeed<Vault.Page<ContractState>, Vault.Update<ContractState>> results = vaultService.trackBy(ContractState.class, criteria);
Vault.Page<ContractState> snapshot = results.getSnapshot(); Vault.Page<ContractState> snapshot = results.getSnapshot();
Observable<Vault.Update<ContractState>> updates = results.getUpdates();
// DOCEND VaultJavaQueryExample4 // DOCEND VaultJavaQueryExample4
assertThat(snapshot.getStates()).hasSize(3); assertThat(snapshot.getStates()).hasSize(3);
@ -358,7 +352,6 @@ public class VaultQueryJavaTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void aggregateFunctionsWithoutGroupClause() { public void aggregateFunctionsWithoutGroupClause() {
database.transaction(tx -> { database.transaction(tx -> {
Amount<Currency> dollars100 = new Amount<>(100, Currency.getInstance("USD")); Amount<Currency> dollars100 = new Amount<>(100, Currency.getInstance("USD"));
Amount<Currency> dollars200 = new Amount<>(200, Currency.getInstance("USD")); Amount<Currency> dollars200 = new Amount<>(200, Currency.getInstance("USD"));
Amount<Currency> dollars300 = new Amount<>(300, Currency.getInstance("USD")); Amount<Currency> dollars300 = new Amount<>(300, Currency.getInstance("USD"));
@ -404,7 +397,6 @@ public class VaultQueryJavaTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void aggregateFunctionsWithSingleGroupClause() { public void aggregateFunctionsWithSingleGroupClause() {
database.transaction(tx -> { database.transaction(tx -> {
Amount<Currency> dollars100 = new Amount<>(100, Currency.getInstance("USD")); Amount<Currency> dollars100 = new Amount<>(100, Currency.getInstance("USD"));
Amount<Currency> dollars200 = new Amount<>(200, Currency.getInstance("USD")); Amount<Currency> dollars200 = new Amount<>(200, Currency.getInstance("USD"));
Amount<Currency> dollars300 = new Amount<>(300, Currency.getInstance("USD")); Amount<Currency> dollars300 = new Amount<>(300, Currency.getInstance("USD"));

View File

@ -24,7 +24,6 @@ import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.GBP import net.corda.finance.GBP
import net.corda.finance.USD
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
@ -157,6 +156,7 @@ class CordaRPCOpsImplTest {
@Test @Test
fun `issue and move`() { fun `issue and move`() {
@Suppress("DEPRECATION")
withPermissions(invokeRpc(CordaRPCOps::stateMachinesFeed), withPermissions(invokeRpc(CordaRPCOps::stateMachinesFeed),
invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed), invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed),
invokeRpc("vaultTrackBy"), invokeRpc("vaultTrackBy"),
@ -168,11 +168,7 @@ class CordaRPCOpsImplTest {
vaultTrackCash = rpc.vaultTrackBy<Cash.State>().updates vaultTrackCash = rpc.vaultTrackBy<Cash.State>().updates
} }
val result = rpc.startFlow(::CashIssueFlow, val result = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notary)
100.DOLLARS,
OpaqueBytes(ByteArray(1, { 1 })),
notary
)
mockNet.runNetwork() mockNet.runNetwork()
@ -247,7 +243,7 @@ class CordaRPCOpsImplTest {
fun `cash command by user not permissioned for cash`() { fun `cash command by user not permissioned for cash`() {
withoutAnyPermissions { withoutAnyPermissions {
assertThatExceptionOfType(PermissionException::class.java).isThrownBy { assertThatExceptionOfType(PermissionException::class.java).isThrownBy {
rpc.startFlow(::CashIssueFlow, Amount(100, USD), OpaqueBytes(ByteArray(1, { 1 })), notary) rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notary)
} }
} }
} }

View File

@ -60,7 +60,7 @@ class NodeTest {
fun `generateAndSaveNodeInfo works`() { fun `generateAndSaveNodeInfo works`() {
val configuration = createConfig(ALICE_NAME) val configuration = createConfig(ALICE_NAME)
val platformVersion = 789 val platformVersion = 789
configureDatabase(configuration.dataSourceProperties, configuration.database, { null }, { null }).use { database -> configureDatabase(configuration.dataSourceProperties, configuration.database, { null }, { null }).use {
val node = Node(configuration, rigorousMock<VersionInfo>().also { val node = Node(configuration, rigorousMock<VersionInfo>().also {
doReturn(platformVersion).whenever(it).platformVersion doReturn(platformVersion).whenever(it).platformVersion
}, initialiseSerialization = false) }, initialiseSerialization = false)

View File

@ -19,7 +19,6 @@ import org.apache.activemq.artemis.api.core.SimpleString
import org.junit.Test import org.junit.Test
import rx.Notification import rx.Notification
import rx.Observable import rx.Observable
import rx.Subscription
import rx.subjects.UnicastSubject import rx.subjects.UnicastSubject
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*
@ -38,7 +37,7 @@ class RoundTripObservableSerializerTests {
.maximumSize(100) .maximumSize(100)
.build() .build()
subMap.put(id, ObservableSubscription(mock<Subscription>())) subMap.put(id, ObservableSubscription(mock()))
return subMap return subMap
} }
@ -48,7 +47,7 @@ class RoundTripObservableSerializerTests {
}) })
private fun createRpcObservableMap(): Cache<Trace.InvocationId, UnicastSubject<Notification<*>>> { private fun createRpcObservableMap(): Cache<Trace.InvocationId, UnicastSubject<Notification<*>>> {
val onObservableRemove = RemovalListener<Trace.InvocationId, UnicastSubject<Notification<*>>> { key, value, cause -> val onObservableRemove = RemovalListener<Trace.InvocationId, UnicastSubject<Notification<*>>> { key, _, _ ->
val observableId = key!! val observableId = key!!
observablesToReap.locked { observables.add(observableId) } observablesToReap.locked { observables.add(observableId) }
@ -85,7 +84,7 @@ class RoundTripObservableSerializerTests {
// What we're actually going to serialize then deserialize // What we're actually going to serialize then deserialize
val obs = Observable.create<Int>({ 12 }) val obs = Observable.create<Int> { Math.random() }
val serverSerializationContext = RpcServerObservableSerializer.createContext( val serverSerializationContext = RpcServerObservableSerializer.createContext(
serializationContext, serverObservableContext) serializationContext, serverObservableContext)
@ -95,6 +94,6 @@ class RoundTripObservableSerializerTests {
val blob = SerializationOutput(serverSerializer).serialize(obs, serverSerializationContext) val blob = SerializationOutput(serverSerializer).serialize(obs, serverSerializationContext)
val obs2 = DeserializationInput(clientSerializer).deserialize(blob, clientSerializationContext) DeserializationInput(clientSerializer).deserialize(blob, clientSerializationContext)
} }
} }

View File

@ -8,13 +8,12 @@ import net.corda.node.internal.serialization.testutils.TestObservableContext
import net.corda.node.internal.serialization.testutils.serializationContext import net.corda.node.internal.serialization.testutils.serializationContext
import net.corda.node.serialization.amqp.RpcServerObservableSerializer import net.corda.node.serialization.amqp.RpcServerObservableSerializer
import net.corda.node.services.messaging.ObservableSubscription import net.corda.node.services.messaging.ObservableSubscription
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.SerializationOutput import net.corda.serialization.internal.amqp.SerializationOutput
import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.AllWhitelist
import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.SimpleString
import org.junit.Test import org.junit.Test
import rx.Observable import rx.Observable
import rx.Subscription
import java.time.Instant import java.time.Instant
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -28,7 +27,7 @@ class RpcServerObservableSerializerTests {
.maximumSize(100) .maximumSize(100)
.build() .build()
subMap.put(Trace.InvocationId("test1", Instant.now()), ObservableSubscription(mock<Subscription>())) subMap.put(Trace.InvocationId("test1", Instant.now()), ObservableSubscription(mock()))
return subMap return subMap
} }
@ -72,7 +71,7 @@ class RpcServerObservableSerializerTests {
register(RpcServerObservableSerializer()) register(RpcServerObservableSerializer())
} }
val obs = Observable.create<Int>({ 12 }) val obs = Observable.create<Int> { Math.random() }
val newContext = RpcServerObservableSerializer.createContext(serializationContext, observable) val newContext = RpcServerObservableSerializer.createContext(serializationContext, observable)
try { try {

View File

@ -1,21 +1,7 @@
package net.corda.node.services.events package net.corda.node.services.events
import com.nhaarman.mockito_kotlin.any import com.nhaarman.mockito_kotlin.*
import com.nhaarman.mockito_kotlin.argForWhich import net.corda.core.contracts.*
import com.nhaarman.mockito_kotlin.doAnswer
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.eq
import com.nhaarman.mockito_kotlin.same
import com.nhaarman.mockito_kotlin.timeout
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.verifyNoMoreInteractions
import com.nhaarman.mockito_kotlin.whenever
import junit.framework.Assert.fail
import net.corda.core.contracts.SchedulableState
import net.corda.core.contracts.ScheduledActivity
import net.corda.core.contracts.ScheduledStateRef
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowLogicRef import net.corda.core.flows.FlowLogicRef
@ -36,11 +22,7 @@ import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.spectator import net.corda.testing.internal.spectator
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.TestClock import net.corda.testing.node.TestClock
import org.junit.After import org.junit.*
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestWatcher import org.junit.rules.TestWatcher
import org.junit.runner.Description import org.junit.runner.Description
import org.slf4j.Logger import org.slf4j.Logger
@ -51,6 +33,7 @@ import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.fail
open class NodeSchedulerServiceTestBase { open class NodeSchedulerServiceTestBase {
protected class Event(time: Instant) { protected class Event(time: Instant) {
@ -87,7 +70,7 @@ open class NodeSchedulerServiceTestBase {
doLookup(transactionStates).whenever(it).loadState(any()) doLookup(transactionStates).whenever(it).loadState(any())
} }
protected val traces = Collections.synchronizedList(mutableListOf<ScheduledStateRef>()) private val traces = Collections.synchronizedList(mutableListOf<ScheduledStateRef>())
@Before @Before
fun resetTraces() { fun resetTraces() {
@ -98,7 +81,7 @@ open class NodeSchedulerServiceTestBase {
doReturn(false).whenever(it).isTraceEnabled doReturn(false).whenever(it).isTraceEnabled
doAnswer { doAnswer {
traces += it.getArgument<ScheduledStateRef>(1) traces += it.getArgument<ScheduledStateRef>(1)
}.whenever(it).trace(eq(NodeSchedulerService.schedulingAsNextFormat), any<Object>()) }.whenever(it).trace(eq(NodeSchedulerService.schedulingAsNextFormat), any<Any>())
} }
protected fun assertWaitingFor(ssr: ScheduledStateRef) { protected fun assertWaitingFor(ssr: ScheduledStateRef) {
@ -273,7 +256,7 @@ class NodeSchedulerServiceTest : NodeSchedulerServiceTestBase() {
class NodeSchedulerPersistenceTest : NodeSchedulerServiceTestBase() { class NodeSchedulerPersistenceTest : NodeSchedulerServiceTestBase() {
private val databaseConfig: DatabaseConfig = DatabaseConfig() private val databaseConfig: DatabaseConfig = DatabaseConfig()
fun createScheduler(db: CordaPersistence): NodeSchedulerService { private fun createScheduler(db: CordaPersistence): NodeSchedulerService {
return NodeSchedulerService( return NodeSchedulerService(
testClock, testClock,
db, db,
@ -285,7 +268,7 @@ class NodeSchedulerPersistenceTest : NodeSchedulerServiceTestBase() {
log = log).apply { start() } log = log).apply { start() }
} }
fun transactionStateMock(logicRef: FlowLogicRef, time: Instant): TransactionState<*> { private fun transactionStateMock(logicRef: FlowLogicRef, time: Instant): TransactionState<*> {
return rigorousMock<TransactionState<SchedulableState>>().also { return rigorousMock<TransactionState<SchedulableState>>().also {
doReturn(rigorousMock<SchedulableState>().also { doReturn(rigorousMock<SchedulableState>().also {
doReturn(ScheduledActivity(logicRef, time)).whenever(it).nextScheduledActivity(any(), any()) doReturn(ScheduledActivity(logicRef, time)).whenever(it).nextScheduledActivity(any(), any())

View File

@ -6,9 +6,8 @@ import net.corda.core.crypto.generateKeyPair
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.internal.configureDatabase import net.corda.node.internal.configureDatabase
import net.corda.node.services.config.CertChainPolicyConfig
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.FlowTimeoutConfiguration import net.corda.node.services.config.FlowTimeoutConfiguration
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.configureWithDevSSLCertificate import net.corda.node.services.config.configureWithDevSSLCertificate
import net.corda.node.services.network.NetworkMapCacheImpl import net.corda.node.services.network.NetworkMapCacheImpl
import net.corda.node.services.network.PersistentNetworkMapCache import net.corda.node.services.network.PersistentNetworkMapCache
@ -72,7 +71,6 @@ class ArtemisMessagingTest {
doReturn("cordacadevpass").whenever(it).keyStorePassword doReturn("cordacadevpass").whenever(it).keyStorePassword
doReturn(NetworkHostAndPort("0.0.0.0", serverPort)).whenever(it).p2pAddress doReturn(NetworkHostAndPort("0.0.0.0", serverPort)).whenever(it).p2pAddress
doReturn(null).whenever(it).jmxMonitoringHttpPort doReturn(null).whenever(it).jmxMonitoringHttpPort
doReturn(emptyList<CertChainPolicyConfig>()).whenever(it).certificateChainCheckPolicies
doReturn(FlowTimeoutConfiguration(5.seconds, 3, backoffBase = 1.0)).whenever(it).flowTimeout doReturn(FlowTimeoutConfiguration(5.seconds, 3, backoffBase = 1.0)).whenever(it).flowTimeout
} }
LogHelper.setLevel(PersistentUniquenessProvider::class) LogHelper.setLevel(PersistentUniquenessProvider::class)

View File

@ -190,7 +190,7 @@ class DBCheckpointStorageTests {
override fun call() {} override fun call() {}
} }
val frozenLogic = logic.serialize(context = SerializationDefaults.CHECKPOINT_CONTEXT) val frozenLogic = logic.serialize(context = SerializationDefaults.CHECKPOINT_CONTEXT)
val checkpoint = Checkpoint.create(InvocationContext.shell(), FlowStart.Explicit, logic.javaClass, frozenLogic, ALICE, "", SubFlowVersion.CoreFlow(version)).getOrThrow() val checkpoint = Checkpoint.create(InvocationContext.shell(), FlowStart.Explicit, logic.javaClass, frozenLogic, ALICE, SubFlowVersion.CoreFlow(version)).getOrThrow()
return id to checkpoint.serialize(context = SerializationDefaults.CHECKPOINT_CONTEXT) return id to checkpoint.serialize(context = SerializationDefaults.CHECKPOINT_CONTEXT)
} }

View File

@ -7,18 +7,14 @@ import net.corda.core.crypto.SignatureMetadata
import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.TransactionSignature
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.WireTransaction
import net.corda.node.internal.configureDatabase import net.corda.node.internal.configureDatabase
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.transactions.PersistentUniquenessProvider import net.corda.node.services.transactions.PersistentUniquenessProvider
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.*
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.core.dummyCommand
import net.corda.testing.internal.LogHelper import net.corda.testing.internal.LogHelper
import net.corda.testing.internal.createWireTransaction
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
@ -166,7 +162,7 @@ class DBTransactionStorageTests {
} }
private fun newTransaction(): SignedTransaction { private fun newTransaction(): SignedTransaction {
val wtx = WireTransaction( val wtx = createWireTransaction(
inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)), inputs = listOf(StateRef(SecureHash.randomSHA256(), 0)),
attachments = emptyList(), attachments = emptyList(),
outputs = emptyList(), outputs = emptyList(),
@ -174,6 +170,9 @@ class DBTransactionStorageTests {
notary = DUMMY_NOTARY, notary = DUMMY_NOTARY,
timeWindow = null timeWindow = null
) )
return SignedTransaction(wtx, listOf(TransactionSignature(ByteArray(1), ALICE_PUBKEY, SignatureMetadata(1, Crypto.findSignatureScheme(ALICE_PUBKEY).schemeNumberID)))) return SignedTransaction(
wtx,
listOf(TransactionSignature(ByteArray(1), ALICE_PUBKEY, SignatureMetadata(1, Crypto.findSignatureScheme(ALICE_PUBKEY).schemeNumberID)))
)
} }
} }

View File

@ -4,7 +4,6 @@ import com.nhaarman.mockito_kotlin.*
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.generateKeyPair import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
@ -29,23 +28,23 @@ import net.corda.finance.schemas.SampleCashSchemaV2
import net.corda.finance.schemas.SampleCashSchemaV3 import net.corda.finance.schemas.SampleCashSchemaV3
import net.corda.finance.utils.sumCash import net.corda.finance.utils.sumCash
import net.corda.node.internal.configureDatabase import net.corda.node.internal.configureDatabase
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.schema.ContractStateAndRef import net.corda.node.services.schema.ContractStateAndRef
import net.corda.node.services.schema.HibernateObserver import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.vault.VaultSchemaV1
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.NodeVaultService
import net.corda.node.services.vault.VaultSchemaV1
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.testing.core.* import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
import net.corda.testing.internal.vault.DummyLinearStateSchemaV2
import net.corda.testing.internal.vault.VaultFiller import net.corda.testing.internal.vault.VaultFiller
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
import net.corda.testing.internal.vault.DummyLinearStateSchemaV2
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.hibernate.SessionFactory import org.hibernate.SessionFactory
@ -74,18 +73,18 @@ class HibernateConfigurationTest {
val testSerialization = SerializationEnvironmentRule() val testSerialization = SerializationEnvironmentRule()
lateinit var services: MockServices lateinit var services: MockServices
private lateinit var vaultFiller: VaultFiller private lateinit var vaultFiller: VaultFiller
lateinit var bankServices: MockServices private lateinit var bankServices: MockServices
lateinit var issuerServices: MockServices private lateinit var issuerServices: MockServices
lateinit var notaryServices: MockServices private lateinit var notaryServices: MockServices
lateinit var database: CordaPersistence lateinit var database: CordaPersistence
val vault: VaultService get() = services.vaultService val vault: VaultService get() = services.vaultService
// Hibernate configuration objects // Hibernate configuration objects
lateinit var hibernateConfig: HibernateConfiguration lateinit var hibernateConfig: HibernateConfiguration
lateinit var hibernatePersister: HibernateObserver private lateinit var hibernatePersister: HibernateObserver
lateinit var sessionFactory: SessionFactory private lateinit var sessionFactory: SessionFactory
lateinit var entityManager: EntityManager private lateinit var entityManager: EntityManager
lateinit var criteriaBuilder: CriteriaBuilder private lateinit var criteriaBuilder: CriteriaBuilder
// Identities used // Identities used
private lateinit var identity: Party private lateinit var identity: Party
@ -93,7 +92,7 @@ class HibernateConfigurationTest {
private lateinit var notary: Party private lateinit var notary: Party
// test States // test States
lateinit var cashStates: List<StateAndRef<Cash.State>> private lateinit var cashStates: List<StateAndRef<Cash.State>>
@Before @Before
fun setUp() { fun setUp() {
@ -690,7 +689,7 @@ class HibernateConfigurationTest {
val queryResults = entityManager.createQuery(criteriaQuery).resultList val queryResults = entityManager.createQuery(criteriaQuery).resultList
queryResults.forEach { queryResults.forEach {
val cashState = (services.loadState(toStateRef(it.stateRef!!)) as TransactionState<Cash.State>).data val cashState = services.loadState(toStateRef(it.stateRef!!)).data as Cash.State
println("${it.stateRef} with owner: ${cashState.owner.owningKey.toBase58String()}") println("${it.stateRef} with owner: ${cashState.owner.owningKey.toBase58String()}")
} }
@ -774,7 +773,7 @@ class HibernateConfigurationTest {
// execute query // execute query
val queryResults = entityManager.createQuery(criteriaQuery).resultList val queryResults = entityManager.createQuery(criteriaQuery).resultList
queryResults.forEach { queryResults.forEach {
val cashState = (services.loadState(toStateRef(it.stateRef!!)) as TransactionState<Cash.State>).data val cashState = services.loadState(toStateRef(it.stateRef!!)).data as Cash.State
println("${it.stateRef} with owner ${cashState.owner.owningKey.toBase58String()} and participants ${cashState.participants.map { it.owningKey.toBase58String() }}") println("${it.stateRef} with owner ${cashState.owner.owningKey.toBase58String()} and participants ${cashState.participants.map { it.owningKey.toBase58String() }}")
} }
@ -913,6 +912,6 @@ class HibernateConfigurationTest {
} }
private fun toStateRef(pStateRef: PersistentStateRef): StateRef { private fun toStateRef(pStateRef: PersistentStateRef): StateRef {
return StateRef(SecureHash.parse(pStateRef.txId!!), pStateRef.index!!) return StateRef(SecureHash.parse(pStateRef.txId), pStateRef.index)
} }
} }

View File

@ -5,11 +5,7 @@ import com.google.common.jimfs.Configuration
import com.google.common.jimfs.Jimfs import com.google.common.jimfs.Jimfs
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sha256 import net.corda.core.crypto.sha256
import net.corda.core.internal.read import net.corda.core.internal.*
import net.corda.core.internal.readAll
import net.corda.core.internal.readFully
import net.corda.core.internal.write
import net.corda.core.internal.writeLines
import net.corda.core.node.services.vault.AttachmentQueryCriteria import net.corda.core.node.services.vault.AttachmentQueryCriteria
import net.corda.core.node.services.vault.AttachmentSort import net.corda.core.node.services.vault.AttachmentSort
import net.corda.core.node.services.vault.Builder import net.corda.core.node.services.vault.Builder
@ -59,7 +55,7 @@ class NodeAttachmentStorageTest {
fun `insert and retrieve`() { fun `insert and retrieve`() {
val (testJar, expectedHash) = makeTestJar() val (testJar, expectedHash) = makeTestJar()
val id = testJar.read { storage.importAttachment(it) } val id = testJar.read { storage.importAttachment(it, "test", null) }
assertEquals(expectedHash, id) assertEquals(expectedHash, id)
assertNull(storage.openAttachment(SecureHash.randomSHA256())) assertNull(storage.openAttachment(SecureHash.randomSHA256()))
@ -84,7 +80,7 @@ class NodeAttachmentStorageTest {
val (testJar, expectedHash) = makeTestJar() val (testJar, expectedHash) = makeTestJar()
val (jarB, hashB) = makeTestJar(listOf(Pair("file", "content"))) val (jarB, hashB) = makeTestJar(listOf(Pair("file", "content")))
val id = testJar.read { storage.importAttachment(it) } val id = testJar.read { storage.importAttachment(it, "test", null) }
assertEquals(expectedHash, id) assertEquals(expectedHash, id)
@ -99,7 +95,7 @@ class NodeAttachmentStorageTest {
stream.close() stream.close()
val idB = jarB.read { storage.importAttachment(it) } val idB = jarB.read { storage.importAttachment(it, "test", null) }
assertEquals(hashB, idB) assertEquals(hashB, idB)
storage.openAttachment(id)!!.openAsJAR().use { storage.openAttachment(id)!!.openAsJAR().use {
@ -119,6 +115,7 @@ class NodeAttachmentStorageTest {
val (jarB, hashB) = makeTestJar(listOf(Pair("file", "content"))) val (jarB, hashB) = makeTestJar(listOf(Pair("file", "content")))
val (jarC, hashC) = makeTestJar(listOf(Pair("magic_file", "magic_content_puff"))) val (jarC, hashC) = makeTestJar(listOf(Pair("magic_file", "magic_content_puff")))
@Suppress("DEPRECATION")
jarA.read { storage.importAttachment(it) } jarA.read { storage.importAttachment(it) }
jarB.read { storage.importAttachment(it, "uploaderB", "fileB.zip") } jarB.read { storage.importAttachment(it, "uploaderB", "fileB.zip") }
jarC.read { storage.importAttachment(it, "uploaderC", "fileC.zip") } jarC.read { storage.importAttachment(it, "uploaderC", "fileC.zip") }
@ -186,11 +183,11 @@ class NodeAttachmentStorageTest {
fun `duplicates not allowed`() { fun `duplicates not allowed`() {
val (testJar, _) = makeTestJar() val (testJar, _) = makeTestJar()
testJar.read { testJar.read {
storage.importAttachment(it) storage.importAttachment(it, "test", null)
} }
assertFailsWith<FileAlreadyExistsException> { assertFailsWith<FileAlreadyExistsException> {
testJar.read { testJar.read {
storage.importAttachment(it) storage.importAttachment(it, "test", null)
} }
} }
} }
@ -199,7 +196,7 @@ class NodeAttachmentStorageTest {
fun `corrupt entry throws exception`() { fun `corrupt entry throws exception`() {
val (testJar, _) = makeTestJar() val (testJar, _) = makeTestJar()
val id = database.transaction { val id = database.transaction {
val id = testJar.read { storage.importAttachment(it) } val id = testJar.read { storage.importAttachment(it, "test", null) }
// Corrupt the file in the store. // Corrupt the file in the store.
val bytes = testJar.readAll() val bytes = testJar.readAll()
@ -227,7 +224,7 @@ class NodeAttachmentStorageTest {
path.writeLines(listOf("Hey", "there!")) path.writeLines(listOf("Hey", "there!"))
path.read { path.read {
assertFailsWith<IllegalArgumentException>("either empty or not a JAR") { assertFailsWith<IllegalArgumentException>("either empty or not a JAR") {
storage.importAttachment(it) storage.importAttachment(it, "test", null)
} }
} }
} }

View File

@ -5,6 +5,7 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.flows.* import net.corda.core.flows.*
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.InputStreamAndHash import net.corda.core.internal.InputStreamAndHash
import net.corda.core.node.services.AttachmentId
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
@ -21,6 +22,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import java.io.InputStream
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
@ -57,10 +59,10 @@ class MaxTransactionSizeTests {
val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 2) val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 2)
val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 3) val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 3)
val flow = aliceNode.transaction { val flow = aliceNode.transaction {
val hash1 = aliceNode.services.attachments.importAttachment(bigFile1.inputStream) val hash1 = aliceNode.importAttachment(bigFile1.inputStream)
val hash2 = aliceNode.services.attachments.importAttachment(bigFile2.inputStream) val hash2 = aliceNode.importAttachment(bigFile2.inputStream)
val hash3 = aliceNode.services.attachments.importAttachment(bigFile3.inputStream) val hash3 = aliceNode.importAttachment(bigFile3.inputStream)
val hash4 = aliceNode.services.attachments.importAttachment(bigFile4.inputStream) val hash4 = aliceNode.importAttachment(bigFile4.inputStream)
assertEquals(hash1, bigFile1.sha256) assertEquals(hash1, bigFile1.sha256)
SendLargeTransactionFlow(notary, bob, hash1, hash2, hash3, hash4) SendLargeTransactionFlow(notary, bob, hash1, hash2, hash3, hash4)
} }
@ -80,10 +82,10 @@ class MaxTransactionSizeTests {
val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 2) val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 2)
val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 3) val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 3)
val flow = aliceNode.transaction { val flow = aliceNode.transaction {
val hash1 = aliceNode.services.attachments.importAttachment(bigFile1.inputStream) val hash1 = aliceNode.importAttachment(bigFile1.inputStream)
val hash2 = aliceNode.services.attachments.importAttachment(bigFile2.inputStream) val hash2 = aliceNode.importAttachment(bigFile2.inputStream)
val hash3 = aliceNode.services.attachments.importAttachment(bigFile3.inputStream) val hash3 = aliceNode.importAttachment(bigFile3.inputStream)
val hash4 = aliceNode.services.attachments.importAttachment(bigFile4.inputStream) val hash4 = aliceNode.importAttachment(bigFile4.inputStream)
assertEquals(hash1, bigFile1.sha256) assertEquals(hash1, bigFile1.sha256)
SendLargeTransactionFlow(notary, bob, hash1, hash2, hash3, hash4, verify = false) SendLargeTransactionFlow(notary, bob, hash1, hash2, hash3, hash4, verify = false)
} }
@ -94,6 +96,10 @@ class MaxTransactionSizeTests {
} }
} }
private fun StartedMockNode.importAttachment(inputStream: InputStream): AttachmentId {
return services.attachments.importAttachment(inputStream, "test", null)
}
@StartableByRPC @StartableByRPC
@InitiatingFlow @InitiatingFlow
class SendLargeTransactionFlow(private val notary: Party, class SendLargeTransactionFlow(private val notary: Party,

View File

@ -41,7 +41,6 @@ import org.junit.Test
import org.junit.rules.ExpectedException import org.junit.rules.ExpectedException
import org.junit.rules.ExternalResource import org.junit.rules.ExternalResource
import java.time.Duration import java.time.Duration
import java.time.Instant
import java.time.LocalDate import java.time.LocalDate
import java.time.ZoneOffset import java.time.ZoneOffset
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
@ -103,7 +102,7 @@ open class VaultQueryTestRule : ExternalResource(), VaultQueryParties {
override val bob = TestIdentity(BOB_NAME, 80) override val bob = TestIdentity(BOB_NAME, 80)
override val cashNotary = TestIdentity(CordaX500Name("Cash Notary Service", "Zurich", "CH"), 21) override val cashNotary = TestIdentity(CordaX500Name("Cash Notary Service", "Zurich", "CH"), 21)
override val charlie = TestIdentity(CHARLIE_NAME, 90) override val charlie = TestIdentity(CHARLIE_NAME, 90)
override val dummyCashIssuer = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10) final override val dummyCashIssuer = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10)
override val DUMMY_CASH_ISSUER = dummyCashIssuer.ref(1) override val DUMMY_CASH_ISSUER = dummyCashIssuer.ref(1)
override val dummyNotary = TestIdentity(DUMMY_NOTARY_NAME, 20) override val dummyNotary = TestIdentity(DUMMY_NOTARY_NAME, 20)
override val DUMMY_OBLIGATION_ISSUER = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10).party override val DUMMY_OBLIGATION_ISSUER = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10).party
@ -133,7 +132,7 @@ open class VaultQueryTestRule : ExternalResource(), VaultQueryParties {
cordappPackages, cordappPackages,
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity), makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity),
megaCorp, megaCorp,
moreKeys = DUMMY_NOTARY_KEY) moreKeys = *arrayOf(DUMMY_NOTARY_KEY))
database = databaseAndServices.first database = databaseAndServices.first
services = databaseAndServices.second services = databaseAndServices.second
vaultFiller = VaultFiller(services, dummyNotary) vaultFiller = VaultFiller(services, dummyNotary)
@ -151,7 +150,7 @@ open class VaultQueryTestRule : ExternalResource(), VaultQueryParties {
} }
} }
class VaultQueryRollbackRule(val vaultQueryParties: VaultQueryParties) : ExternalResource() { class VaultQueryRollbackRule(private val vaultQueryParties: VaultQueryParties) : ExternalResource() {
lateinit var transaction: DatabaseTransaction lateinit var transaction: DatabaseTransaction

View File

@ -64,7 +64,7 @@ class VaultWithCashTest {
private val servicesKey = generateKeyPair() private val servicesKey = generateKeyPair()
lateinit var services: MockServices lateinit var services: MockServices
private lateinit var vaultFiller: VaultFiller private lateinit var vaultFiller: VaultFiller
lateinit var issuerServices: MockServices private lateinit var issuerServices: MockServices
val vaultService: VaultService get() = services.vaultService val vaultService: VaultService get() = services.vaultService
lateinit var database: CordaPersistence lateinit var database: CordaPersistence
private lateinit var notaryServices: MockServices private lateinit var notaryServices: MockServices
@ -77,7 +77,7 @@ class VaultWithCashTest {
cordappPackages, cordappPackages,
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity), makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity),
TestIdentity(MEGA_CORP.name, servicesKey), TestIdentity(MEGA_CORP.name, servicesKey),
moreKeys = dummyNotary.keyPair) moreKeys = *arrayOf(dummyNotary.keyPair))
database = databaseAndServices.first database = databaseAndServices.first
services = databaseAndServices.second services = databaseAndServices.second
vaultFiller = VaultFiller(services, dummyNotary) vaultFiller = VaultFiller(services, dummyNotary)
@ -130,7 +130,7 @@ class VaultWithCashTest {
database.transaction { database.transaction {
// A tx that spends our money. // A tx that spends our money.
val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY) val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY)
Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, BOB) Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, services.myInfo.legalIdentitiesAndCerts.single(), BOB)
val spendPTX = services.signInitialTransaction(spendTXBuilder, freshKey) val spendPTX = services.signInitialTransaction(spendTXBuilder, freshKey)
notaryServices.addSignature(spendPTX) notaryServices.addSignature(spendPTX)
} }
@ -178,7 +178,7 @@ class VaultWithCashTest {
val first = backgroundExecutor.fork { val first = backgroundExecutor.fork {
database.transaction { database.transaction {
val txn1Builder = TransactionBuilder(DUMMY_NOTARY) val txn1Builder = TransactionBuilder(DUMMY_NOTARY)
Cash.generateSpend(services, txn1Builder, 60.DOLLARS, BOB) Cash.generateSpend(services, txn1Builder, 60.DOLLARS, services.myInfo.legalIdentitiesAndCerts.single(), BOB)
val ptxn1 = notaryServices.signInitialTransaction(txn1Builder) val ptxn1 = notaryServices.signInitialTransaction(txn1Builder)
val txn1 = services.addSignature(ptxn1, freshKey) val txn1 = services.addSignature(ptxn1, freshKey)
println("txn1: ${txn1.id} spent ${((txn1.tx.outputs[0].data) as Cash.State).amount}") println("txn1: ${txn1.id} spent ${((txn1.tx.outputs[0].data) as Cash.State).amount}")
@ -209,7 +209,7 @@ class VaultWithCashTest {
val second = backgroundExecutor.fork { val second = backgroundExecutor.fork {
database.transaction { database.transaction {
val txn2Builder = TransactionBuilder(DUMMY_NOTARY) val txn2Builder = TransactionBuilder(DUMMY_NOTARY)
Cash.generateSpend(services, txn2Builder, 80.DOLLARS, BOB) Cash.generateSpend(services, txn2Builder, 80.DOLLARS, services.myInfo.legalIdentitiesAndCerts.single(), BOB)
val ptxn2 = notaryServices.signInitialTransaction(txn2Builder) val ptxn2 = notaryServices.signInitialTransaction(txn2Builder)
val txn2 = services.addSignature(ptxn2, freshKey) val txn2 = services.addSignature(ptxn2, freshKey)
println("txn2: ${txn2.id} spent ${((txn2.tx.outputs[0].data) as Cash.State).amount}") println("txn2: ${txn2.id} spent ${((txn2.tx.outputs[0].data) as Cash.State).amount}")
@ -333,7 +333,7 @@ class VaultWithCashTest {
database.transaction { database.transaction {
// A tx that spends our money. // A tx that spends our money.
val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY) val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY)
Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, BOB) Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, services.myInfo.legalIdentitiesAndCerts.single(), BOB)
val spendPTX = notaryServices.signInitialTransaction(spendTXBuilder) val spendPTX = notaryServices.signInitialTransaction(spendTXBuilder)
val spendTX = services.addSignature(spendPTX, freshKey) val spendTX = services.addSignature(spendPTX, freshKey)
services.recordTransactions(spendTX) services.recordTransactions(spendTX)

View File

@ -13,7 +13,6 @@ import rx.Observable
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import java.io.Closeable import java.io.Closeable
import java.util.* import java.util.*
import kotlin.test.fail
class ObservablesTests { class ObservablesTests {
private fun isInDatabaseTransaction() = contextTransactionOrNull != null private fun isInDatabaseTransaction() = contextTransactionOrNull != null
@ -58,7 +57,7 @@ class ObservablesTests {
assertThat(secondEvent.get()).isEqualTo(0 to false) assertThat(secondEvent.get()).isEqualTo(0 to false)
} }
class TestException : Exception("Synthetic exception for tests") {} class TestException : Exception("Synthetic exception for tests")
@Test @Test
fun `bufferUntilDatabaseCommit swallows if transaction rolled back`() { fun `bufferUntilDatabaseCommit swallows if transaction rolled back`() {
@ -83,7 +82,6 @@ class ObservablesTests {
assertThat(secondEvent.isDone).isFalse() assertThat(secondEvent.isDone).isFalse()
throw TestException() throw TestException()
} }
fail("Should not have successfully completed transaction")
} catch (e: TestException) { } catch (e: TestException) {
} }
assertThat(secondEvent.isDone).isFalse() assertThat(secondEvent.isDone).isFalse()
@ -115,7 +113,6 @@ class ObservablesTests {
assertThat(secondEvent.isDone).isFalse() assertThat(secondEvent.isDone).isFalse()
throw TestException() throw TestException()
} }
fail("Should not have successfully completed transaction")
} catch (e: TestException) { } catch (e: TestException) {
} }
assertThat(secondEvent.isDone).isTrue() assertThat(secondEvent.isDone).isTrue()

View File

@ -1,10 +1,8 @@
package net.corda.attachmentdemo package net.corda.attachmentdemo
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.all
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.DriverParameters
@ -20,14 +18,7 @@ class AttachmentDemoTest {
fun `attachment demo using a 10MB zip file`() { fun `attachment demo using a 10MB zip file`() {
val numOfExpectedBytes = 10_000_000 val numOfExpectedBytes = 10_000_000
driver(DriverParameters(isDebug = true, portAllocation = PortAllocation.Incremental(20000))) { driver(DriverParameters(isDebug = true, portAllocation = PortAllocation.Incremental(20000))) {
val demoUser = listOf(User("demo", "demo", setOf( val demoUser = listOf(User("demo", "demo", setOf(all())))
startFlow<AttachmentDemoFlow>(),
invokeRpc(CordaRPCOps::attachmentExists),
invokeRpc(CordaRPCOps::uploadAttachment),
invokeRpc(CordaRPCOps::openAttachment),
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed)
)))
val (nodeA, nodeB) = listOf( val (nodeA, nodeB) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = demoUser, maximumHeapSize = "1g") startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = demoUser, maximumHeapSize = "1g")

View File

@ -86,14 +86,12 @@ fun sender(rpc: CordaRPCOps, numOfClearBytes: Int = 1024) { // default size 1K.
} }
private fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.SHA256, executor: ScheduledExecutorService) { private fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.SHA256, executor: ScheduledExecutorService) {
// Get the identity key of the other side (the recipient). // Get the identity key of the other side (the recipient).
val notaryFuture: CordaFuture<Party> = poll(executor, DUMMY_NOTARY_NAME.toString()) { rpc.wellKnownPartyFromX500Name(DUMMY_NOTARY_NAME) } val notaryFuture: CordaFuture<Party> = poll(executor, DUMMY_NOTARY_NAME.toString()) { rpc.wellKnownPartyFromX500Name(DUMMY_NOTARY_NAME) }
val otherSideFuture: CordaFuture<Party> = poll(executor, DUMMY_BANK_B_NAME.toString()) { rpc.wellKnownPartyFromX500Name(DUMMY_BANK_B_NAME) } val otherSideFuture: CordaFuture<Party> = poll(executor, DUMMY_BANK_B_NAME.toString()) { rpc.wellKnownPartyFromX500Name(DUMMY_BANK_B_NAME) }
// Make sure we have the file in storage // Make sure we have the file in storage
if (!rpc.attachmentExists(hash)) { if (!rpc.attachmentExists(hash)) {
inputStream.use { inputStream.use {
val avail = inputStream.available()
val id = rpc.uploadAttachment(it) val id = rpc.uploadAttachment(it)
require(hash == id) { "Id was '$id' instead of '$hash'" } require(hash == id) { "Id was '$id' instead of '$hash'" }
} }
@ -133,6 +131,7 @@ class AttachmentDemoFlow(private val otherSide: Party,
} }
} }
@Suppress("DEPRECATION")
// DOCSTART 1 // DOCSTART 1
fun recipient(rpc: CordaRPCOps, webPort: Int) { fun recipient(rpc: CordaRPCOps, webPort: Int) {
println("Waiting to receive transaction ...") println("Waiting to receive transaction ...")

View File

@ -1,3 +1,5 @@
@file:Suppress("DEPRECATION")
package net.corda.test.spring package net.corda.test.spring
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture

View File

@ -13,7 +13,7 @@ public class JavaGenericsTest {
private final Integer v; private final Integer v;
private Inner(Integer v) { this.v = v; } private Inner(Integer v) { this.v = v; }
public Integer getV() { return v; } Integer getV() { return v; }
} }
private static class A<T> { private static class A<T> {
@ -25,7 +25,7 @@ public class JavaGenericsTest {
@Test @Test
public void basicGeneric() throws NotSerializableException { public void basicGeneric() throws NotSerializableException {
A a1 = new A(1); A a1 = new A<>(1);
SerializerFactory factory = testDefaultFactory(); SerializerFactory factory = testDefaultFactory();
@ -66,7 +66,7 @@ public class JavaGenericsTest {
@Test @Test
public void forceWildcard() throws NotSerializableException { public void forceWildcard() throws NotSerializableException {
SerializedBytes<?> bytes = forceWildcardSerialize(new A(new Inner(29))); SerializedBytes<?> bytes = forceWildcardSerialize(new A<>(new Inner(29)));
Inner i = (Inner)forceWildcardDeserialize(bytes).getT(); Inner i = (Inner)forceWildcardDeserialize(bytes).getT();
assertEquals(29, i.getV()); assertEquals(29, i.getV());
} }
@ -75,7 +75,7 @@ public class JavaGenericsTest {
public void forceWildcardSharedFactory() throws NotSerializableException { public void forceWildcardSharedFactory() throws NotSerializableException {
SerializerFactory factory = testDefaultFactory(); SerializerFactory factory = testDefaultFactory();
SerializedBytes<?> bytes = forceWildcardSerializeFactory(new A(new Inner(29)), factory); SerializedBytes<?> bytes = forceWildcardSerializeFactory(new A<>(new Inner(29)), factory);
Inner i = (Inner)forceWildcardDeserializeFactory(bytes, factory).getT(); Inner i = (Inner)forceWildcardDeserializeFactory(bytes, factory).getT();
assertEquals(29, i.getV()); assertEquals(29, i.getV());

View File

@ -7,6 +7,7 @@ import java.io.NotSerializableException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Map; import java.util.Map;
import static net.corda.core.internal.InternalUtils.uncheckedCast;
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory; import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -30,6 +31,7 @@ public class JavaPrivatePropertyTests {
B(Boolean b) { this.b = b; } B(Boolean b) { this.b = b; }
@SuppressWarnings("unused")
public Boolean isB() { public Boolean isB() {
return this.b; return this.b;
} }
@ -38,6 +40,7 @@ public class JavaPrivatePropertyTests {
static class B2 { static class B2 {
private Boolean b; private Boolean b;
@SuppressWarnings("unused")
public Boolean isB() { public Boolean isB() {
return this.b; return this.b;
} }
@ -50,6 +53,7 @@ public class JavaPrivatePropertyTests {
static class B3 { static class B3 {
private Boolean b; private Boolean b;
@SuppressWarnings("unused")
// break the BEAN format explicitly (i.e. it's not isB) // break the BEAN format explicitly (i.e. it's not isB)
public Boolean isb() { public Boolean isb() {
return this.b; return this.b;
@ -67,6 +71,7 @@ public class JavaPrivatePropertyTests {
return this.a; return this.a;
} }
@SuppressWarnings("unused")
public Boolean isA() { public Boolean isA() {
return this.a > 0; return this.a > 0;
} }
@ -145,7 +150,7 @@ public class JavaPrivatePropertyTests {
Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor"); Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor");
f.setAccessible(true); f.setAccessible(true);
Map<?, AMQPSerializer<?>> serializersByDescriptor = (Map<?, AMQPSerializer<?>>) f.get(factory); Map<?, AMQPSerializer<?>> serializersByDescriptor = uncheckedCast(f.get(factory));
assertEquals(1, serializersByDescriptor.size()); assertEquals(1, serializersByDescriptor.size());
ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]); ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]);
@ -172,7 +177,7 @@ public class JavaPrivatePropertyTests {
// //
Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor"); Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor");
f.setAccessible(true); f.setAccessible(true);
Map<?, AMQPSerializer<?>> serializersByDescriptor = (Map<?, AMQPSerializer<?>>) f.get(factory); Map<?, AMQPSerializer<?>> serializersByDescriptor = uncheckedCast(f.get(factory));
assertEquals(1, serializersByDescriptor.size()); assertEquals(1, serializersByDescriptor.size());
ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]); ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]);

View File

@ -17,7 +17,6 @@ import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class ContractAttachmentSerializerTest { class ContractAttachmentSerializerTest {
@Rule @Rule
@JvmField @JvmField
val testSerialization = SerializationEnvironmentRule() val testSerialization = SerializationEnvironmentRule()
@ -51,7 +50,7 @@ class ContractAttachmentSerializerTest {
fun `write contract attachment and read it back using token context`() { fun `write contract attachment and read it back using token context`() {
val attachment = GeneratedAttachment("test".toByteArray()) val attachment = GeneratedAttachment("test".toByteArray())
mockServices.attachments.importAttachment(attachment.open()) mockServices.attachments.importAttachment(attachment.open(), "test", null)
val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID) val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID)
val serialized = contractAttachment.serialize(factory, contextWithToken) val serialized = contractAttachment.serialize(factory, contextWithToken)
@ -68,7 +67,7 @@ class ContractAttachmentSerializerTest {
val largeAttachmentSize = 1024 * 1024 val largeAttachmentSize = 1024 * 1024
val attachment = GeneratedAttachment(ByteArray(largeAttachmentSize)) val attachment = GeneratedAttachment(ByteArray(largeAttachmentSize))
mockServices.attachments.importAttachment(attachment.open()) mockServices.attachments.importAttachment(attachment.open(), "test", null)
val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID) val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID)
val serialized = contractAttachment.serialize(factory, contextWithToken) val serialized = contractAttachment.serialize(factory, contextWithToken)

View File

@ -2,10 +2,9 @@ package net.corda.serialization.internal.amqp
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.serialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import net.corda.serialization.internal.amqp.testutils.testName import net.corda.serialization.internal.amqp.testutils.testName
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
import java.io.NotSerializableException import java.io.NotSerializableException
@ -28,7 +27,7 @@ class ErrorMessagesTests {
val testname = "${javaClass.name}\$${testName()}" val testname = "${javaClass.name}\$${testName()}"
Assertions.assertThatThrownBy { assertThatThrownBy {
TestSerializationOutput(VERBOSE, sf).serialize(C(1)) TestSerializationOutput(VERBOSE, sf).serialize(C(1))
}.isInstanceOf(NotSerializableException::class.java).hasMessage(errMsg("a", testname)) }.isInstanceOf(NotSerializableException::class.java).hasMessage(errMsg("a", testname))
} }
@ -43,7 +42,7 @@ class ErrorMessagesTests {
val testname = "${javaClass.name}\$${testName()}" val testname = "${javaClass.name}\$${testName()}"
Assertions.assertThatThrownBy { assertThatThrownBy {
TestSerializationOutput(VERBOSE, sf).serialize(C(1, 2)) TestSerializationOutput(VERBOSE, sf).serialize(C(1, 2))
}.isInstanceOf(NotSerializableException::class.java).hasMessage(errMsg("b", testname)) }.isInstanceOf(NotSerializableException::class.java).hasMessage(errMsg("b", testname))
} }
@ -55,28 +54,27 @@ class ErrorMessagesTests {
// despite b being private, the getter we've added is public and thus allows for the serialisation // despite b being private, the getter we've added is public and thus allows for the serialisation
// of the object // of the object
data class C(val a: Int, private val b: Int) { data class C(val a: Int, private val b: Int) {
public fun getB() = b @Suppress("unused")
fun getB() = b
} }
val sf = testDefaultFactory() val sf = testDefaultFactory()
val testname = "${javaClass.name}\$${testName()}"
val bytes = TestSerializationOutput(VERBOSE, sf).serialize(C(1, 2)) val bytes = TestSerializationOutput(VERBOSE, sf).serialize(C(1, 2))
val c = DeserializationInput(sf).deserialize(bytes) DeserializationInput(sf).deserialize(bytes)
} }
// Java allows this to be set at the class level yet Kotlin doesn't for some reason // Java allows this to be set at the class level yet Kotlin doesn't for some reason
@Ignore("Current behaviour allows for the serialization of objects with private members, this will be disallowed at some point in the future") @Ignore("Current behaviour allows for the serialization of objects with private members, this will be disallowed at some point in the future")
@Test @Test
fun protectedProperty() { fun protectedProperty() {
data class C(protected val a: Int) open class C(@Suppress("unused") protected val a: Int)
val sf = testDefaultFactory() val sf = testDefaultFactory()
val testname = "${javaClass.name}\$${testName()}" val testname = "${javaClass.name}\$${testName()}"
Assertions.assertThatThrownBy { assertThatThrownBy {
TestSerializationOutput(VERBOSE, sf).serialize(C(1)) TestSerializationOutput(VERBOSE, sf).serialize(C(1))
}.isInstanceOf(NotSerializableException::class.java).hasMessage(errMsg("a", testname)) }.isInstanceOf(NotSerializableException::class.java).hasMessage(errMsg("a", testname))
} }

View File

@ -277,7 +277,7 @@ class GenericsTests {
private fun fingerprintingDiffersStrip(state: Any) { private fun fingerprintingDiffersStrip(state: Any) {
class cl : ClassLoader() class cl : ClassLoader()
val m = ClassLoader::class.java.getDeclaredMethod("findLoadedClass", *arrayOf<Class<*>>(String::class.java)) val m = ClassLoader::class.java.getDeclaredMethod("findLoadedClass", String::class.java)
m.isAccessible = true m.isAccessible = true
val factory1 = testDefaultFactory() val factory1 = testDefaultFactory()
@ -295,16 +295,16 @@ class GenericsTests {
// now deserialise those objects // now deserialise those objects
val factory3 = testDefaultFactory() val factory3 = testDefaultFactory()
factory3.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) factory3.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val des1 = DeserializationInput(factory3).deserializeAndReturnEnvelope(ser1.obj) DeserializationInput(factory3).deserializeAndReturnEnvelope(ser1.obj)
val factory4 = SerializerFactory(AllWhitelist, cl()) val factory4 = SerializerFactory(AllWhitelist, cl())
factory4.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) factory4.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val des2 = DeserializationInput(factory4).deserializeAndReturnEnvelope(ser2.obj) DeserializationInput(factory4).deserializeAndReturnEnvelope(ser2.obj)
} }
@Test @Test
fun fingerprintingDiffers() { fun fingerprintingDiffers() {
val state = TransactionState<TestContractState> ( val state = TransactionState(
TestContractState(listOf(miniCorp.party)), TestContractState(listOf(miniCorp.party)),
"wibble", miniCorp.party, "wibble", miniCorp.party,
encumbrance = null, encumbrance = null,
@ -317,7 +317,7 @@ class GenericsTests {
@Test @Test
fun fingerprintingDiffersList() { fun fingerprintingDiffersList() {
val state = TransactionState<TestContractState> ( val state = TransactionState(
TestContractState(listOf(miniCorp.party)), TestContractState(listOf(miniCorp.party)),
"wibble", miniCorp.party, "wibble", miniCorp.party,
encumbrance = null, encumbrance = null,

View File

@ -97,7 +97,7 @@ class PrivatePropertyTests {
@ConstructorForDeserialization @ConstructorForDeserialization
constructor() : this(0, 0) constructor() : this(0, 0)
fun setA(a: Int, b: Int) { this.a = a } fun setA(a: Int, @Suppress("UNUSED_PARAMETER") b: Int) { this.a = a }
fun getA() = a fun getA() = a
} }

View File

@ -4,7 +4,8 @@ import net.corda.core.serialization.ConstructorForDeserialization
import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.serialize import net.corda.serialization.internal.amqp.testutils.serialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test import org.junit.Test
class RoundTripTests { class RoundTripTests {
@ -16,20 +17,15 @@ class RoundTripTests {
val bytes = SerializationOutput(factory).serialize(C(mutableListOf("a", "b", "c"))) val bytes = SerializationOutput(factory).serialize(C(mutableListOf("a", "b", "c")))
val newC = DeserializationInput(factory).deserialize(bytes) val newC = DeserializationInput(factory).deserialize(bytes)
Assertions.assertThatThrownBy { assertThatThrownBy {
newC.l.add("d") newC.l.add("d")
}.isInstanceOf(UnsupportedOperationException::class.java) }.isInstanceOf(UnsupportedOperationException::class.java)
} }
@Test @Test
fun mutableStillMutable() { fun mutableStillMutable() {
class C { class C(l: MutableList<String>) {
val l: MutableList<String> val l: MutableList<String> = l.toMutableList()
@Suppress("Unused")
constructor (l: MutableList<String>) {
this.l = l.toMutableList()
}
} }
val factory = testDefaultFactoryNoEvolution() val factory = testDefaultFactoryNoEvolution()
@ -37,6 +33,7 @@ class RoundTripTests {
val newC = DeserializationInput(factory).deserialize(bytes) val newC = DeserializationInput(factory).deserialize(bytes)
newC.l.add("d") newC.l.add("d")
assertThat(newC.l).containsExactly("a", "b", "c", "d")
} }
@Test @Test
@ -52,6 +49,7 @@ class RoundTripTests {
val newC = DeserializationInput(factory).deserialize(bytes) val newC = DeserializationInput(factory).deserialize(bytes)
newC.l.add("d") newC.l.add("d")
assertThat(newC.l).containsExactly("a", "b", "c", "d")
} }
@Test @Test
@ -61,6 +59,6 @@ class RoundTripTests {
val factory = testDefaultFactoryNoEvolution() val factory = testDefaultFactoryNoEvolution()
val bytes = SerializationOutput(factory).serialize(C(listOf("a", "b", "c"))) val bytes = SerializationOutput(factory).serialize(C(listOf("a", "b", "c")))
val newC = DeserializationInput(factory).deserialize(bytes) val newC = DeserializationInput(factory).deserialize(bytes)
val newC2 = newC.copy(l = (newC.l + "d")) newC.copy(l = (newC.l + "d"))
} }
} }

View File

@ -888,6 +888,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
class GenericSubclass(param: OtherGeneric<String>) : GenericSuperclass<String>(param) { class GenericSubclass(param: OtherGeneric<String>) : GenericSuperclass<String>(param) {
override fun equals(other: Any?): Boolean = other is GenericSubclass // This is a bit lame but we just want to check it doesn't throw exceptions override fun equals(other: Any?): Boolean = other is GenericSubclass // This is a bit lame but we just want to check it doesn't throw exceptions
override fun hashCode(): Int = javaClass.hashCode()
} }
@Test @Test
@ -966,8 +967,10 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
assertSame(objCopy.a, objCopy.b) assertSame(objCopy.a, objCopy.b)
} }
data class Spike private constructor(val a: String) { class Spike private constructor(val a: String) {
constructor() : this("a") constructor() : this("a")
override fun equals(other: Any?): Boolean = other is Spike && other.a == this.a
override fun hashCode(): Int = a.hashCode()
} }
@Test @Test
@ -1028,7 +1031,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
serdes(obj, factory, factory2) serdes(obj, factory, factory2)
} }
data class ByteArrays(val a: ByteArray, val b: ByteArray) class ByteArrays(val a: ByteArray, val b: ByteArray)
@Test @Test
fun `test byte arrays not reference counted`() { fun `test byte arrays not reference counted`() {
@ -1162,7 +1165,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
} }
// //
// Example stacktrace that this test is tryint to reproduce // Example stacktrace that this test is trying to reproduce
// //
// java.lang.IllegalArgumentException: // java.lang.IllegalArgumentException:
// net.corda.core.contracts.TransactionState -> // net.corda.core.contracts.TransactionState ->
@ -1179,10 +1182,6 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
// //
@Test @Test
fun reproduceWrongNumberOfArguments() { fun reproduceWrongNumberOfArguments() {
val field = SerializerFactory::class.java.getDeclaredField("serializersByType").apply {
this.isAccessible = true
}
data class C(val a: Amount<Currency>) data class C(val a: Amount<Currency>)
val factory = testDefaultFactoryNoEvolution() val factory = testDefaultFactoryNoEvolution()
@ -1337,7 +1336,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
val bytes = SerializationOutput(testDefaultFactory()).serialize(i) val bytes = SerializationOutput(testDefaultFactory()).serialize(i)
try { try {
val i2 = DeserializationInput(testDefaultFactory()).deserialize(bytes) DeserializationInput(testDefaultFactory()).deserialize(bytes)
} catch (e: NotSerializableException) { } catch (e: NotSerializableException) {
throw Error("Deserializing serialized \$C should not throw") throw Error("Deserializing serialized \$C should not throw")
} }

View File

@ -35,7 +35,7 @@ class SerializationPropertyOrdering {
val u = User(l,l) val u = User(l,l)
val output = TestSerializationOutput(VERBOSE, sf).serializeAndReturnSchema(u) val output = TestSerializationOutput(VERBOSE, sf).serializeAndReturnSchema(u)
val input = DeserializationInput(sf).deserialize(output.obj) DeserializationInput(sf).deserialize(output.obj)
} }
@Test @Test

View File

@ -34,7 +34,7 @@ class MockKeyManagementService(val identityService: IdentityService,
override fun filterMyKeys(candidateKeys: Iterable<PublicKey>): Iterable<PublicKey> = candidateKeys.filter { it in this.keys } override fun filterMyKeys(candidateKeys: Iterable<PublicKey>): Iterable<PublicKey> = candidateKeys.filter { it in this.keys }
override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate { 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 = net.corda.node.services.keys.getSigner(getSigningKeyPair(publicKey)) private fun getSigner(publicKey: PublicKey): ContentSigner = net.corda.node.services.keys.getSigner(getSigningKeyPair(publicKey))

View File

@ -67,10 +67,10 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
// Wait until ports are released // Wait until ports are released
val portNotBoundChecks = nodes.flatMap { val portNotBoundChecks = nodes.flatMap {
listOf( listOf(
it.internals.configuration.p2pAddress.let { addressMustNotBeBoundFuture(shutdownExecutor, it) }, addressMustNotBeBoundFuture(shutdownExecutor, it.internals.configuration.p2pAddress),
it.internals.configuration.rpcOptions.address?.let { addressMustNotBeBoundFuture(shutdownExecutor, it) } addressMustNotBeBoundFuture(shutdownExecutor, it.internals.configuration.rpcOptions.address)
) )
}.filterNotNull() }
nodes.clear() nodes.clear()
portNotBoundChecks.transpose().getOrThrow() portNotBoundChecks.transpose().getOrThrow()
} finally { } finally {

View File

@ -1,11 +1,14 @@
package net.corda.testing.internal package net.corda.testing.internal
import net.corda.core.contracts.*
import net.corda.core.crypto.Crypto import net.corda.core.crypto.Crypto
import net.corda.core.crypto.Crypto.generateKeyPair import net.corda.core.crypto.Crypto.generateKeyPair
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.transactions.WireTransaction
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.node.services.config.configureDevKeyAndTrustStores import net.corda.node.services.config.configureDevKeyAndTrustStores
@ -139,3 +142,15 @@ fun createNodeSslConfig(path: Path, name: CordaX500Name = CordaX500Name("MegaCor
return sslConfig return sslConfig
} }
/** This is the same as the deprecated [WireTransaction] c'tor but avoids the deprecation warning. */
fun createWireTransaction(inputs: List<StateRef>,
attachments: List<SecureHash>,
outputs: List<TransactionState<*>>,
commands: List<Command<*>>,
notary: Party?,
timeWindow: TimeWindow?,
privacySalt: PrivacySalt = PrivacySalt()): WireTransaction {
val componentGroups = WireTransaction.createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow)
return WireTransaction(componentGroups, privacySalt)
}

View File

@ -186,6 +186,7 @@ class NodeTerminalView : Fragment() {
invoke = ::pollCashBalances invoke = ::pollCashBalances
) )
@Suppress("DEPRECATION")
private fun initialise(config: NodeConfigWrapper, ops: CordaRPCOps) { private fun initialise(config: NodeConfigWrapper, ops: CordaRPCOps) {
try { try {
val (txInit, txNext) = ops.internalVerifiedTransactionsFeed() val (txInit, txNext) = ops.internalVerifiedTransactionsFeed()

View File

@ -13,7 +13,6 @@ import java.io.File
class CommandLineInterface { class CommandLineInterface {
fun run(parsedArgs: CliParser) { fun run(parsedArgs: CliParser) {
val baseDir = parsedArgs.baseDirectory val baseDir = parsedArgs.baseDirectory
val cacheDir = File(baseDir, Constants.BOOTSTRAPPER_DIR_NAME) val cacheDir = File(baseDir, Constants.BOOTSTRAPPER_DIR_NAME)
@ -37,7 +36,7 @@ class CommandLineInterface {
.build().getOrThrow() .build().getOrThrow()
persistContext(contextFile, objectMapper, context) persistContext(contextFile, objectMapper, context)
} else { } else {
val context = setupContextFromExisting(contextFile, objectMapper, networkName) val context = setupContextFromExisting(contextFile, objectMapper)
val (_, instantiator, _) = Backend.fromContext(context, cacheDir) val (_, instantiator, _) = Backend.fromContext(context, cacheDir)
val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context)) val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context))
parsedArgs.nodesToAdd.map { parsedArgs.nodesToAdd.map {
@ -48,7 +47,7 @@ class CommandLineInterface {
} }
private fun setupContextFromExisting(contextFile: File, objectMapper: ObjectMapper, networkName: String): Context { private fun setupContextFromExisting(contextFile: File, objectMapper: ObjectMapper): Context {
return contextFile.let { return contextFile.let {
if (it.exists()) { if (it.exists()) {
it.inputStream().use { it.inputStream().use {

View File

@ -23,7 +23,7 @@ class Context(val networkName: String, val backendType: Backend.BackendType, bac
var extraParams = ConcurrentHashMap<String, String>(backendOptions) var extraParams = ConcurrentHashMap<String, String>(backendOptions)
private fun registerNode(name: String, nodeInstanceRequest: NodeInstanceRequest) { private fun registerNode(name: String, nodeInstanceRequest: NodeInstanceRequest) {
nodes.computeIfAbsent(name, { _ -> ConcurrentHashSet() }).add(nodeInstanceRequest.toPersistable()) nodes.computeIfAbsent(name) { ConcurrentHashSet() }.add(nodeInstanceRequest.toPersistable())
} }
fun registerNode(request: NodeInstanceRequest) { fun registerNode(request: NodeInstanceRequest) {
@ -53,7 +53,7 @@ class Context(val networkName: String, val backendType: Backend.BackendType, bac
nodeInstanceRequest.actualX500, nodeInstanceRequest.actualX500,
nodeInstanceRequest.localImageId, nodeInstanceRequest.localImageId,
nodeInstanceRequest.remoteImageName, nodeInstanceRequest.remoteImageName,
nodeInstanceRequest.nodeConfig.rpcOptions.address!!.port, nodeInstanceRequest.nodeConfig.rpcOptions.address.port,
nodeInstanceRequest.expectedFqName, nodeInstanceRequest.expectedFqName,
"", "",
"" ""
@ -62,8 +62,7 @@ class Context(val networkName: String, val backendType: Backend.BackendType, bac
} }
} }
fun NodeInstanceRequest.toPersistable(): PersistableNodeInstance { private fun NodeInstanceRequest.toPersistable(): PersistableNodeInstance {
return fromInstanceRequest(this) return fromInstanceRequest(this)
} }
} }

View File

@ -2,12 +2,11 @@ package net.corda.bootstrapper.nodes
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import net.corda.bootstrapper.Constants import net.corda.bootstrapper.Constants
import org.slf4j.LoggerFactory import net.corda.core.utilities.contextLogger
import java.io.File import java.io.File
class NodeFinder(private val scratchDir: File) { class NodeFinder(private val scratchDir: File) {
fun findNodes(): List<FoundNode> { fun findNodes(): List<FoundNode> {
return scratchDir.walkBottomUp().filter { it.name == "node.conf" && !it.absolutePath.contains(Constants.BOOTSTRAPPER_DIR_NAME) }.map { return scratchDir.walkBottomUp().filter { it.name == "node.conf" && !it.absolutePath.contains(Constants.BOOTSTRAPPER_DIR_NAME) }.map {
try { try {
@ -17,7 +16,7 @@ class NodeFinder(private val scratchDir: File) {
} }
}.filterNotNull() }.filterNotNull()
.filter { !it.first.hasPath("notary") } .filter { !it.first.hasPath("notary") }
.map { (nodeConfig, nodeConfigFile) -> .map { (_, nodeConfigFile) ->
LOG.info("We've found a node with name: ${nodeConfigFile.parentFile.name}") LOG.info("We've found a node with name: ${nodeConfigFile.parentFile.name}")
FoundNode(nodeConfigFile, nodeConfigFile.parentFile) FoundNode(nodeConfigFile, nodeConfigFile.parentFile)
}.toList() }.toList()
@ -25,7 +24,7 @@ class NodeFinder(private val scratchDir: File) {
} }
companion object { companion object {
val LOG = LoggerFactory.getLogger(NodeFinder::class.java) val LOG = contextLogger()
} }
} }

View File

@ -39,40 +39,37 @@ class NodeInstantiator(val instantiator: Instantiator,
} }
fun instantiateNodeInstance(request: Context.PersistableNodeInstance): CompletableFuture<InstanceInfo> { fun instantiateNodeInstance(request: Context.PersistableNodeInstance): CompletableFuture<InstanceInfo> {
return instantiateNodeInstance(request.remoteImageName, request.rpcPort!!, request.instanceName, request.fqdn, request.instanceX500).thenApplyAsync { return instantiateNodeInstance(request.remoteImageName, request.instanceName, request.fqdn, request.instanceX500).thenApplyAsync {
InstanceInfo(request.groupName, request.instanceName, request.fqdn, it.first, it.second) InstanceInfo(request.groupName, request.instanceName, request.fqdn, it.first, it.second)
} }
} }
fun instantiateNodeInstance(request: NodeInstanceRequest): CompletableFuture<NodeInstance> { fun instantiateNodeInstance(request: NodeInstanceRequest): CompletableFuture<NodeInstance> {
return instantiateNodeInstance(request.remoteImageName, request.nodeConfig.rpcOptions.address!!.port, request.nodeInstanceName, request.expectedFqName, request.actualX500) return instantiateNodeInstance(request.remoteImageName, request.nodeInstanceName, request.expectedFqName, request.actualX500)
.thenApplyAsync { (reachableName, portMapping) -> .thenApplyAsync { (reachableName, portMapping) ->
request.toNodeInstance(reachableName, portMapping) request.toNodeInstance(reachableName, portMapping)
} }
} }
fun instantiateNotaryInstance(request: NodeInstanceRequest): CompletableFuture<NodeInstance> { fun instantiateNotaryInstance(request: NodeInstanceRequest): CompletableFuture<NodeInstance> {
return instantiateNotaryInstance(request.remoteImageName, request.nodeConfig.rpcOptions.address!!.port, request.nodeInstanceName, request.expectedFqName) return instantiateNotaryInstance(request.remoteImageName, request.nodeInstanceName, request.expectedFqName)
.thenApplyAsync { (reachableName, portMapping) -> .thenApplyAsync { (reachableName, portMapping) ->
request.toNodeInstance(reachableName, portMapping) request.toNodeInstance(reachableName, portMapping)
} }
} }
private fun instantiateNotaryInstance(remoteImageName: String, private fun instantiateNotaryInstance(remoteImageName: String,
rpcPort: Int,
nodeInstanceName: String, nodeInstanceName: String,
expectedFqName: String): CompletableFuture<Pair<String, Map<Int, Int>>> { expectedFqName: String): CompletableFuture<Pair<String, Map<Int, Int>>> {
return instantiator.instantiateContainer( return instantiator.instantiateContainer(
remoteImageName, remoteImageName,
listOf(Constants.NODE_P2P_PORT, Constants.NODE_RPC_PORT, Constants.NODE_SSHD_PORT), listOf(Constants.NODE_P2P_PORT, Constants.NODE_RPC_PORT, Constants.NODE_SSHD_PORT),
nodeInstanceName, nodeInstanceName,
mapOf("OUR_NAME" to expectedFqName, mapOf("OUR_NAME" to expectedFqName, "OUR_PORT" to Constants.NODE_P2P_PORT.toString())
"OUR_PORT" to Constants.NODE_P2P_PORT.toString())
) )
} }
private fun instantiateNodeInstance(remoteImageName: String, private fun instantiateNodeInstance(remoteImageName: String,
rpcPort: Int,
nodeInstanceName: String, nodeInstanceName: String,
expectedFqName: String, expectedFqName: String,
actualX500: String): CompletableFuture<Pair<String, Map<Int, Int>>> { actualX500: String): CompletableFuture<Pair<String, Map<Int, Int>>> {

View File

@ -7,13 +7,12 @@ import net.corda.serialization.internal.AMQP_P2P_CONTEXT
import net.corda.serialization.internal.AMQP_STORAGE_CONTEXT import net.corda.serialization.internal.AMQP_STORAGE_CONTEXT
import net.corda.serialization.internal.SerializationFactoryImpl import net.corda.serialization.internal.SerializationFactoryImpl
class SerializationEngine { class SerializationEngine {
companion object { companion object {
fun init() { fun init() {
synchronized(this) { synchronized(this) {
if (nodeSerializationEnv == null) { if (nodeSerializationEnv == null) {
val classloader = this.javaClass.classLoader val classloader = this::class.java.classLoader
nodeSerializationEnv = SerializationEnvironmentImpl( nodeSerializationEnv = SerializationEnvironmentImpl(
SerializationFactoryImpl().apply { SerializationFactoryImpl().apply {
registerScheme(AMQPServerSerializationScheme(emptyList())) registerScheme(AMQPServerSerializationScheme(emptyList()))
@ -27,4 +26,4 @@ class SerializationEngine {
} }
} }
} }
} }