Removing warnings

This commit is contained in:
Shams Asari
2018-07-05 12:40:36 +01:00
parent 20a589d66d
commit 0c8c914882
45 changed files with 168 additions and 344 deletions

7
.idea/compiler.xml generated
View File

@ -54,6 +54,12 @@
<module name="contracts-states_test" target="1.8" /> <module name="contracts-states_test" target="1.8" />
<module name="corda-core_integrationTest" target="1.8" /> <module name="corda-core_integrationTest" target="1.8" />
<module name="corda-core_smokeTest" target="1.8" /> <module name="corda-core_smokeTest" target="1.8" />
<module name="corda-enterprise-testing_main" target="1.8" />
<module name="corda-enterprise-testing_test" target="1.8" />
<module name="corda-enterprise-tools_main" target="1.8" />
<module name="corda-enterprise-tools_test" target="1.8" />
<module name="corda-enterprise_main" target="1.8" />
<module name="corda-enterprise_test" target="1.8" />
<module name="corda-finance_integrationTest" target="1.8" /> <module name="corda-finance_integrationTest" target="1.8" />
<module name="corda-project-testing_main" target="1.8" /> <module name="corda-project-testing_main" target="1.8" />
<module name="corda-project-testing_test" target="1.8" /> <module name="corda-project-testing_test" target="1.8" />
@ -93,6 +99,7 @@
<module name="demobench_main" target="1.8" /> <module name="demobench_main" target="1.8" />
<module name="demobench_test" target="1.8" /> <module name="demobench_test" target="1.8" />
<module name="dist_binFiles" target="1.8" /> <module name="dist_binFiles" target="1.8" />
<module name="dist_installerFiles" target="1.8" />
<module name="dist_licenseFiles" target="1.8" /> <module name="dist_licenseFiles" target="1.8" />
<module name="dist_main" target="1.8" /> <module name="dist_main" target="1.8" />
<module name="dist_readmeFiles" target="1.8" /> <module name="dist_readmeFiles" target="1.8" />

View File

@ -7,12 +7,10 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.node.NetworkParameters import net.corda.core.node.NetworkParameters
import net.corda.core.node.NotaryInfo import net.corda.core.node.NotaryInfo
import net.corda.core.node.services.AttachmentId
import net.corda.core.serialization.SerializationDefaults import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.node.services.config.CertChainPolicyConfig
import net.corda.node.services.config.EnterpriseConfiguration import net.corda.node.services.config.EnterpriseConfiguration
import net.corda.node.services.config.MutualExclusionConfiguration import net.corda.node.services.config.MutualExclusionConfiguration
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
@ -102,7 +100,7 @@ class BridgeSmokeTest {
bridgeJar.copyToDirectory(testDir) bridgeJar.copyToDirectory(testDir)
} }
fun createNetworkParams(baseDirectory: Path) { private fun createNetworkParams(baseDirectory: Path) {
val dummyNotaryParty = TestIdentity(DUMMY_NOTARY_NAME) val dummyNotaryParty = TestIdentity(DUMMY_NOTARY_NAME)
val notaryInfo = NotaryInfo(dummyNotaryParty.party, false) val notaryInfo = NotaryInfo(dummyNotaryParty.party, false)
val copier = NetworkParametersCopier(NetworkParameters( val copier = NetworkParametersCopier(NetworkParameters(
@ -112,18 +110,18 @@ class BridgeSmokeTest {
maxMessageSize = 10485760, maxMessageSize = 10485760,
maxTransactionSize = 40000, maxTransactionSize = 40000,
epoch = 1, epoch = 1,
whitelistedContractImplementations = emptyMap<String, List<AttachmentId>>() whitelistedContractImplementations = emptyMap()
), overwriteFile = true) ), overwriteFile = true)
copier.install(baseDirectory) copier.install(baseDirectory)
} }
fun SSLConfiguration.createBridgeKeyStores(legalName: CordaX500Name, private fun SSLConfiguration.createBridgeKeyStores(legalName: CordaX500Name,
rootCert: X509Certificate = DEV_ROOT_CA.certificate, rootCert: X509Certificate = DEV_ROOT_CA.certificate,
intermediateCa: CertificateAndKeyPair = DEV_INTERMEDIATE_CA) { intermediateCa: CertificateAndKeyPair = DEV_INTERMEDIATE_CA) {
certificatesDirectory.createDirectories() certificatesDirectory.createDirectories()
if (!trustStoreFile.exists()) { if (!trustStoreFile.exists()) {
loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/${DEV_CA_TRUST_STORE_FILE}"), DEV_CA_TRUST_STORE_PASS).save(trustStoreFile, trustStorePassword) loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/$DEV_CA_TRUST_STORE_FILE"), DEV_CA_TRUST_STORE_PASS).save(trustStoreFile, trustStorePassword)
} }
val (nodeCaCert, nodeCaKeyPair) = createDevNodeCa(intermediateCa, legalName) val (nodeCaCert, nodeCaKeyPair) = createDevNodeCa(intermediateCa, legalName)
@ -189,13 +187,13 @@ class BridgeSmokeTest {
} }
} }
fun serverListening(host: String, port: Int): Boolean { private fun serverListening(host: String, port: Int): Boolean {
var s: Socket? = null var s: Socket? = null
try { return try {
s = Socket(host, port) s = Socket(host, port)
return true true
} catch (e: Exception) { } catch (e: Exception) {
return false false
} finally { } finally {
try { try {
s?.close() s?.close()
@ -212,7 +210,6 @@ class BridgeSmokeTest {
doReturn("cordacadevpass").whenever(it).keyStorePassword doReturn("cordacadevpass").whenever(it).keyStorePassword
doReturn(NetworkHostAndPort("localhost", 11005)).whenever(it).p2pAddress doReturn(NetworkHostAndPort("localhost", 11005)).whenever(it).p2pAddress
doReturn(null).whenever(it).jmxMonitoringHttpPort doReturn(null).whenever(it).jmxMonitoringHttpPort
doReturn(emptyList<CertChainPolicyConfig>()).whenever(it).certificateChainCheckPolicies
doReturn(EnterpriseConfiguration(MutualExclusionConfiguration(false, "", 20000, 40000), externalBridge = true)).whenever(it).enterpriseConfiguration doReturn(EnterpriseConfiguration(MutualExclusionConfiguration(false, "", 20000, 40000), externalBridge = true)).whenever(it).enterpriseConfiguration
} }
val artemisServer = ArtemisMessagingServer(artemisConfig, NetworkHostAndPort("0.0.0.0", 11005), MAX_MESSAGE_SIZE) val artemisServer = ArtemisMessagingServer(artemisConfig, NetworkHostAndPort("0.0.0.0", 11005), MAX_MESSAGE_SIZE)

View File

@ -17,7 +17,6 @@ import net.corda.bridge.createBridgeKeyStores
import net.corda.bridge.createNetworkParams import net.corda.bridge.createNetworkParams
import net.corda.bridge.services.artemis.BridgeArtemisConnectionServiceImpl import net.corda.bridge.services.artemis.BridgeArtemisConnectionServiceImpl
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.services.config.CertChainPolicyConfig
import net.corda.node.services.config.EnterpriseConfiguration import net.corda.node.services.config.EnterpriseConfiguration
import net.corda.node.services.config.MutualExclusionConfiguration import net.corda.node.services.config.MutualExclusionConfiguration
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
@ -102,7 +101,6 @@ class ArtemisConnectionTest {
doReturn("cordacadevpass").whenever(it).keyStorePassword doReturn("cordacadevpass").whenever(it).keyStorePassword
doReturn(NetworkHostAndPort("localhost", 11005)).whenever(it).p2pAddress doReturn(NetworkHostAndPort("localhost", 11005)).whenever(it).p2pAddress
doReturn(null).whenever(it).jmxMonitoringHttpPort doReturn(null).whenever(it).jmxMonitoringHttpPort
doReturn(emptyList<CertChainPolicyConfig>()).whenever(it).certificateChainCheckPolicies
doReturn(EnterpriseConfiguration(MutualExclusionConfiguration(false, "", 20000, 40000), externalBridge = true)).whenever(it).enterpriseConfiguration doReturn(EnterpriseConfiguration(MutualExclusionConfiguration(false, "", 20000, 40000), externalBridge = true)).whenever(it).enterpriseConfiguration
} }
val artemisServer = ArtemisMessagingServer(artemisConfig, NetworkHostAndPort("0.0.0.0", 11005), MAX_MESSAGE_SIZE) val artemisServer = ArtemisMessagingServer(artemisConfig, NetworkHostAndPort("0.0.0.0", 11005), MAX_MESSAGE_SIZE)

View File

@ -57,14 +57,16 @@ class StateMachineDataModel {
private val progressTracking by observable(NodeMonitorModel::progressTracking) private val progressTracking by observable(NodeMonitorModel::progressTracking)
private val progressEvents = progressTracking.recordAsAssociation(ProgressTrackingEvent::stateMachineId) private val progressEvents = progressTracking.recordAsAssociation(ProgressTrackingEvent::stateMachineId)
val counter = Counter() private val counter = Counter()
private val stateMachineIndexMap = HashMap<StateMachineRunId, Int>() private val stateMachineIndexMap = HashMap<StateMachineRunId, Int>()
private val stateMachineStatus = stateMachineUpdates.fold(FXCollections.observableArrayList<SimpleObjectProperty<StateMachineStatus>>()) { list, update -> private val stateMachineStatus = stateMachineUpdates.fold(FXCollections.observableArrayList<SimpleObjectProperty<StateMachineStatus>>()) { list, update ->
when (update) { when (update) {
is StateMachineUpdate.Added -> { is StateMachineUpdate.Added -> {
counter.addSmm() counter.addSmm()
val flowInitiator= update.stateMachineInfo.initiator // TODO Use invocationContext instead
@Suppress("DEPRECATION")
val flowInitiator = update.stateMachineInfo.initiator
val added: SimpleObjectProperty<StateMachineStatus> = val added: SimpleObjectProperty<StateMachineStatus> =
SimpleObjectProperty(StateMachineStatus.Added(update.id, update.stateMachineInfo.flowLogicClassName, flowInitiator)) SimpleObjectProperty(StateMachineStatus.Added(update.id, update.stateMachineInfo.flowLogicClassName, flowInitiator))
list.add(added) list.add(added)
@ -83,7 +85,7 @@ class StateMachineDataModel {
private val stateMachineDataList = stateMachineStatus.map { private val stateMachineDataList = stateMachineStatus.map {
val smStatus = it.value as StateMachineStatus.Added val smStatus = it.value as StateMachineStatus.Added
val id = smStatus.id val id = smStatus.id
val progress = SimpleObjectProperty(progressEvents.get(id)) val progress = SimpleObjectProperty(progressEvents[id])
StateMachineData(id, smStatus.stateMachineName, smStatus.flowInitiator, StateMachineData(id, smStatus.stateMachineName, smStatus.flowInitiator,
Pair(it, EasyBind.map(progress) { ProgressStatus(it?.message) })) Pair(it, EasyBind.map(progress) { ProgressStatus(it?.message) }))
} }

View File

@ -52,7 +52,7 @@ data class StateMachineInfo @JvmOverloads constructor(
* An object representing information about the initiator of the flow. Note that this field is * An object representing information about the initiator of the flow. Note that this field is
* superceded by the [invocationContext] property, which has more detail. * superceded by the [invocationContext] property, which has more detail.
*/ */
@Deprecated("There is more info available using 'context'") val initiator: FlowInitiator, @Deprecated("There is more info available using 'invocationContext'") val initiator: FlowInitiator,
/** A [DataFeed] of the current progress step as a human readable string, and updates to that string. */ /** A [DataFeed] of the current progress step as a human readable string, and updates to that string. */
val progressTrackerStepAndUpdates: DataFeed<String, String>?, val progressTrackerStepAndUpdates: DataFeed<String, String>?,
/** An [InvocationContext] describing why and by whom the flow was started. */ /** An [InvocationContext] describing why and by whom the flow was started. */

View File

@ -136,7 +136,7 @@ class IntegrationTestingTutorial : IntegrationTest() {
// move to Bob // move to Bob
parallel( parallel(
(1..numberOfStates).map { i -> (1..numberOfStates).map { i ->
expect(match = { it.moved() == i * 100 }) { update: Vault.Update<Cash.State> -> expect(match = { it.moved() == i * 100 }) { _: Vault.Update<Cash.State> ->
} }
} }
), ),
@ -154,7 +154,7 @@ class IntegrationTestingTutorial : IntegrationTest() {
} }
} }
fun Vault.Update<Cash.State>.moved(): Int { private fun Vault.Update<Cash.State>.moved(): Int {
val consumedSum = consumed.sumBy { it.state.data.amount.quantity.toInt() } val consumedSum = consumed.sumBy { it.state.data.amount.quantity.toInt() }
val producedSum = produced.sumBy { it.state.data.amount.quantity.toInt() } val producedSum = produced.sumBy { it.state.data.amount.quantity.toInt() }
return consumedSum - producedSum return consumedSum - producedSum

View File

@ -40,6 +40,7 @@ import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
@ -134,7 +135,7 @@ public class FlowCookbookJava {
// We retrieve a notary from the network map. // We retrieve a notary from the network map.
// DOCSTART 01 // DOCSTART 01
CordaX500Name notaryName = new CordaX500Name("Notary Service", "London", "GB"); CordaX500Name notaryName = new CordaX500Name("Notary Service", "London", "GB");
Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(notaryName); Party specificNotary = Objects.requireNonNull(getServiceHub().getNetworkMapCache().getNotary(notaryName));
// Alternatively, we can pick an arbitrary notary from the notary // Alternatively, we can pick an arbitrary notary from the notary
// list. However, it is always preferable to specify the notary // list. However, it is always preferable to specify the notary
// explicitly, as the notary list might change when new notaries are // explicitly, as the notary list might change when new notaries are
@ -378,7 +379,7 @@ public class FlowCookbookJava {
// Or we can add the output state as a ``TransactionState``, which already specifies // Or we can add the output state as a ``TransactionState``, which already specifies
// the output's contract and notary. // the output's contract and notary.
// DOCSTART 51 // DOCSTART 51
TransactionState txState = new TransactionState(ourOutputState, DummyContract.PROGRAM_ID, specificNotary); TransactionState txState = new TransactionState<>(ourOutputState, DummyContract.PROGRAM_ID, specificNotary);
// DOCEND 51 // DOCEND 51
// Commands can be added as ``Command``s. // Commands can be added as ``Command``s.
@ -662,7 +663,7 @@ public class FlowCookbookJava {
} }
@Override @Override
protected void checkTransaction(SignedTransaction stx) { protected void checkTransaction(@NotNull SignedTransaction stx) {
requireThat(require -> { requireThat(require -> {
// Any additional checking we see fit... // Any additional checking we see fit...
DummyState outputState = (DummyState) stx.getTx().getOutputs().get(0).getData(); DummyState outputState = (DummyState) stx.getTx().getOutputs().get(0).getData();

View File

@ -13,6 +13,7 @@ package net.corda.docs.java.tutorial.contract;
import net.corda.core.contracts.*; import net.corda.core.contracts.*;
import net.corda.core.transactions.LedgerTransaction; import net.corda.core.transactions.LedgerTransaction;
import net.corda.core.transactions.LedgerTransaction.InOutGroup; import net.corda.core.transactions.LedgerTransaction.InOutGroup;
import org.jetbrains.annotations.NotNull;
import java.time.Instant; import java.time.Instant;
import java.util.Currency; import java.util.Currency;
@ -22,6 +23,7 @@ import static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
import static net.corda.core.contracts.ContractsDSL.requireThat; import static net.corda.core.contracts.ContractsDSL.requireThat;
import static net.corda.finance.utils.StateSumming.sumCashBy; import static net.corda.finance.utils.StateSumming.sumCashBy;
@SuppressWarnings("unused")
public class CommercialPaper implements Contract { public class CommercialPaper implements Contract {
// DOCSTART 1 // DOCSTART 1
public static final String IOU_CONTRACT_ID = "com.example.contract.IOUContract"; public static final String IOU_CONTRACT_ID = "com.example.contract.IOUContract";
@ -29,7 +31,7 @@ public class CommercialPaper implements Contract {
// DOCSTART 3 // DOCSTART 3
@Override @Override
public void verify(LedgerTransaction tx) { public void verify(@NotNull LedgerTransaction tx) {
List<InOutGroup<State, State>> groups = tx.groupStates(State.class, State::withoutOwner); List<InOutGroup<State, State>> groups = tx.groupStates(State.class, State::withoutOwner);
CommandWithParties<Commands> cmd = requireSingleCommand(tx.getCommands(), Commands.class); CommandWithParties<Commands> cmd = requireSingleCommand(tx.getCommands(), Commands.class);
// DOCEND 3 // DOCEND 3
@ -37,7 +39,7 @@ public class CommercialPaper implements Contract {
// DOCSTART 4 // DOCSTART 4
TimeWindow timeWindow = tx.getTimeWindow(); TimeWindow timeWindow = tx.getTimeWindow();
for (InOutGroup group : groups) { for (InOutGroup<State, State> group : groups) {
List<State> inputs = group.getInputs(); List<State> inputs = group.getInputs();
List<State> outputs = group.getOutputs(); List<State> outputs = group.getOutputs();
@ -57,6 +59,7 @@ public class CommercialPaper implements Contract {
Amount<Issued<Currency>> received = sumCashBy(tx.getOutputStates(), input.getOwner()); Amount<Issued<Currency>> received = sumCashBy(tx.getOutputStates(), input.getOwner());
if (timeWindow == null) throw new IllegalArgumentException("Redemptions must be timestamped"); if (timeWindow == null) throw new IllegalArgumentException("Redemptions must be timestamped");
Instant time = timeWindow.getFromTime(); Instant time = timeWindow.getFromTime();
if (time == null) throw new IllegalArgumentException("Redemptions must have a from time");
requireThat(require -> { requireThat(require -> {
require.using("the paper must have matured", time.isAfter(input.getMaturityDate())); require.using("the paper must have matured", time.isAfter(input.getMaturityDate()));
require.using("the received amount equals the face value", received == input.getFaceValue()); require.using("the received amount equals the face value", received == input.getFaceValue());
@ -68,6 +71,7 @@ public class CommercialPaper implements Contract {
State output = outputs.get(0); State output = outputs.get(0);
if (timeWindow == null) throw new IllegalArgumentException("Issuances must have a time-window"); if (timeWindow == null) throw new IllegalArgumentException("Issuances must have a time-window");
Instant time = timeWindow.getUntilTime(); Instant time = timeWindow.getUntilTime();
if (time == null) throw new IllegalArgumentException("Issuances must have an until time");
requireThat(require -> { requireThat(require -> {
// Don't allow people to issue commercial paper under other entities identities. // Don't allow people to issue commercial paper under other entities identities.
require.using("output states are issued by a command signer", cmd.getSigners().contains(output.getIssuance().getParty().getOwningKey())); require.using("output states are issued by a command signer", cmd.getSigners().contains(output.getIssuance().getParty().getOwningKey()));

View File

@ -11,19 +11,19 @@
package net.corda.behave.network package net.corda.behave.network
import net.corda.behave.database.DatabaseType import net.corda.behave.database.DatabaseType
import net.corda.behave.file.* import net.corda.behave.file.LogSource
import net.corda.behave.monitoring.PatternWatch import net.corda.behave.file.currentDirectory
import net.corda.behave.file.stagingRoot
import net.corda.behave.file.tmpDirectory
import net.corda.behave.node.Distribution import net.corda.behave.node.Distribution
import net.corda.behave.node.Node import net.corda.behave.node.Node
import net.corda.behave.node.configuration.NotaryType import net.corda.behave.node.configuration.NotaryType
import net.corda.behave.process.Command import net.corda.behave.process.Command
import net.corda.behave.process.JarCommand import net.corda.behave.process.JarCommand
import net.corda.core.CordaException import net.corda.core.CordaException
import net.corda.core.CordaRuntimeException
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.minutes import net.corda.core.utilities.minutes
import net.corda.core.utilities.seconds
import java.io.Closeable import java.io.Closeable
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
@ -147,116 +147,8 @@ class Network private constructor(
* using Local signing and "Auto Approval" mode * using Local signing and "Auto Approval" mode
*/ */
private fun bootstrapDoorman() { private fun bootstrapDoorman() {
// TODO: rework how we use the Doorman/NMS (now these are a separate product / distribution) // TODO: rework how we use the Doorman/NMS (now these are a separate product / distribution)
signalFailure("Bootstrapping a Corda Enterprise network using the Doorman is no longer supported; exiting ...") signalFailure("Bootstrapping a Corda Enterprise network using the Doorman is no longer supported; exiting ...")
return
// WARNING!! Need to use the correct bootstrapper
// only if using OS nodes (need to choose the latest version)
val r3node = nodes.values
.find { it.config.distribution.type == Distribution.Type.CORDA_ENTERPRISE } ?: throw CordaRuntimeException("Missing R3 distribution node")
val distribution = r3node.config.distribution
// Copy over reference configuration files used in bootstrapping
val source = doormanConfigDirectory
val doormanTargetDirectory = targetDirectory / "doorman"
source.toFile().copyRecursively(doormanTargetDirectory.toFile(), true)
// Use master version of Bootstrapper
val doormanJar = Distribution.R3_MASTER.doormanJar
log.info("DoormanJar URL: $doormanJar\n")
// 1. Create key stores for local signer
// java -jar doorman-<version>.jar --mode ROOT_KEYGEN
log.info("Doorman target directory: $doormanTargetDirectory")
runCommand(JarCommand(doormanJar,
arrayOf("--config-file", "$doormanConfigDirectory/node-init.conf", "--mode", "ROOT_KEYGEN", "--trust-store-password", "password"),
doormanTargetDirectory, timeout))
// java -jar doorman-<version>.jar --mode CA_KEYGEN
runCommand(JarCommand(doormanJar,
arrayOf("--config-file", "$doormanConfigDirectory/node-init.conf", "--mode", "CA_KEYGEN"),
doormanTargetDirectory, timeout))
// 2. Start the doorman service for notary registration
doormanNMS = JarCommand(doormanJar,
arrayOf("--config-file", "$doormanConfigDirectory/node-init.conf"),
doormanTargetDirectory, timeout)
val doormanCommand = runCommand(doormanNMS, noWait = true)
log.info("Waiting for DoormanNMS to be alive")
PatternWatch(doormanCommand.output, "Network management web services started on").await(30.seconds)
log.info("DoormanNMS up and running")
// Notary Nodes
val notaryNodes = nodes.values.filter { it.config.notary.notaryType != NotaryType.NONE }
notaryNodes.forEach { notaryNode ->
val notaryTargetDirectory = targetDirectory / notaryNode.config.name
log.info("Notary target directory: $notaryTargetDirectory")
// 3. Create notary node and register with the doorman
runCommand(JarCommand(distribution.cordaJar,
arrayOf("--initial-registration",
"--base-directory", "$notaryTargetDirectory",
"--network-root-truststore", "../doorman/certificates/distribute-nodes/network-root-truststore.jks",
"--network-root-truststore-password", "password"),
notaryTargetDirectory, timeout))
// 4. Generate node info files for notary nodes
runCommand(JarCommand(distribution.cordaJar,
arrayOf("--just-generate-node-info",
"--base-directory", "$notaryTargetDirectory"),
notaryTargetDirectory, timeout))
// cp (or ln -s) nodeInfo* notary-node-info
val nodeInfoFile = notaryTargetDirectory.toFile().listFiles { _, filename -> filename.matches("nodeInfo-.+".toRegex()) }.firstOrNull() ?: throw CordaRuntimeException("Missing notary nodeInfo file")
Files.copy(nodeInfoFile.toPath(), (notaryTargetDirectory / "notary-node-info"), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING)
}
// exit Doorman process
doormanCommand.interrupt()
doormanCommand.waitFor()
// 5. Add notary identities to the network parameters
// 6. Load initial network parameters file for network map service
val networkParamsConfig = if (notaryNodes.isEmpty()) "network-parameters-without-notary.conf" else "network-parameters.conf"
val updateNetworkParams = JarCommand(doormanJar,
arrayOf("--config-file", "$doormanTargetDirectory/node.conf", "--set-network-parameters", "$doormanTargetDirectory/$networkParamsConfig"),
doormanTargetDirectory, timeout)
runCommand(updateNetworkParams)
// 7. Start a fully configured Doorman / NMS
doormanNMS = JarCommand(doormanJar,
arrayOf("--config-file", "$doormanConfigDirectory/node.conf"),
doormanTargetDirectory, timeout)
val doormanNMSCommand = runCommand(doormanNMS, noWait = true)
log.info("Waiting for DoormanNMS to be alive")
PatternWatch(doormanNMSCommand.output, "Network management web services started on").await(30.seconds)
log.info("DoormanNMS up and running")
// 8. Register other participant nodes
val partyNodes = nodes.values.filter { it.config.notary.notaryType == NotaryType.NONE }
partyNodes.forEach { partyNode ->
val partyTargetDirectory = targetDirectory / partyNode.config.name
log.info("Party target directory: $partyTargetDirectory")
// 3. Create notary node and register with the doorman
runCommand(JarCommand(distribution.cordaJar,
arrayOf("--initial-registration",
"--network-root-truststore", "../doorman/certificates/distribute-nodes/network-root-truststore.jks",
"--network-root-truststore-password", "password",
"--base-directory", "$partyTargetDirectory"),
partyTargetDirectory, timeout))
}
isDoormanNMSRunning = true
} }
private fun runCommand(command: Command, noWait: Boolean = false): Command { private fun runCommand(command: Command, noWait: Boolean = false): Command {
@ -446,7 +338,7 @@ class Network private constructor(
val rpcProxyPortNo = node.config.nodeInterface.rpcProxy val rpcProxyPortNo = node.config.nodeInterface.rpcProxy
val pid = Files.lines(tmpDirectory / "rpcProxy-pid-$rpcProxyPortNo").findFirst().get() val pid = Files.lines(tmpDirectory / "rpcProxy-pid-$rpcProxyPortNo").findFirst().get()
// TODO: consider generic implementation to support non *nix platforms // TODO: consider generic implementation to support non *nix platforms
Command(listOf("kill", "-9", "$pid")).run() Command(listOf("kill", "-9", pid)).run()
(tmpDirectory / "rpcProxy-pid-$rpcProxyPortNo").deleteIfExists() (tmpDirectory / "rpcProxy-pid-$rpcProxyPortNo").deleteIfExists()
} }
catch (e: Exception) { catch (e: Exception) {

View File

@ -14,7 +14,6 @@ import net.corda.behave.database.DatabaseConnection
import net.corda.behave.database.DatabaseType import net.corda.behave.database.DatabaseType
import net.corda.behave.file.LogSource import net.corda.behave.file.LogSource
import net.corda.behave.file.currentDirectory import net.corda.behave.file.currentDirectory
import net.corda.behave.file.stagingRoot
import net.corda.behave.monitoring.PatternWatch import net.corda.behave.monitoring.PatternWatch
import net.corda.behave.node.configuration.* import net.corda.behave.node.configuration.*
import net.corda.behave.process.JarCommand import net.corda.behave.process.JarCommand
@ -31,8 +30,8 @@ import net.corda.core.internal.div
import net.corda.core.internal.exists import net.corda.core.internal.exists
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.minutes
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.minutes
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import java.net.InetAddress import java.net.InetAddress
@ -45,7 +44,7 @@ import java.util.concurrent.CountDownLatch
*/ */
class Node( class Node(
val config: Configuration, val config: Configuration,
val rootDirectory: Path = currentDirectory, private val rootDirectory: Path = currentDirectory,
private val settings: ServiceSettings = ServiceSettings(), private val settings: ServiceSettings = ServiceSettings(),
val rpcProxy: Boolean = false, val rpcProxy: Boolean = false,
val networkType: Distribution.Type val networkType: Distribution.Type
@ -77,18 +76,6 @@ class Node(
private var haveDependenciesStopped = false private var haveDependenciesStopped = false
fun describe(): String {
val network = config.nodeInterface
val database = config.database
return """
|Node Information: ${config.name}
| - P2P: ${network.host}:${network.p2pPort}
| - RPC: ${network.host}:${network.rpcPort}
| - SSH: ${network.host}:${network.sshPort}
| - DB: ${network.host}:${database.port} (${database.type})
|""".trimMargin()
}
fun configure() { fun configure() {
if (isConfigured) { return } if (isConfigured) { return }
isConfigured = true isConfigured = true
@ -164,10 +151,6 @@ class Node(
} }
} }
val nodeInfoGenerationOutput: LogSource by lazy {
LogSource(logDirectory, "node-info-gen.log")
}
val logOutput: LogSource by lazy { val logOutput: LogSource by lazy {
val hostname = InetAddress.getLocalHost().hostName val hostname = InetAddress.getLocalHost().hostName
LogSource(logDirectory, "node-$hostname.*.log") LogSource(logDirectory, "node-$hostname.*.log")
@ -387,10 +370,11 @@ class Node(
val name = name ?: error("Node name not set") val name = name ?: error("Node name not set")
val directory = directory ?: error("Runtime directory not set") val directory = directory ?: error("Runtime directory not set")
// TODO: rework how we use the Doorman/NMS (now these are a separate product / distribution) // TODO: rework how we use the Doorman/NMS (now these are a separate product / distribution)
val compatibilityZoneURL = null val compatibilityZoneURL = if (networkType == Distribution.Type.CORDA_ENTERPRISE && System.getProperty("USE_NETWORK_SERVICES") != null) {
if (networkType == Distribution.Type.CORDA_ENTERPRISE && System.getProperty("USE_NETWORK_SERVICES") != null) "http://localhost:1300" // TODO: add additional USE_NETWORK_SERVICES_URL to specify location of existing operational environment to use.
"http://localhost:1300" // TODO: add additional USE_NETWORK_SERVICES_URL to specify location of existing operational environment to use. } else {
else null null
}
return Node( return Node(
Configuration( Configuration(
name, name,

View File

@ -72,7 +72,7 @@ class ScenarioState {
inline fun <T> withNetwork(action: ScenarioState.() -> T): T { inline fun <T> withNetwork(action: ScenarioState.() -> T): T {
ensureNetworkIsRunning() ensureNetworkIsRunning()
return action() return this.action()
} }
inline fun <T> withClient(nodeName: String, crossinline action: (CordaRPCOps) -> T): T { inline fun <T> withClient(nodeName: String, crossinline action: (CordaRPCOps) -> T): T {

View File

@ -10,7 +10,6 @@
package net.corda.behave.scenarios.helpers package net.corda.behave.scenarios.helpers
import net.corda.behave.logging.getLogger
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 org.slf4j.Logger import org.slf4j.Logger
@ -32,12 +31,12 @@ abstract class Substeps(protected val state: ScenarioState) {
} }
protected fun <T> withClientProxy(nodeName: String, action: ScenarioState.(CordaRPCOps) -> T): T { protected fun <T> withClientProxy(nodeName: String, action: ScenarioState.(CordaRPCOps) -> T): T {
return state.withClientProxy(nodeName, { return state.withClientProxy(nodeName) {
return@withClientProxy try { try {
action(state, it) action(state, it)
} catch (ex: Exception) { } catch (ex: Exception) {
state.error<T>(ex.message ?: "Failed to execute HTTP call") state.error(ex.message ?: "Failed to execute HTTP call")
} }
}) }
} }
} }

View File

@ -34,7 +34,6 @@ repositories {
} }
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

@ -114,7 +114,6 @@ object FiberMonitor {
thread { thread {
while (true) { while (true) {
Thread.sleep(1000) Thread.sleep(1000)
this
} }
} }
} }

View File

@ -12,7 +12,7 @@ package net.corda.flowhook
import java.lang.instrument.Instrumentation import java.lang.instrument.Instrumentation
@Suppress("UNUSED") @Suppress("UNUSED", "UNUSED_PARAMETER")
class FlowHookAgent { class FlowHookAgent {
companion object { companion object {
@JvmStatic @JvmStatic
@ -22,4 +22,3 @@ class FlowHookAgent {
} }
} }
} }

View File

@ -21,7 +21,7 @@ import org.apache.activemq.artemis.core.io.buffer.TimedBuffer
import java.sql.Connection import java.sql.Connection
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@Suppress("UNUSED") @Suppress("UNUSED", "UNUSED_PARAMETER")
object FlowHookContainer { object FlowHookContainer {
@JvmStatic @JvmStatic

View File

@ -34,7 +34,6 @@ repositories {
} }
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'net.corda.plugins.cordapp' apply plugin: 'net.corda.plugins.cordapp'

View File

@ -11,13 +11,11 @@ import java.util.concurrent.Callable
// Responsible for executing test scenario for a single node executing `LinearStateBatchNotariseFlow` and verifying the results // Responsible for executing test scenario for a single node executing `LinearStateBatchNotariseFlow` and verifying the results
class LinearStateScenarioRunner(options: OptionSet) : AbstractScenarioRunner(options), Callable<Boolean> { class LinearStateScenarioRunner(options: OptionSet) : AbstractScenarioRunner(options), Callable<Boolean> {
companion object { companion object {
private val logger = contextLogger() private val logger = contextLogger()
} }
override fun call(): Boolean { override fun call(): Boolean {
scenarioInitialized() scenarioInitialized()
try { try {
@ -42,6 +40,7 @@ class LinearStateScenarioRunner(options: OptionSet) : AbstractScenarioRunner(opt
} }
} }
@Suppress("UNUSED_PARAMETER")
private fun verifyResultsAndStatesTally(results: MutableList<LinearStateBatchNotariseFlow.Result>, states: Vault.Page<LinearStateBatchNotariseContract.State>): Boolean { private fun verifyResultsAndStatesTally(results: MutableList<LinearStateBatchNotariseFlow.Result>, states: Vault.Page<LinearStateBatchNotariseContract.State>): Boolean {
// Unfortunately, there is absolutely nothing in `LinearStateBatchNotariseFlow.Result` which can link it to the original transaction // Unfortunately, there is absolutely nothing in `LinearStateBatchNotariseFlow.Result` which can link it to the original transaction
return true return true

View File

@ -27,8 +27,8 @@ class CashSelectionOracleImpl : AbstractCashSelection(maxRetries = 16, retrySlee
private val log = contextLogger() private val log = contextLogger()
} }
override fun isCompatible(metaData: DatabaseMetaData): Boolean { override fun isCompatible(metadata: DatabaseMetaData): Boolean {
return metaData.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true) return metadata.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true)
} }
override fun toString() = "${this::class.qualifiedName} for '$JDBC_DRIVER_NAME'" override fun toString() = "${this::class.qualifiedName} for '$JDBC_DRIVER_NAME'"

View File

@ -16,7 +16,6 @@ import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.toBase58String
import java.sql.Connection import java.sql.Connection
import java.sql.DatabaseMetaData import java.sql.DatabaseMetaData
import java.sql.ResultSet import java.sql.ResultSet
@ -32,8 +31,8 @@ class CashSelectionSQLServerImpl : AbstractCashSelection(maxRetries = 16, retryS
private val log = contextLogger() private val log = contextLogger()
} }
override fun isCompatible(metaData: DatabaseMetaData): Boolean { override fun isCompatible(metadata: DatabaseMetaData): Boolean {
return metaData.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true) return metadata.driverName.startsWith(JDBC_DRIVER_NAME, ignoreCase = true)
} }
override fun toString() = "${this::class.qualifiedName} for '$JDBC_DRIVER_NAME'" override fun toString() = "${this::class.qualifiedName} for '$JDBC_DRIVER_NAME'"

View File

@ -8,7 +8,6 @@ import java.nio.file.Paths
import kotlin.system.exitProcess import kotlin.system.exitProcess
fun main(args: Array<String>) { fun main(args: Array<String>) {
if (args.isEmpty()) { if (args.isEmpty()) {
println("Usage: launcher <main-class-name> [args]") println("Usage: launcher <main-class-name> [args]")
exitProcess(0) exitProcess(0)
@ -54,15 +53,14 @@ fun main(args: Array<String>) {
@Suppress("unchecked") @Suppress("unchecked")
private fun fixBaseDirArg(args: Array<String>, nodeBaseDirFromArgs: Path): Array<String> { private fun fixBaseDirArg(args: Array<String>, nodeBaseDirFromArgs: Path): Array<String> {
val baseDirIdx = args.indexOf("--base-directory") val baseDirIdx = args.indexOf("--base-directory")
if (baseDirIdx != -1){ return if (baseDirIdx != -1) {
args[baseDirIdx+1] = nodeBaseDirFromArgs.toString() // Replace the arg that follows, i.e. --base-directory X
return args // TODO This will not work for --base-directory=X
args[baseDirIdx + 1] = nodeBaseDirFromArgs.toString()
args
} else {
args + listOf("--base-directory", nodeBaseDirFromArgs.toString())
} }
val argsWithBaseDir = args.copyOf(args.size + 2)
argsWithBaseDir[argsWithBaseDir.lastIndex - 1] = "--base-directory"
argsWithBaseDir[argsWithBaseDir.lastIndex] = nodeBaseDirFromArgs.toString()
return argsWithBaseDir as Array<String>
} }
private fun setupClassLoader(nodeBaseDir: Path): ClassLoader { private fun setupClassLoader(nodeBaseDir: Path): ClassLoader {

View File

@ -257,7 +257,7 @@ class MySQLNotaryServiceTests : IntegrationTest() {
} }
private fun createNotaryNode(): InternalMockNetwork.MockNode { private fun createNotaryNode(): InternalMockNetwork.MockNode {
val dataStoreProperties = makeTestDataSourceProperties(configSupplier = { _, _ -> ConfigFactory.empty() }, fallBackConfigSupplier = ::inMemoryH2DataSourceConfig).apply { val dataStoreProperties = makeInternalTestDataSourceProperties(configSupplier = { ConfigFactory.empty() }).apply {
setProperty("autoCommit", "false") setProperty("autoCommit", "false")
} }
return mockNet.createUnstartedNode( return mockNet.createUnstartedNode(

View File

@ -16,6 +16,7 @@ import net.corda.node.utilities.AffinityExecutor
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import org.hibernate.Session import org.hibernate.Session
import org.hibernate.query.NativeQuery
import java.io.Serializable import java.io.Serializable
import java.sql.SQLTransientConnectionException import java.sql.SQLTransientConnectionException
import java.time.Duration import java.time.Duration
@ -132,7 +133,7 @@ class RunOnceService(private val database: CordaPersistence, private val machine
private fun insertMutualExclusion(session: Session) { private fun insertMutualExclusion(session: Session) {
val query = session.createNativeQuery("INSERT INTO $TABLE VALUES ('X', :machineName, :pid, CURRENT_TIMESTAMP, :version)", MutualExclusion::class.java) val query = session.createNativeQuery("INSERT INTO $TABLE VALUES ('X', :machineName, :pid, CURRENT_TIMESTAMP, :version)", MutualExclusion::class.java)
query.unwrap(org.hibernate.SQLQuery::class.java).addSynchronizedEntityClass(MutualExclusion::class.java) query.unwrap(NativeQuery::class.java).addSynchronizedEntityClass(MutualExclusion::class.java)
query.setParameter("pid", pid) query.setParameter("pid", pid)
query.setParameter("machineName", machineName) query.setParameter("machineName", machineName)
query.setParameter("version", 0) query.setParameter("version", 0)

View File

@ -70,7 +70,7 @@ class MultiThreadedStateMachineManager(
val checkpointStorage: CheckpointStorage, 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 = MultiThreadedStateMachineManager::class.java.classLoader private val classloader: ClassLoader = MultiThreadedStateMachineManager::class.java.classLoader
) : StateMachineManager, StateMachineManagerInternal { ) : StateMachineManager, StateMachineManagerInternal {
@ -158,7 +158,7 @@ class MultiThreadedStateMachineManager(
} }
serviceHub.networkMapCache.nodeReady.then { serviceHub.networkMapCache.nodeReady.then {
resumeRestoredFlows(fibers) resumeRestoredFlows(fibers)
flowMessaging.start { receivedMessage, deduplicationHandler -> flowMessaging.start { _, deduplicationHandler ->
lifeCycle.requireState(State.STARTED, StateMachineStoppedException("Flow cannot be started. State machine is stopped.")) { lifeCycle.requireState(State.STARTED, StateMachineStoppedException("Flow cannot be started. State machine is stopped.")) {
deliverExternalEvent(deduplicationHandler.externalCause) deliverExternalEvent(deduplicationHandler.externalCause)
} }
@ -306,10 +306,10 @@ class MultiThreadedStateMachineManager(
} }
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() {
@ -324,8 +324,7 @@ class MultiThreadedStateMachineManager(
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
if (concurrentBox.content.flows.containsKey(id)) return@map null if (concurrentBox.content.flows.containsKey(id)) return@map null
val checkpoint = deserializeCheckpoint(serializedCheckpoint) val checkpoint = deserializeCheckpoint(serializedCheckpoint) ?: return@map null
if (checkpoint == null) return@map null
createFlowFromCheckpoint( createFlowFromCheckpoint(
id = id, id = id,
checkpoint = checkpoint, checkpoint = checkpoint,
@ -440,7 +439,7 @@ class MultiThreadedStateMachineManager(
val flowId = sessionToFlow[recipientId] val flowId = sessionToFlow[recipientId]
if (flowId == null) { if (flowId == null) {
deduplicationHandler.afterDatabaseTransaction() deduplicationHandler.afterDatabaseTransaction()
if (sessionMessage.payload is EndSessionMessage) { if (sessionMessage.payload === EndSessionMessage) {
logger.debug { logger.debug {
"Got ${EndSessionMessage::class.java.simpleName} for " + "Got ${EndSessionMessage::class.java.simpleName} for " +
"unknown session $recipientId, discarding..." "unknown session $recipientId, discarding..."
@ -537,12 +536,6 @@ class MultiThreadedStateMachineManager(
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)
@ -553,7 +546,7 @@ class MultiThreadedStateMachineManager(
val frozenFlowLogic = (flowLogic as FlowLogic<*>).serialize(context = checkpointSerializationContext!!) val frozenFlowLogic = (flowLogic as FlowLogic<*>).serialize(context = checkpointSerializationContext!!)
val flowCorDappVersion = FlowStateMachineImpl.createSubFlowVersion(serviceHub.cordappProvider.getCordappForFlow(flowLogic), serviceHub.myInfo.platformVersion) val flowCorDappVersion = FlowStateMachineImpl.createSubFlowVersion(serviceHub.cordappProvider.getCordappForFlow(flowLogic), serviceHub.myInfo.platformVersion)
val initialCheckpoint = Checkpoint.create(invocationContext, flowStart, flowLogic.javaClass, frozenFlowLogic, ourIdentity, deduplicationSeed, flowCorDappVersion).getOrThrow() val initialCheckpoint = Checkpoint.create(invocationContext, flowStart, flowLogic.javaClass, frozenFlowLogic, ourIdentity, flowCorDappVersion).getOrThrow()
val startedFuture = openFuture<Unit>() val startedFuture = openFuture<Unit>()
val initialState = StateMachineState( val initialState = StateMachineState(
checkpoint = initialCheckpoint, checkpoint = initialCheckpoint,
@ -721,7 +714,7 @@ class MultiThreadedStateMachineManager(
private fun addAndStartFlow(id: StateMachineRunId, flow: Flow) { private fun addAndStartFlow(id: StateMachineRunId, flow: Flow) {
val checkpoint = flow.fiber.snapshot().checkpoint val checkpoint = flow.fiber.snapshot().checkpoint
for (sessionId in getFlowSessionIds(checkpoint)) { for (sessionId in getFlowSessionIds(checkpoint)) {
sessionToFlow.put(sessionId, id) sessionToFlow[sessionId] = id
} }
concurrentBox.concurrent { concurrentBox.concurrent {
val oldFlow = flows.put(id, flow) val oldFlow = flows.put(id, flow)

View File

@ -246,7 +246,6 @@ class RunOnceServiceTest {
assertEquals('X', result.id) assertEquals('X', result.id)
assertEquals("machine1", result.machineName) assertEquals("machine1", result.machineName)
assertEquals("123", result.pid) assertEquals("123", result.pid)
assertTrue(result.timestamp is LocalDateTime)
return result return result
} }
@ -256,7 +255,6 @@ class RunOnceServiceTest {
assertEquals('X', result.id) assertEquals('X', result.id)
assertEquals("machine2", result.machineName) assertEquals("machine2", result.machineName)
assertEquals("789", result.pid) assertEquals("789", result.pid)
assertTrue(result.timestamp is LocalDateTime)
return result return result
} }
} }

View File

@ -25,6 +25,7 @@ import net.corda.testing.node.MockServices
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
import java.lang.reflect.Method
import java.math.BigInteger import java.math.BigInteger
import java.net.URL import java.net.URL
import javax.persistence.* import javax.persistence.*
@ -32,7 +33,6 @@ import java.net.URLClassLoader
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
class SchemaMigrationTest { class SchemaMigrationTest {
@Test @Test
@ -82,7 +82,7 @@ class SchemaMigrationTest {
// check that the file was picked up // check that the file was picked up
val nrOfChangesOnDiscoveredFile = db.dataSource.connection.use { val nrOfChangesOnDiscoveredFile = db.dataSource.connection.use {
it.createStatement().executeQuery("select count(*) from DATABASECHANGELOG where filename ='migration/${fileName}'").use { rs -> it.createStatement().executeQuery("select count(*) from DATABASECHANGELOG where filename ='migration/$fileName'").use { rs ->
rs.next() rs.next()
rs.getInt(1) rs.getInt(1)
} }
@ -102,9 +102,11 @@ class SchemaMigrationTest {
} }
//hacky way to add a folder to the classpath //hacky way to add a folder to the classpath
fun addToClassPath(file: Path) = URLClassLoader::class.java.getDeclaredMethod("addURL", URL::class.java).apply { private fun addToClassPath(file: Path): Method {
isAccessible = true return URLClassLoader::class.java.getDeclaredMethod("addURL", URL::class.java).apply {
invoke(ClassLoader.getSystemClassLoader(), file.toFile().toURL()) isAccessible = true
invoke(ClassLoader.getSystemClassLoader(), file.toUri().toURL())
}
} }
object DummyTestSchema object DummyTestSchema
@ -116,9 +118,9 @@ class SchemaMigrationTest {
@ElementCollection @ElementCollection
@Column(name = "participants") @Column(name = "participants")
@CollectionTable(name = "dummy_test_states_parts", joinColumns = arrayOf( @CollectionTable(name = "dummy_test_states_parts", joinColumns = [
JoinColumn(name = "output_index", referencedColumnName = "output_index"), JoinColumn(name = "output_index", referencedColumnName = "output_index"),
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))) JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")])
override var participants: MutableSet<AbstractParty>? = null, override var participants: MutableSet<AbstractParty>? = null,
@Transient @Transient

View File

@ -40,7 +40,6 @@ class LinearStateBatchNotariseContract : Contract {
} }
override fun verify(tx: LedgerTransaction) { override fun verify(tx: LedgerTransaction) {
val command = tx.commands.requireSingleCommand<Commands>() tx.commands.requireSingleCommand<Commands>()
val timeWindow: TimeWindow? = tx.timeWindow
} }
} }

View File

@ -230,27 +230,6 @@ abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : C
return Pair(gathered, gatheredAmount) return Pair(gathered, gatheredAmount)
} }
/**
* Generate an transaction exiting fungible assets from the ledger.
*
* @param tx transaction builder to add states and commands to.
* @param amountIssued the amount to be exited, represented as a quantity of issued currency.
* @param assetStates the asset states to take funds from. No checks are done about ownership of these states, it is
* the responsibility of the caller to check that they do not attempt to exit funds held by others.
* @return the public keys which must sign the transaction for it to be valid.
*/
@Throws(InsufficientBalanceException::class)
@JvmStatic
@Deprecated("Replaced with generateExit() which takes in a party to pay change to")
fun <S : FungibleAsset<T>, T: Any> generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>,
assetStates: List<StateAndRef<S>>,
deriveState: (TransactionState<S>, Amount<Issued<T>>, AbstractParty) -> TransactionState<S>,
generateMoveCommand: () -> CommandData,
generateExitCommand: (Amount<Issued<T>>) -> CommandData): Set<PublicKey> {
val owner = assetStates.map { it.state.data.owner }.toSet().firstOrNull() ?: throw InsufficientBalanceException(amountIssued)
return generateExit(tx, amountIssued, assetStates, owner, deriveState, generateMoveCommand, generateExitCommand)
}
/** /**
* Generate an transaction exiting fungible assets from the ledger. * Generate an transaction exiting fungible assets from the ledger.
* *
@ -323,31 +302,6 @@ abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : C
abstract fun extractCommands(commands: Collection<CommandWithParties<CommandData>>): Collection<CommandWithParties<C>> abstract fun extractCommands(commands: Collection<CommandWithParties<CommandData>>): Collection<CommandWithParties<C>>
/**
* Generate an transaction exiting assets from the ledger.
*
* @param tx transaction builder to add states and commands to.
* @param amountIssued the amount to be exited, represented as a quantity of issued currency.
* @param assetStates the asset states to take funds from. No checks are done about ownership of these states, it is
* the responsibility of the caller to check that they do not exit funds held by others.
* @param payChangeTo party to pay any change to; this is normally a confidential identity of the calling
* party.
* @return the public keys which must sign the transaction for it to be valid.
*/
@Throws(InsufficientBalanceException::class)
@Deprecated("Replaced with generateExit() which takes in a party to pay change to")
fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>,
assetStates: List<StateAndRef<S>>): Set<PublicKey> {
return generateExit(
tx,
amountIssued,
assetStates,
deriveState = { state, amount, owner -> deriveState(state, amount, owner) },
generateMoveCommand = { -> generateMoveCommand() },
generateExitCommand = { amount -> generateExitCommand(amount) }
)
}
/** /**
* Generate an transaction exiting assets from the ledger. * Generate an transaction exiting assets from the ledger.
* *
@ -367,8 +321,8 @@ abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : C
assetStates, assetStates,
payChangeTo, payChangeTo,
deriveState = { state, amount, owner -> deriveState(state, amount, owner) }, deriveState = { state, amount, owner -> deriveState(state, amount, owner) },
generateMoveCommand = { -> generateMoveCommand() }, generateMoveCommand = { generateMoveCommand() },
generateExitCommand = { amount -> generateExitCommand(amount) } generateExitCommand = { generateExitCommand(it) }
) )
} }

View File

@ -14,22 +14,18 @@ import co.paralleluniverse.fibers.Suspendable
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.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.StatesNotAvailableException import net.corda.core.node.services.StatesNotAvailableException
import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.deserialize
import net.corda.core.utilities.* import net.corda.core.utilities.*
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import net.corda.core.internal.uncheckedCast
import java.sql.* import java.sql.*
import java.util.* import java.util.*
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
/** /**
* Pluggable interface to allow for different cash selection provider implementations * Pluggable interface to allow for different cash selection provider implementations
@ -41,17 +37,17 @@ import kotlin.concurrent.withLock
abstract class AbstractCashSelection(private val maxRetries: Int = 8, private val retrySleep: Int = 100, abstract class AbstractCashSelection(private val maxRetries: Int = 8, private val retrySleep: Int = 100,
private val retryCap: Int = 2000) { private val retryCap: Int = 2000) {
companion object { companion object {
val instance = AtomicReference<AbstractCashSelection>() private val instance = AtomicReference<AbstractCashSelection>()
fun getInstance(metadata: () -> java.sql.DatabaseMetaData): AbstractCashSelection { fun getInstance(metadata: () -> java.sql.DatabaseMetaData): AbstractCashSelection {
return instance.get() ?: { return instance.get() ?: {
val _metadata = metadata() val metadataResult = metadata()
val cashSelectionAlgos = ServiceLoader.load(AbstractCashSelection::class.java).toList() val cashSelectionAlgos = ServiceLoader.load(AbstractCashSelection::class.java).toList()
val cashSelectionAlgo = cashSelectionAlgos.firstOrNull { it.isCompatible(_metadata) } val cashSelectionAlgo = cashSelectionAlgos.firstOrNull { it.isCompatible(metadataResult) }
cashSelectionAlgo?.let { cashSelectionAlgo?.let {
instance.set(cashSelectionAlgo) instance.set(cashSelectionAlgo)
cashSelectionAlgo cashSelectionAlgo
} ?: throw ClassNotFoundException("\nUnable to load compatible cash selection algorithm implementation for JDBC driver ($_metadata)." + } ?: throw ClassNotFoundException("\nUnable to load compatible cash selection algorithm implementation for JDBC driver ($metadataResult)." +
"\nPlease specify an implementation in META-INF/services/${AbstractCashSelection::class.java}") "\nPlease specify an implementation in META-INF/services/${AbstractCashSelection::class.java}")
}.invoke() }.invoke()
} }
@ -84,7 +80,7 @@ abstract class AbstractCashSelection(private val maxRetries: Int = 8, private va
abstract fun executeQuery(connection: Connection, amount: Amount<Currency>, lockId: UUID, notary: Party?, abstract fun executeQuery(connection: Connection, amount: Amount<Currency>, lockId: UUID, notary: Party?,
onlyFromIssuerParties: Set<AbstractParty>, withIssuerRefs: Set<OpaqueBytes>, withResultSet: (ResultSet) -> Boolean): Boolean onlyFromIssuerParties: Set<AbstractParty>, withIssuerRefs: Set<OpaqueBytes>, withResultSet: (ResultSet) -> Boolean): Boolean
override abstract fun toString(): String abstract override fun toString(): String
/** /**
* Query to gather Cash states that are available and retry if they are temporarily unavailable. * Query to gather Cash states that are available and retry if they are temporarily unavailable.
@ -149,7 +145,7 @@ abstract class AbstractCashSelection(private val maxRetries: Int = 8, private va
if (stateRefs.isNotEmpty()) { if (stateRefs.isNotEmpty()) {
// TODO: future implementation to retrieve contract states from a Vault BLOB store // TODO: future implementation to retrieve contract states from a Vault BLOB store
stateAndRefs.addAll(services.loadStates(stateRefs) as Collection<StateAndRef<Cash.State>>) stateAndRefs.addAll(uncheckedCast(services.loadStates(stateRefs)))
} }
val success = stateAndRefs.isNotEmpty() && totalPennies >= amount.quantity val success = stateAndRefs.isNotEmpty() && totalPennies >= amount.quantity

View File

@ -13,6 +13,9 @@ package com.r3.corda.enterprise.perftestcordapp.flows
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.cash.selection.AbstractCashSelection import com.r3.corda.enterprise.perftestcordapp.contracts.asset.cash.selection.AbstractCashSelection
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.FINALISING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.SIGNING_TX
import com.r3.corda.enterprise.perftestcordapp.issuedBy import com.r3.corda.enterprise.perftestcordapp.issuedBy
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.contracts.InsufficientBalanceException import net.corda.core.contracts.InsufficientBalanceException
@ -60,10 +63,13 @@ class CashExitFlow(private val amount: Amount<Currency>,
.getInstance { serviceHub.jdbcSession().metaData } .getInstance { serviceHub.jdbcSession().metaData }
.unconsumedCashStatesForSpending(serviceHub, amount, setOf(issuer.party), builder.notary, builder.lockId, setOf(issuer.reference)) .unconsumedCashStatesForSpending(serviceHub, amount, setOf(issuer.party), builder.notary, builder.lockId, setOf(issuer.reference))
val signers = try { val signers = try {
val changeOwner = exitStates.map { it.state.data.owner }.toSet().firstOrNull() ?: throw InsufficientBalanceException(amount)
Cash().generateExit( Cash().generateExit(
builder, builder,
amount.issuedBy(issuer), amount.issuedBy(issuer),
exitStates) exitStates,
changeOwner
)
} catch (e: InsufficientBalanceException) { } catch (e: InsufficientBalanceException) {
throw CashException("Exiting more cash than exists", e) throw CashException("Exiting more cash than exists", e)
} }

View File

@ -14,6 +14,10 @@ import co.paralleluniverse.fibers.Suspendable
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.OnLedgerAsset import com.r3.corda.enterprise.perftestcordapp.contracts.asset.OnLedgerAsset
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.PartyAndAmount import com.r3.corda.enterprise.perftestcordapp.contracts.asset.PartyAndAmount
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.FINALISING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_ID
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.SIGNING_TX
import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesFlow
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.flows.FlowException import net.corda.core.flows.FlowException
@ -23,6 +27,7 @@ import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.uncheckedCast
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
@ -54,7 +59,7 @@ class CashIssueAndDoublePayment(val amount: Amount<Currency>,
= txState.copy(data = txState.data.copy(amount = amt, owner = owner)) = txState.copy(data = txState.data.copy(amount = amt, owner = owner))
val issueResult = subFlow(CashIssueFlow(amount, issueRef, notary)) val issueResult = subFlow(CashIssueFlow(amount, issueRef, notary))
val cashStateAndRef = serviceHub.loadStates(setOf(StateRef(issueResult.id, 0))).single() as StateAndRef<Cash.State> val cashStateAndRef: StateAndRef<Cash.State> = uncheckedCast(serviceHub.loadStates(setOf(StateRef(issueResult.id, 0))).single())
progressTracker.currentStep = GENERATING_ID progressTracker.currentStep = GENERATING_ID
val txIdentities = if (anonymous) { val txIdentities = if (anonymous) {
@ -86,7 +91,7 @@ class CashIssueAndDoublePayment(val amount: Amount<Currency>,
progressTracker.currentStep = FINALISING_TX progressTracker.currentStep = FINALISING_TX
val notarised1 = finaliseTx(tx1, setOf(recipient), "Unable to notarise spend first time") val notarised1 = finaliseTx(tx1, setOf(recipient), "Unable to notarise spend first time")
try { try {
val notarised2 = finaliseTx(tx2, setOf(recipient), "Unable to notarise spend second time") finaliseTx(tx2, setOf(recipient), "Unable to notarise spend second time")
} catch (expected: CashException) { } catch (expected: CashException) {
val cause = expected.cause val cause = expected.cause
if (cause is NotaryException) { if (cause is NotaryException) {

View File

@ -14,12 +14,17 @@ import co.paralleluniverse.fibers.Suspendable
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.OnLedgerAsset import com.r3.corda.enterprise.perftestcordapp.contracts.asset.OnLedgerAsset
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.PartyAndAmount import com.r3.corda.enterprise.perftestcordapp.contracts.asset.PartyAndAmount
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.FINALISING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_ID
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.SIGNING_TX
import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesFlow
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.uncheckedCast
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
@ -51,7 +56,7 @@ class CashIssueAndDuplicatePayment(val amount: Amount<Currency>,
= txState.copy(data = txState.data.copy(amount = amt, owner = owner)) = txState.copy(data = txState.data.copy(amount = amt, owner = owner))
val issueResult = subFlow(CashIssueFlow(amount, issueRef, notary)) val issueResult = subFlow(CashIssueFlow(amount, issueRef, notary))
val cashStateAndRef = serviceHub.loadStates(setOf(StateRef(issueResult.id, 0))).single() as StateAndRef<Cash.State> val cashStateAndRef: StateAndRef<Cash.State> = uncheckedCast(serviceHub.loadStates(setOf(StateRef(issueResult.id, 0))).single())
progressTracker.currentStep = GENERATING_ID progressTracker.currentStep = GENERATING_ID
val txIdentities = if (anonymous) { val txIdentities = if (anonymous) {
@ -74,7 +79,7 @@ class CashIssueAndDuplicatePayment(val amount: Amount<Currency>,
val tx = serviceHub.signInitialTransaction(spendTx, keysForSigning) val tx = serviceHub.signInitialTransaction(spendTx, keysForSigning)
progressTracker.currentStep = FINALISING_TX progressTracker.currentStep = FINALISING_TX
val notarised1 = finaliseTx(tx, setOf(recipient), "Unable to notarise spend first time") finaliseTx(tx, setOf(recipient), "Unable to notarise spend first time")
val notarised2 = finaliseTx(tx, setOf(recipient), "Unable to notarise spend second time") val notarised2 = finaliseTx(tx, setOf(recipient), "Unable to notarise spend second time")
return Result(notarised2.id, recipient) return Result(notarised2.id, recipient)

View File

@ -14,12 +14,17 @@ import co.paralleluniverse.fibers.Suspendable
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.OnLedgerAsset import com.r3.corda.enterprise.perftestcordapp.contracts.asset.OnLedgerAsset
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.PartyAndAmount import com.r3.corda.enterprise.perftestcordapp.contracts.asset.PartyAndAmount
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.FINALISING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_ID
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.SIGNING_TX
import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesFlow
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.uncheckedCast
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
@ -51,7 +56,7 @@ class CashIssueAndPaymentNoSelection(val amount: Amount<Currency>,
progressTracker.currentStep = GENERATING_TX progressTracker.currentStep = GENERATING_TX
val issueResult = subFlow(CashIssueFlow(amount, issueRef, notary)) val issueResult = subFlow(CashIssueFlow(amount, issueRef, notary))
val cashStateAndRef = serviceHub.loadStates(setOf(StateRef(issueResult.id, 0))).single() as StateAndRef<Cash.State> val cashStateAndRef: StateAndRef<Cash.State> = uncheckedCast(serviceHub.loadStates(setOf(StateRef(issueResult.id, 0))).single())
progressTracker.currentStep = GENERATING_ID progressTracker.currentStep = GENERATING_ID
val txIdentities = if (anonymous) { val txIdentities = if (anonymous) {

View File

@ -12,6 +12,9 @@ package com.r3.corda.enterprise.perftestcordapp.flows
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.FINALISING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.SIGNING_TX
import com.r3.corda.enterprise.perftestcordapp.issuedBy import com.r3.corda.enterprise.perftestcordapp.issuedBy
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC

View File

@ -12,6 +12,10 @@ package com.r3.corda.enterprise.perftestcordapp.flows
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.FINALISING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_ID
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.GENERATING_TX
import com.r3.corda.enterprise.perftestcordapp.flows.AbstractCashFlow.Companion.SIGNING_TX
import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesFlow
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.contracts.InsufficientBalanceException import net.corda.core.contracts.InsufficientBalanceException

View File

@ -104,8 +104,7 @@ class LinearStateBatchNotariseFlow(private val notary: Party,
} }
builder.addCommand(LinearStateBatchNotariseContract.Commands.Evolve(), us.owningKey) builder.addCommand(LinearStateBatchNotariseContract.Commands.Evolve(), us.owningKey)
builder.setTimeWindow(TimeWindow.fromOnly(serviceHub.clock.instant())) builder.setTimeWindow(TimeWindow.fromOnly(serviceHub.clock.instant()))
val tx = serviceHub.signInitialTransaction(builder, us.owningKey) return serviceHub.signInitialTransaction(builder, us.owningKey)
return tx
} }
@Suspendable @Suspendable
@ -117,17 +116,16 @@ class LinearStateBatchNotariseFlow(private val notary: Party,
@Suspendable @Suspendable
private fun assembleInitialTx(us: Party): SignedTransaction { private fun assembleInitialTx(us: Party): SignedTransaction {
val builder = TransactionBuilder(notary) val builder = TransactionBuilder(notary)
(0 until n).forEach { outputIndex -> (0 until n).forEach {
builder.addOutputState(TransactionState(LinearStateBatchNotariseContract.State(UniqueIdentifier(), us, serviceHub.clock.instant()), LinearStateBatchNotariseContract.CP_PROGRAM_ID, notary)) builder.addOutputState(TransactionState(LinearStateBatchNotariseContract.State(UniqueIdentifier(), us, serviceHub.clock.instant()), LinearStateBatchNotariseContract.CP_PROGRAM_ID, notary))
} }
builder.addCommand(LinearStateBatchNotariseContract.Commands.Create(), us.owningKey) builder.addCommand(LinearStateBatchNotariseContract.Commands.Create(), us.owningKey)
builder.setTimeWindow(TimeWindow.fromOnly(serviceHub.clock.instant())) builder.setTimeWindow(TimeWindow.fromOnly(serviceHub.clock.instant()))
val tx = serviceHub.signInitialTransaction(builder, us.owningKey) return serviceHub.signInitialTransaction(builder, us.owningKey)
return tx
} }
@Suspendable @Suspendable
protected fun finaliseTx(tx: SignedTransaction, message: String): SignedTransaction { private fun finaliseTx(tx: SignedTransaction, message: String): SignedTransaction {
try { try {
return subFlow(FinalityFlow(tx)) return subFlow(FinalityFlow(tx))
} catch (e: NotaryException) { } catch (e: NotaryException) {

View File

@ -11,9 +11,6 @@
package net.corda.testing.node package net.corda.testing.node
import com.google.common.collect.MutableClassToInstanceMap import com.google.common.collect.MutableClassToInstanceMap
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigParseOptions
import net.corda.core.contracts.ContractClassName import net.corda.core.contracts.ContractClassName
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.cordapp.CordappProvider import net.corda.core.cordapp.CordappProvider
@ -34,9 +31,6 @@ import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.internal.ServicesForResolutionImpl import net.corda.node.internal.ServicesForResolutionImpl
import net.corda.node.internal.configureDatabase import net.corda.node.internal.configureDatabase
import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.services.api.SchemaService
import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.api.* import net.corda.node.services.api.*
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.schema.HibernateObserver import net.corda.node.services.schema.HibernateObserver
@ -89,7 +83,7 @@ open class MockServices private constructor(
*/ */
@JvmStatic @JvmStatic
fun makeTestDataSourceProperties(nodeName: String = SecureHash.randomSHA256().toString()): Properties { fun makeTestDataSourceProperties(nodeName: String = SecureHash.randomSHA256().toString()): Properties {
return makeTestDataSourceProperties(nodeName, null, ::databaseProviderDataSourceConfig, ::inMemoryH2DataSourceConfig) return makeInternalTestDataSourceProperties(nodeName)
} }
/** /**
@ -109,7 +103,7 @@ open class MockServices private constructor(
networkParameters: NetworkParameters = testNetworkParameters(), networkParameters: NetworkParameters = testNetworkParameters(),
vararg moreKeys: KeyPair): Pair<CordaPersistence, MockServices> { vararg moreKeys: KeyPair): Pair<CordaPersistence, MockServices> {
val cordappLoader = CordappLoader.createWithTestPackages(cordappPackages) val cordappLoader = CordappLoader.createWithTestPackages(cordappPackages)
val dataSourceProps = makeTestDataSourceProperties(initialIdentity.name.organisation, SecureHash.randomSHA256().toString()) val dataSourceProps = makeInternalTestDataSourceProperties(initialIdentity.name.organisation, SecureHash.randomSHA256().toString())
val schemaService = NodeSchemaService(cordappLoader.cordappSchemas) val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
val database = configureDatabase(dataSourceProps, makeTestDatabaseProperties(initialIdentity.name.organisation), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService) val database = configureDatabase(dataSourceProps, makeTestDatabaseProperties(initialIdentity.name.organisation), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService)
val mockService = database.transaction { val mockService = database.transaction {

View File

@ -383,7 +383,7 @@ open class InternalMockNetwork(private val cordappPackages: List<String>,
val config = mockNodeConfiguration().also { val config = mockNodeConfiguration().also {
doReturn(baseDirectory(id).createDirectories()).whenever(it).baseDirectory doReturn(baseDirectory(id).createDirectories()).whenever(it).baseDirectory
doReturn(parameters.legalName ?: CordaX500Name("Mock Company $id", "London", "GB")).whenever(it).myLegalName doReturn(parameters.legalName ?: CordaX500Name("Mock Company $id", "London", "GB")).whenever(it).myLegalName
doReturn(makeTestDataSourceProperties("node_$id","net_$networkId")).whenever(it).dataSourceProperties doReturn(makeInternalTestDataSourceProperties("node_$id", "net_$networkId")).whenever(it).dataSourceProperties
doReturn(makeTestDatabaseProperties("node_$id")).whenever(it).database doReturn(makeTestDatabaseProperties("node_$id")).whenever(it).database
doReturn(emptyList<SecureHash>()).whenever(it).extraNetworkMapKeys doReturn(emptyList<SecureHash>()).whenever(it).extraNetworkMapKeys
parameters.configOverrides(it) parameters.configOverrides(it)

View File

@ -146,16 +146,16 @@ internal interface InternalMockMessagingService : MessagingService {
* @param nodeName Reflects the "instance" of the in-memory database or database username/schema. * @param nodeName Reflects the "instance" of the in-memory database or database username/schema.
* Defaults to a random string. Passed to [configSupplier] and [fallBackConfigSupplier] methods. * Defaults to a random string. Passed to [configSupplier] and [fallBackConfigSupplier] methods.
* @param nodeNameExtension Provides additional name extension for [configSupplier] and [fallBackConfigSupplier]. * @param nodeNameExtension Provides additional name extension for [configSupplier] and [fallBackConfigSupplier].
* @param configSupplier Returns [Config] with dataSourceProperties, invoked with [nodeName] and [nodeNameExtension] parameters. * @param configSupplier Returns [Config] with dataSourceProperties, invoked with [nodeName].
* Defaults to configuration created when 'databaseProvider' system property is set. * Defaults to configuration created when 'databaseProvider' system property is set.
* @param fallBackConfigSupplier Returns [Config] with dataSourceProperties, invoked with [nodeName] and [nodeNameExtension] parameters. * @param fallBackConfigSupplier Returns [Config] with dataSourceProperties, invoked with [nodeName] and [nodeNameExtension] parameters.
* Defaults to configuration of in-memory H2 instance. * Defaults to configuration of in-memory H2 instance.
*/ */
fun makeTestDataSourceProperties(nodeName: String? = SecureHash.randomSHA256().toString(), fun makeInternalTestDataSourceProperties(nodeName: String? = SecureHash.randomSHA256().toString(),
nodeNameExtension: String? = null, nodeNameExtension: String? = null,
configSupplier: (String?, String?) -> Config = ::databaseProviderDataSourceConfig, configSupplier: (String?) -> Config = ::databaseProviderDataSourceConfig,
fallBackConfigSupplier: (String?, String?) -> Config = ::inMemoryH2DataSourceConfig): Properties { fallBackConfigSupplier: (String?, String?) -> Config = ::inMemoryH2DataSourceConfig): Properties {
val config = configSupplier(nodeName, nodeNameExtension) val config = configSupplier(nodeName)
.withFallback(fallBackConfigSupplier(nodeName, nodeNameExtension)) .withFallback(fallBackConfigSupplier(nodeName, nodeNameExtension))
.resolve() .resolve()
@ -175,8 +175,8 @@ fun makeTestDataSourceProperties(nodeName: String? = SecureHash.randomSHA256().t
* @param configSupplier Returns [Config] with databaseProperties, invoked with [nodeName] parameter. * @param configSupplier Returns [Config] with databaseProperties, invoked with [nodeName] parameter.
*/ */
fun makeTestDatabaseProperties(nodeName: String? = null, fun makeTestDatabaseProperties(nodeName: String? = null,
configSupplier: (String?, String?) -> Config = ::databaseProviderDataSourceConfig): DatabaseConfig { configSupplier: (String?) -> Config = ::databaseProviderDataSourceConfig): DatabaseConfig {
val config = configSupplier(nodeName, null) val config = configSupplier(nodeName)
val transactionIsolationLevel = if (config.hasPath(DatabaseConstants.TRANSACTION_ISOLATION_LEVEL)) val transactionIsolationLevel = if (config.hasPath(DatabaseConstants.TRANSACTION_ISOLATION_LEVEL))
TransactionIsolationLevel.valueOf(config.getString(DatabaseConstants.TRANSACTION_ISOLATION_LEVEL)) TransactionIsolationLevel.valueOf(config.getString(DatabaseConstants.TRANSACTION_ISOLATION_LEVEL))
else TransactionIsolationLevel.READ_COMMITTED else TransactionIsolationLevel.READ_COMMITTED
@ -188,11 +188,9 @@ fun makeTestDatabaseProperties(nodeName: String? = null,
* Reads database and dataSource configuration from a file denoted by 'databaseProvider' system property, * Reads database and dataSource configuration from a file denoted by 'databaseProvider' system property,
* overwritten by system properties and defaults to H2 in memory db. * overwritten by system properties and defaults to H2 in memory db.
* @param nodeName Reflects the "instance" of the database username/schema, the value will be used to replace ${custom.nodeOrganizationName} placeholder * @param nodeName Reflects the "instance" of the database username/schema, the value will be used to replace ${custom.nodeOrganizationName} placeholder
* @param notUsed Not uses, required for API backward compatibility.
* if the placeholder is present in config. * if the placeholder is present in config.
*/ */
fun databaseProviderDataSourceConfig(nodeName: String? = null, notUsed: String? = null): Config { fun databaseProviderDataSourceConfig(nodeName: String? = null): Config {
val parseOptions = ConfigParseOptions.defaults() val parseOptions = ConfigParseOptions.defaults()
val keys = listOf(DatabaseConstants.DATA_SOURCE_URL, DatabaseConstants.DATA_SOURCE_CLASSNAME, val keys = listOf(DatabaseConstants.DATA_SOURCE_URL, DatabaseConstants.DATA_SOURCE_CLASSNAME,
@ -218,11 +216,11 @@ fun databaseProviderDataSourceConfig(nodeName: String? = null, notUsed: String?
/** /**
* Creates data source configuration for in memory H2 as it would be specified in reference.conf 'datasource' snippet. * Creates data source configuration for in memory H2 as it would be specified in reference.conf 'datasource' snippet.
* @param nodeName Reflects the "instance" of the database username/schema * @param providedNodeName Reflects the "instance" of the database username/schema
* @param postfix Additional postix added to database "instance" name to add uniqueness when running integration tests. * @param postfix Additional postix added to database "instance" name to add uniqueness when running integration tests.
*/ */
fun inMemoryH2DataSourceConfig(nodeName: String? = null, postfix: String? = null) : Config { fun inMemoryH2DataSourceConfig(providedNodeName: String? = null, postfix: String? = null) : Config {
val nodeName = nodeName ?: SecureHash.randomSHA256().toString() val nodeName = providedNodeName ?: SecureHash.randomSHA256().toString()
val h2InstanceName = if (postfix != null) nodeName + "_" + postfix else nodeName val h2InstanceName = if (postfix != null) nodeName + "_" + postfix else nodeName
return ConfigFactory.parseMap(mapOf( return ConfigFactory.parseMap(mapOf(

View File

@ -12,6 +12,7 @@ import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.doneFuture import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.internal.openHttpConnection import net.corda.core.internal.openHttpConnection
import net.corda.core.internal.responseAs import net.corda.core.internal.responseAs
import net.corda.core.internal.uncheckedCast
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.AttachmentId import net.corda.core.node.services.AttachmentId
@ -29,7 +30,6 @@ import java.time.Instant
import javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM import javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM
class CordaRPCProxyClient(private val targetHostAndPort: NetworkHostAndPort) : CordaRPCOps { class CordaRPCProxyClient(private val targetHostAndPort: NetworkHostAndPort) : CordaRPCOps {
companion object { companion object {
val log = contextLogger() val log = contextLogger()
} }
@ -47,7 +47,7 @@ class CordaRPCProxyClient(private val targetHostAndPort: NetworkHostAndPort) : C
log.info("Corda RPC Proxy client calling: $flowName with values: $argList") log.info("Corda RPC Proxy client calling: $flowName with values: $argList")
val response = doPost<Any>(targetHostAndPort, "start-flow", argList.serialize().bytes) val response = doPost<Any>(targetHostAndPort, "start-flow", argList.serialize().bytes)
val result = doneFuture(response) val result = doneFuture(response)
return FlowHandleImpl(StateMachineRunId.createRandom(), result) as FlowHandle<T> return uncheckedCast(FlowHandleImpl(StateMachineRunId.createRandom(), result))
} }
override fun nodeInfo(): NodeInfo { override fun nodeInfo(): NodeInfo {

View File

@ -25,6 +25,7 @@ import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response import javax.ws.rs.core.Response
import javax.ws.rs.core.Response.status import javax.ws.rs.core.Response.status
@Suppress("UNUSED_PARAMETER")
@Path(RPC_PROXY_PATH) @Path(RPC_PROXY_PATH)
class RPCProxyWebService(targetHostAndPort: NetworkHostAndPort) { class RPCProxyWebService(targetHostAndPort: NetworkHostAndPort) {
@ -108,7 +109,7 @@ class RPCProxyWebService(targetHostAndPort: NetworkHostAndPort) {
fun vaultQuery(input: InputStream): Response { fun vaultQuery(input: InputStream): Response {
log.info("vaultQuery") log.info("vaultQuery")
val contractStateType = input.readBytes().deserialize<String>() val contractStateType = input.readBytes().deserialize<String>()
val clazz = Class.forName(contractStateType) as Class<ContractState> val clazz = Class.forName(contractStateType).asSubclass(ContractState::class.java)
return use { return use {
log.info("Calling vaultQuery with: $clazz") log.info("Calling vaultQuery with: $clazz")
it.vaultQuery(clazz) it.vaultQuery(clazz)
@ -125,7 +126,7 @@ class RPCProxyWebService(targetHostAndPort: NetworkHostAndPort) {
for (i in argsList.indices) { for (i in argsList.indices) {
log.info("$i: ${argsList[i]}") log.info("$i: ${argsList[i]}")
} }
val flowClass = Class.forName(argsList[0] as String) as Class<FlowLogic<*>> val flowClass = Class.forName(argsList[0] as String).asSubclass(FlowLogic::class.java)
val flowArgs = argsList.drop(1).toTypedArray() val flowArgs = argsList.drop(1).toTypedArray()
log.info("Calling flow: $flowClass with arguments: ${flowArgs.asList()}") log.info("Calling flow: $flowClass with arguments: ${flowArgs.asList()}")
rpcClient.startFlowDynamic(flowClass, *flowArgs).returnValue.getOrThrow() rpcClient.startFlowDynamic(flowClass, *flowArgs).returnValue.getOrThrow()

View File

@ -176,7 +176,7 @@ private fun handleCommand(options: OptionSet, baseDirectory: Path, configFile: P
options.has(DRY_RUN) -> { options.has(DRY_RUN) -> {
val writer = getMigrationOutput(baseDirectory, options) val writer = getMigrationOutput(baseDirectory, options)
migrationLogger.info("Exporting the current db migrations ...") migrationLogger.info("Exporting the current db migrations ...")
runMigrationCommand { migration, dataSource -> runMigrationCommand { migration, _ ->
migration.generateMigrationScript(writer) migration.generateMigrationScript(writer)
} }
} }
@ -240,7 +240,7 @@ private fun runWithDataSource(config: Configuration, baseDirectory: Path, classL
val jarDirs = config.jarDirs.map { Paths.get(it) } val jarDirs = config.jarDirs.map { Paths.get(it) }
for (jarDir in jarDirs) { for (jarDir in jarDirs) {
if (!jarDir.exists()) { if (!jarDir.exists()) {
errorAndExit("Could not find the configured JDBC driver directory: '${jarDir}'.") errorAndExit("Could not find the configured JDBC driver directory: '$jarDir'.")
} }
} }
@ -252,7 +252,7 @@ private fun runWithDataSource(config: Configuration, baseDirectory: Path, classL
errorAndExit("""Failed to create datasource. errorAndExit("""Failed to create datasource.
|Please check that the correct JDBC driver is installed in one of the following folders: |Please check that the correct JDBC driver is installed in one of the following folders:
|${(driversFolder + jarDirs).joinToString("\n\t - ", "\t - ")} |${(driversFolder + jarDirs).joinToString("\n\t - ", "\t - ")}
|Caused By ${e}""".trimMargin(), e) |Caused By $e""".trimMargin(), e)
} }
} }

View File

@ -248,7 +248,7 @@ class TransactionViewer : CordaView("Transactions") {
} }
override fun computeValue(): SecureHash { override fun computeValue(): SecureHash {
return if (hashList.isEmpty()) SecureHash.zeroHash return if (hashList.isEmpty()) SecureHash.zeroHash
else hashList.fold(hashList[0], { one, another -> one.hashConcat(another) }) else hashList.fold(hashList[0], SecureHash::hashConcat)
} }
} }
graphicProperty().bind(hashBinding.map { identicon(it, 30.0) }) graphicProperty().bind(hashBinding.map { identicon(it, 30.0) })
@ -325,7 +325,7 @@ class TransactionViewer : CordaView("Transactions") {
} }
} }
is IOUState -> { is IOUState -> {
fun Pane.partyLabel(party: Party) = label(party.nameOrNull().let { PartyNameFormatter.short.format(it) } ?: "Anonymous") { fun Pane.partyLabel(party: Party) = label(party.nameOrNull().let { PartyNameFormatter.short.format(it) }) {
tooltip(party.owningKey.toBase58String()) tooltip(party.owningKey.toBase58String())
} }
row { row {
@ -363,8 +363,7 @@ private fun calculateTotalEquiv(myIdentity: Party?,
outputs: List<ContractState>): AmountDiff<Currency> { outputs: List<ContractState>): AmountDiff<Currency> {
val (reportingCurrency, exchange) = reportingCurrencyExchange val (reportingCurrency, exchange) = reportingCurrencyExchange
fun List<ContractState>.sum(): Long { fun List<ContractState>.sum(): Long {
val cashSum: Long = map { it as? Cash.State } val cashSum: Long = mapNotNull { it as? Cash.State }
.filterNotNull()
.filter { it.owner.owningKey.toKnownParty().value == myIdentity } .filter { it.owner.owningKey.toKnownParty().value == myIdentity }
.map { exchange(it.amount.withoutIssuer()).quantity } .map { exchange(it.amount.withoutIssuer()).quantity }
.sum() .sum()

View File

@ -16,7 +16,7 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.internal.LazyPool import net.corda.core.internal.LazyPool
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.contextLogger
import org.apache.jmeter.config.Argument import org.apache.jmeter.config.Argument
import org.apache.jmeter.config.Arguments import org.apache.jmeter.config.Arguments
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient
@ -27,7 +27,7 @@ import java.util.*
/** /**
* Do most of the work for firing flow start requests via RPC at a Corda node. * Do most of the work for firing flow start requests via RPC at a Corda node.
*/ */
abstract class BaseFlowSampler() : AbstractJavaSamplerClient() { abstract class BaseFlowSampler : AbstractJavaSamplerClient() {
companion object { companion object {
private data class RPCParams(val address: NetworkHostAndPort, val user: String, val password: String) private data class RPCParams(val address: NetworkHostAndPort, val user: String, val password: String)
private data class RPCClient(val rpcClient: CordaRPCClient, val rpcConnection: CordaRPCConnection, val ops: CordaRPCOps) private data class RPCClient(val rpcClient: CordaRPCClient, val rpcConnection: CordaRPCConnection, val ops: CordaRPCOps)
@ -40,7 +40,7 @@ abstract class BaseFlowSampler() : AbstractJavaSamplerClient() {
val allArgs = setOf(label, host, port, username, password) val allArgs = setOf(label, host, port, username, password)
val log = loggerFor<BaseFlowSampler>() val log = contextLogger()
private val rpcClientPools = Collections.synchronizedMap(mutableMapOf<RPCParams, LazyPool<RPCClient>>()) private val rpcClientPools = Collections.synchronizedMap(mutableMapOf<RPCParams, LazyPool<RPCClient>>())
} }
@ -48,7 +48,7 @@ abstract class BaseFlowSampler() : AbstractJavaSamplerClient() {
private var rpcParams: RPCParams? = null private var rpcParams: RPCParams? = null
private var rpcPool: LazyPool<RPCClient>? = null private var rpcPool: LazyPool<RPCClient>? = null
var labelValue: String? = null private var labelValue: String? = null
override fun getDefaultParameters(): Arguments { override fun getDefaultParameters(): Arguments {
// Add copies of all args, since they seem to be mutable. // Add copies of all args, since they seem to be mutable.
@ -70,7 +70,7 @@ abstract class BaseFlowSampler() : AbstractJavaSamplerClient() {
labelValue = null labelValue = null
} }
rpcPool = rpcClientPools.computeIfAbsent(rpcParams) { rpcPool = rpcClientPools.computeIfAbsent(rpcParams) {
LazyPool<RPCClient> { LazyPool {
val rpcClient = CordaRPCClient(it.address) val rpcClient = CordaRPCClient(it.address)
val rpcConnection = rpcClient.start(it.user, it.password) val rpcConnection = rpcClient.start(it.user, it.password)
val rpcProxy = rpcConnection.proxy val rpcProxy = rpcConnection.proxy
@ -98,14 +98,14 @@ abstract class BaseFlowSampler() : AbstractJavaSamplerClient() {
try { try {
val flowResult = handle.returnValue.get() val flowResult = handle.returnValue.get()
result.sampleEnd() result.sampleEnd()
return result.apply { result.apply {
isSuccessful = true isSuccessful = true
additionalFlowResponseProcessing(context, this, flowResult) additionalFlowResponseProcessing(context, this, flowResult)
} }
} catch (e: Exception) { } catch (e: Exception) {
result.sampleEnd() result.sampleEnd()
e.printStackTrace() e.printStackTrace()
return result.apply { result.apply {
isSuccessful = false isSuccessful = false
additionalFlowResponseProcessing(context, this, e) additionalFlowResponseProcessing(context, this, e)
} }

View File

@ -16,9 +16,6 @@ import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.notarytest.service.JDBCLoadTestFlow import net.corda.notarytest.service.JDBCLoadTestFlow
import java.io.File
import java.io.PrintWriter
import java.time.Instant
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/** The number of test flows to run on each notary node */ /** The number of test flows to run on each notary node */
@ -43,7 +40,7 @@ fun main(args: Array<String>) {
CordaRPCClient(it).start(notaryDemoUser.username, notaryDemoUser.password).use { CordaRPCClient(it).start(notaryDemoUser.username, notaryDemoUser.password).use {
println(it.proxy.nodeInfo()) println(it.proxy.nodeInfo())
val totalTime = Stopwatch.createStarted() val totalTime = Stopwatch.createStarted()
val durations = run(it.proxy, 1) run(it.proxy, 1)
totalTime.stop() totalTime.stop()
val totalTx = TEST_RUNS * TRANSACTION_COUNT val totalTx = TEST_RUNS * TRANSACTION_COUNT
@ -65,13 +62,3 @@ private fun run(rpc: CordaRPCOps, inputStateCount: Int? = null): List<Long> {
flowDuration flowDuration
} }
} }
private fun printCSV(node: NetworkHostAndPort, durations: List<Long>, testRuns: Int, batchSize: Int) {
val pw = PrintWriter(File("notarytest-${Instant.now()}-${node.host}${node.port}-${testRuns}x$batchSize.csv"))
val sb = StringBuilder()
sb.append("$testRuns, $batchSize")
sb.append('\n')
sb.append(durations.joinToString())
pw.write(sb.toString())
pw.close()
}