mirror of
https://github.com/corda/corda.git
synced 2025-05-30 06:04:24 +00:00
Reformat files in node
This commit is contained in:
parent
7a372bed59
commit
cb9e27a84a
@ -32,7 +32,7 @@ class BootTests {
|
|||||||
driver {
|
driver {
|
||||||
val user = User("u", "p", setOf(startFlowPermission<ObjectInputStreamFlow>()))
|
val user = User("u", "p", setOf(startFlowPermission<ObjectInputStreamFlow>()))
|
||||||
val future = startNode(rpcUsers = listOf(user)).getOrThrow().rpcClientToNode().
|
val future = startNode(rpcUsers = listOf(user)).getOrThrow().rpcClientToNode().
|
||||||
start(user.username, user.password).proxy.startFlow(::ObjectInputStreamFlow).returnValue
|
start(user.username, user.password).proxy.startFlow(::ObjectInputStreamFlow).returnValue
|
||||||
assertThatThrownBy { future.getOrThrow() }.isInstanceOf(InvalidClassException::class.java).hasMessage("filter status: REJECTED")
|
assertThatThrownBy { future.getOrThrow() }.isInstanceOf(InvalidClassException::class.java).hasMessage("filter status: REJECTED")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ class CordappScanningDriverTest {
|
|||||||
|
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
class ReceiveFlow(val otherParty: Party) :FlowLogic<String>() {
|
class ReceiveFlow(val otherParty: Party) : FlowLogic<String>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): String = initiateFlow(otherParty).receive<String>().unwrap { it }
|
override fun call(): String = initiateFlow(otherParty).receive<String>().unwrap { it }
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class NodeStartupPerformanceTests {
|
|||||||
driver(networkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = false)) {
|
driver(networkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = false)) {
|
||||||
startDedicatedNetworkMapService().get()
|
startDedicatedNetworkMapService().get()
|
||||||
val times = ArrayList<Long>()
|
val times = ArrayList<Long>()
|
||||||
for (i in 1 .. 10) {
|
for (i in 1..10) {
|
||||||
val time = Stopwatch.createStarted().apply {
|
val time = Stopwatch.createStarted().apply {
|
||||||
startNode().get()
|
startNode().get()
|
||||||
}.stop().elapsed(TimeUnit.MICROSECONDS)
|
}.stop().elapsed(TimeUnit.MICROSECONDS)
|
||||||
|
@ -70,7 +70,7 @@ class AttachmentLoadingTests : TestDependencyInjectionBase() {
|
|||||||
val contract = contractClass.newInstance()
|
val contract = contractClass.newInstance()
|
||||||
val txBuilder = generateInitialMethod.invoke(contract, PartyAndReference(DUMMY_BANK_A, OpaqueBytes(kotlin.ByteArray(1))), 1, DUMMY_NOTARY) as TransactionBuilder
|
val txBuilder = generateInitialMethod.invoke(contract, PartyAndReference(DUMMY_BANK_A, OpaqueBytes(kotlin.ByteArray(1))), 1, DUMMY_NOTARY) as TransactionBuilder
|
||||||
val context = SerializationFactory.defaultFactory.defaultContext
|
val context = SerializationFactory.defaultFactory.defaultContext
|
||||||
.withClassLoader(appClassLoader)
|
.withClassLoader(appClassLoader)
|
||||||
val ledgerTx = txBuilder.toLedgerTransaction(services, context)
|
val ledgerTx = txBuilder.toLedgerTransaction(services, context)
|
||||||
contract.verify(ledgerTx)
|
contract.verify(ledgerTx)
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ import kotlin.test.assertTrue
|
|||||||
|
|
||||||
class NodeInfoWatcherTest : NodeBasedTest() {
|
class NodeInfoWatcherTest : NodeBasedTest() {
|
||||||
|
|
||||||
@Rule @JvmField var folder = TemporaryFolder()
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
var folder = TemporaryFolder()
|
||||||
|
|
||||||
lateinit var keyManagementService: KeyManagementService
|
lateinit var keyManagementService: KeyManagementService
|
||||||
lateinit var nodeInfoPath: Path
|
lateinit var nodeInfoPath: Path
|
||||||
|
@ -170,8 +170,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
|||||||
(customRetryIntervalMs?.let { mapOf("activeMQServer.bridge.retryIntervalMs" to it.toString()) } ?: emptyMap())
|
(customRetryIntervalMs?.let { mapOf("activeMQServer.bridge.retryIntervalMs" to it.toString()) } ?: emptyMap())
|
||||||
if (party == DUMMY_NOTARY) {
|
if (party == DUMMY_NOTARY) {
|
||||||
startNetworkMapNode(party.name, configOverrides = configOverrides)
|
startNetworkMapNode(party.name, configOverrides = configOverrides)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
startNode(party.name,
|
startNode(party.name,
|
||||||
configOverrides = configOverrides,
|
configOverrides = configOverrides,
|
||||||
noNetworkMap = noNetworkMap,
|
noNetworkMap = noNetworkMap,
|
||||||
@ -184,7 +183,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
|||||||
private fun checkConnectivity(nodes: List<StartedNode<*>>) {
|
private fun checkConnectivity(nodes: List<StartedNode<*>>) {
|
||||||
nodes.forEach { node1 ->
|
nodes.forEach { node1 ->
|
||||||
nodes.forEach { node2 ->
|
nodes.forEach { node2 ->
|
||||||
if(!(node1 === node2)) { // Do not check connectivity to itself
|
if (!(node1 === node2)) { // Do not check connectivity to itself
|
||||||
node2.internals.registerInitiatedFlow(SendBackFlow::class.java)
|
node2.internals.registerInitiatedFlow(SendBackFlow::class.java)
|
||||||
val resultFuture = node1.services.startFlow(SendFlow(node2.info.chooseIdentity())).resultFuture
|
val resultFuture = node1.services.startFlow(SendFlow(node2.info.chooseIdentity())).resultFuture
|
||||||
assertThat(resultFuture.getOrThrow()).isEqualTo("Hello!")
|
assertThat(resultFuture.getOrThrow()).isEqualTo("Hello!")
|
||||||
|
@ -21,7 +21,8 @@ import kotlin.test.assertEquals
|
|||||||
* transaction size limit (which should only consider the hashes).
|
* transaction size limit (which should only consider the hashes).
|
||||||
*/
|
*/
|
||||||
class LargeTransactionsTest {
|
class LargeTransactionsTest {
|
||||||
@StartableByRPC @InitiatingFlow
|
@StartableByRPC
|
||||||
|
@InitiatingFlow
|
||||||
class SendLargeTransactionFlow(private val hash1: SecureHash,
|
class SendLargeTransactionFlow(private val hash1: SecureHash,
|
||||||
private val hash2: SecureHash,
|
private val hash2: SecureHash,
|
||||||
private val hash3: SecureHash,
|
private val hash3: SecureHash,
|
||||||
@ -44,7 +45,8 @@ class LargeTransactionsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitiatedBy(SendLargeTransactionFlow::class) @Suppress("UNUSED")
|
@InitiatedBy(SendLargeTransactionFlow::class)
|
||||||
|
@Suppress("UNUSED")
|
||||||
class ReceiveLargeTransactionFlow(private val otherSide: FlowSession) : FlowLogic<Unit>() {
|
class ReceiveLargeTransactionFlow(private val otherSide: FlowSession) : FlowLogic<Unit>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
|
@ -12,11 +12,11 @@ import java.util.*;
|
|||||||
import static net.corda.node.shell.InteractiveShell.*;
|
import static net.corda.node.shell.InteractiveShell.*;
|
||||||
|
|
||||||
@Man(
|
@Man(
|
||||||
"Allows you to start flows, list the ones available and to watch flows currently running on the node.\n\n" +
|
"Allows you to start flows, list the ones available and to watch flows currently running on the node.\n\n" +
|
||||||
"Starting flow is the primary way in which you command the node to change the ledger.\n\n" +
|
"Starting flow is the primary way in which you command the node to change the ledger.\n\n" +
|
||||||
"This command is generic, so the right way to use it depends on the flow you wish to start. You can use the 'flow start'\n" +
|
"This command is generic, so the right way to use it depends on the flow you wish to start. You can use the 'flow start'\n" +
|
||||||
"command with either a full class name, or a substring of the class name that's unambiguous. The parameters to the \n" +
|
"command with either a full class name, or a substring of the class name that's unambiguous. The parameters to the \n" +
|
||||||
"flow constructors (the right one is picked automatically) are then specified using the same syntax as for the run command."
|
"flow constructors (the right one is picked automatically) are then specified using the same syntax as for the run command."
|
||||||
)
|
)
|
||||||
public class FlowShellCommand extends InteractiveShellCommand {
|
public class FlowShellCommand extends InteractiveShellCommand {
|
||||||
@Command
|
@Command
|
||||||
|
@ -13,10 +13,10 @@ import java.util.*;
|
|||||||
public class RunShellCommand extends InteractiveShellCommand {
|
public class RunShellCommand extends InteractiveShellCommand {
|
||||||
@Command
|
@Command
|
||||||
@Man(
|
@Man(
|
||||||
"Runs a method from the CordaRPCOps interface, which is the same interface exposed to RPC clients.\n\n" +
|
"Runs a method from the CordaRPCOps interface, which is the same interface exposed to RPC clients.\n\n" +
|
||||||
|
|
||||||
"You can learn more about what commands are available by typing 'run' just by itself, or by\n" +
|
"You can learn more about what commands are available by typing 'run' just by itself, or by\n" +
|
||||||
"consulting the developer guide at https://docs.corda.net/api/kotlin/corda/net.corda.core.messaging/-corda-r-p-c-ops/index.html"
|
"consulting the developer guide at https://docs.corda.net/api/kotlin/corda/net.corda.core.messaging/-corda-r-p-c-ops/index.html"
|
||||||
)
|
)
|
||||||
@Usage("runs a method from the CordaRPCOps interface on the node.")
|
@Usage("runs a method from the CordaRPCOps interface on the node.")
|
||||||
public Object main(
|
public Object main(
|
||||||
|
@ -69,8 +69,8 @@ data class CmdLineOptions(val baseDirectory: Path,
|
|||||||
val isVersion: Boolean,
|
val isVersion: Boolean,
|
||||||
val noLocalShell: Boolean,
|
val noLocalShell: Boolean,
|
||||||
val sshdServer: Boolean,
|
val sshdServer: Boolean,
|
||||||
val justGenerateNodeInfo : Boolean) {
|
val justGenerateNodeInfo: Boolean) {
|
||||||
fun loadConfig() = ConfigHelper
|
fun loadConfig() = ConfigHelper
|
||||||
.loadConfig(baseDirectory, configFile)
|
.loadConfig(baseDirectory, configFile)
|
||||||
.parseAs<FullNodeConfiguration>()
|
.parseAs<FullNodeConfiguration>()
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
/**
|
/**
|
||||||
* This customizes the ServiceHub for each CordaService that is initiating flows
|
* This customizes the ServiceHub for each CordaService that is initiating flows
|
||||||
*/
|
*/
|
||||||
private class AppServiceHubImpl<T : SerializeAsToken>(val serviceHub: ServiceHubInternal): AppServiceHub, ServiceHub by serviceHub {
|
private class AppServiceHubImpl<T : SerializeAsToken>(val serviceHub: ServiceHubInternal) : AppServiceHub, ServiceHub by serviceHub {
|
||||||
lateinit var serviceInstance: T
|
lateinit var serviceInstance: T
|
||||||
override fun <T> startTrackedFlow(flow: FlowLogic<T>): FlowProgressHandle<T> {
|
override fun <T> startTrackedFlow(flow: FlowLogic<T>): FlowProgressHandle<T> {
|
||||||
val stateMachine = startFlowChecked(flow)
|
val stateMachine = startFlowChecked(flow)
|
||||||
|
@ -349,7 +349,7 @@ open class Node(override val configuration: FullNodeConfiguration,
|
|||||||
_startupComplete.set(Unit)
|
_startupComplete.set(Unit)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ th -> logger.error("Unexpected exception", th)}
|
{ th -> logger.error("Unexpected exception", th) }
|
||||||
)
|
)
|
||||||
shutdownHook = addShutdownHook {
|
shutdownHook = addShutdownHook {
|
||||||
stop()
|
stop()
|
||||||
|
@ -110,14 +110,14 @@ open class NodeStartup(val args: Array<String>) {
|
|||||||
startedNode.internals.startupComplete.then {
|
startedNode.internals.startupComplete.then {
|
||||||
try {
|
try {
|
||||||
InteractiveShell.startShell(cmdlineOptions.baseDirectory, runShell, cmdlineOptions.sshdServer, startedNode)
|
InteractiveShell.startShell(cmdlineOptions.baseDirectory, runShell, cmdlineOptions.sshdServer, startedNode)
|
||||||
} catch(e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
logger.error("Shell failed to start", e)
|
logger.error("Shell failed to start", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{ th ->
|
||||||
th -> logger.error("Unexpected exception during registration", th)
|
logger.error("Unexpected exception during registration", th)
|
||||||
})
|
})
|
||||||
startedNode.internals.run()
|
startedNode.internals.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class CordappLoader private constructor(private val cordappJarPaths: List<URL>)
|
|||||||
|
|
||||||
/** Takes a package of classes and creates a JAR from them - only use in tests. */
|
/** Takes a package of classes and creates a JAR from them - only use in tests. */
|
||||||
private fun createDevCordappJar(scanPackage: String, path: URL, jarPackageName: String): URI {
|
private fun createDevCordappJar(scanPackage: String, path: URL, jarPackageName: String): URI {
|
||||||
if(!generatedCordapps.contains(path)) {
|
if (!generatedCordapps.contains(path)) {
|
||||||
val cordappDir = File("build/tmp/generated-test-cordapps")
|
val cordappDir = File("build/tmp/generated-test-cordapps")
|
||||||
cordappDir.mkdirs()
|
cordappDir.mkdirs()
|
||||||
val cordappJAR = File(cordappDir, "$scanPackage-${UUID.randomUUID()}.jar")
|
val cordappJAR = File(cordappDir, "$scanPackage-${UUID.randomUUID()}.jar")
|
||||||
|
@ -19,7 +19,7 @@ open class CordappProviderImpl(private val cordappLoader: CordappLoader) : Singl
|
|||||||
// TODO: Use better supported APIs in Java 9
|
// TODO: Use better supported APIs in Java 9
|
||||||
Exception().stackTrace.forEach { stackFrame ->
|
Exception().stackTrace.forEach { stackFrame ->
|
||||||
val cordapp = getCordappForClass(stackFrame.className)
|
val cordapp = getCordappForClass(stackFrame.className)
|
||||||
if(cordapp != null) {
|
if (cordapp != null) {
|
||||||
return getAppContext(cordapp)
|
return getAppContext(cordapp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,7 @@ data class FlowPermissionAuditEvent(override val timestamp: Instant,
|
|||||||
override val flowId: StateMachineRunId,
|
override val flowId: StateMachineRunId,
|
||||||
val permissionRequested: String,
|
val permissionRequested: String,
|
||||||
val permissionGranted: Boolean) : AuditEvent(), FlowAuditInfo
|
val permissionGranted: Boolean) : AuditEvent(), FlowAuditInfo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimal interface for recording audit information within the system. The AuditService is assumed to be available only
|
* Minimal interface for recording audit information within the system. The AuditService is assumed to be available only
|
||||||
* to trusted internal components via ServiceHubInternal.
|
* to trusted internal components via ServiceHubInternal.
|
||||||
|
@ -122,12 +122,13 @@ enum class CertChainPolicyType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class CertChainPolicyConfig(val role: String, private val policy: CertChainPolicyType, private val trustedAliases: Set<String>) {
|
data class CertChainPolicyConfig(val role: String, private val policy: CertChainPolicyType, private val trustedAliases: Set<String>) {
|
||||||
val certificateChainCheckPolicy: CertificateChainCheckPolicy get() {
|
val certificateChainCheckPolicy: CertificateChainCheckPolicy
|
||||||
return when (policy) {
|
get() {
|
||||||
CertChainPolicyType.Any -> CertificateChainCheckPolicy.Any
|
return when (policy) {
|
||||||
CertChainPolicyType.RootMustMatch -> CertificateChainCheckPolicy.RootMustMatch
|
CertChainPolicyType.Any -> CertificateChainCheckPolicy.Any
|
||||||
CertChainPolicyType.LeafMustMatch -> CertificateChainCheckPolicy.LeafMustMatch
|
CertChainPolicyType.RootMustMatch -> CertificateChainCheckPolicy.RootMustMatch
|
||||||
CertChainPolicyType.MustContainOneOf -> CertificateChainCheckPolicy.MustContainOneOf(trustedAliases)
|
CertChainPolicyType.LeafMustMatch -> CertificateChainCheckPolicy.LeafMustMatch
|
||||||
|
CertChainPolicyType.MustContainOneOf -> CertificateChainCheckPolicy.MustContainOneOf(trustedAliases)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal,
|
|||||||
// to wait in our code, rather than <code>Thread.sleep()</code> or other time-based pauses.
|
// to wait in our code, rather than <code>Thread.sleep()</code> or other time-based pauses.
|
||||||
@Suspendable
|
@Suspendable
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
// We specify full classpath on SettableFuture to differentiate it from the Quasar class of the same name
|
// We specify full classpath on SettableFuture to differentiate it from the Quasar class of the same name
|
||||||
fun awaitWithDeadline(clock: Clock, deadline: Instant, future: Future<*> = GuavaSettableFuture.create<Any>()): Boolean {
|
fun awaitWithDeadline(clock: Clock, deadline: Instant, future: Future<*> = GuavaSettableFuture.create<Any>()): Boolean {
|
||||||
var nanos: Long
|
var nanos: Long
|
||||||
do {
|
do {
|
||||||
@ -89,11 +89,11 @@ class NodeSchedulerService(private val services: ServiceHubInternal,
|
|||||||
try {
|
try {
|
||||||
// This will return when it times out, or when the clock mutates or when when the original future completes.
|
// This will return when it times out, or when the clock mutates or when when the original future completes.
|
||||||
originalFutureCompleted.get(nanos, TimeUnit.NANOSECONDS)
|
originalFutureCompleted.get(nanos, TimeUnit.NANOSECONDS)
|
||||||
} catch(e: ExecutionException) {
|
} catch (e: ExecutionException) {
|
||||||
// No need to take action as will fall out of the loop due to future.isDone
|
// No need to take action as will fall out of the loop due to future.isDone
|
||||||
} catch(e: CancellationException) {
|
} catch (e: CancellationException) {
|
||||||
// No need to take action as will fall out of the loop due to future.isDone
|
// No need to take action as will fall out of the loop due to future.isDone
|
||||||
} catch(e: TimeoutException) {
|
} catch (e: TimeoutException) {
|
||||||
// No need to take action as will fall out of the loop due to future.isDone
|
// No need to take action as will fall out of the loop due to future.isDone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal,
|
|||||||
var txId = it.output.txId ?: throw IllegalStateException("DB returned null SecureHash transactionId")
|
var txId = it.output.txId ?: throw IllegalStateException("DB returned null SecureHash transactionId")
|
||||||
var index = it.output.index ?: throw IllegalStateException("DB returned null SecureHash index")
|
var index = it.output.index ?: throw IllegalStateException("DB returned null SecureHash index")
|
||||||
Pair(StateRef(SecureHash.parse(txId), index),
|
Pair(StateRef(SecureHash.parse(txId), index),
|
||||||
ScheduledStateRef(StateRef(SecureHash.parse(txId), index), it.scheduledAt))
|
ScheduledStateRef(StateRef(SecureHash.parse(txId), index), it.scheduledAt))
|
||||||
},
|
},
|
||||||
toPersistentEntity = { key: StateRef, value: ScheduledStateRef ->
|
toPersistentEntity = { key: StateRef, value: ScheduledStateRef ->
|
||||||
PersistentScheduledState().apply {
|
PersistentScheduledState().apply {
|
||||||
@ -152,7 +152,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal,
|
|||||||
private class InnerState {
|
private class InnerState {
|
||||||
var scheduledStates = createMap()
|
var scheduledStates = createMap()
|
||||||
|
|
||||||
var scheduledStatesQueue: PriorityQueue<ScheduledStateRef> = PriorityQueue( { a, b -> a.scheduledAt.compareTo(b.scheduledAt) } )
|
var scheduledStatesQueue: PriorityQueue<ScheduledStateRef> = PriorityQueue({ a, b -> a.scheduledAt.compareTo(b.scheduledAt) })
|
||||||
|
|
||||||
var rescheduled: GuavaSettableFuture<Boolean>? = null
|
var rescheduled: GuavaSettableFuture<Boolean>? = null
|
||||||
}
|
}
|
||||||
@ -162,7 +162,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal,
|
|||||||
// We need the [StateMachineManager] to be constructed before this is called in case it schedules a flow.
|
// We need the [StateMachineManager] to be constructed before this is called in case it schedules a flow.
|
||||||
fun start() {
|
fun start() {
|
||||||
mutex.locked {
|
mutex.locked {
|
||||||
scheduledStatesQueue.addAll(scheduledStates.all().map { it.second } .toMutableList())
|
scheduledStatesQueue.addAll(scheduledStates.all().map { it.second }.toMutableList())
|
||||||
rescheduleWakeUp()
|
rescheduleWakeUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal,
|
|||||||
if (action.scheduledAt.isBefore(previousEarliest?.scheduledAt ?: Instant.MAX)) {
|
if (action.scheduledAt.isBefore(previousEarliest?.scheduledAt ?: Instant.MAX)) {
|
||||||
// We are earliest
|
// We are earliest
|
||||||
rescheduleWakeUp()
|
rescheduleWakeUp()
|
||||||
} else if(previousEarliest?.ref == action.ref && previousEarliest.scheduledAt != action.scheduledAt) {
|
} else if (previousEarliest?.ref == action.ref && previousEarliest.scheduledAt != action.scheduledAt) {
|
||||||
// We were earliest but might not be any more
|
// We were earliest but might not be any more
|
||||||
rescheduleWakeUp()
|
rescheduleWakeUp()
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
|
|||||||
constructor(wellKnownIdentities: Iterable<PartyAndCertificate> = emptySet(),
|
constructor(wellKnownIdentities: Iterable<PartyAndCertificate> = emptySet(),
|
||||||
confidentialIdentities: Iterable<PartyAndCertificate> = emptySet(),
|
confidentialIdentities: Iterable<PartyAndCertificate> = emptySet(),
|
||||||
trustRoot: X509CertificateHolder) : this(wellKnownIdentities, confidentialIdentities, trustRoot.cert)
|
trustRoot: X509CertificateHolder) : this(wellKnownIdentities, confidentialIdentities, trustRoot.cert)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = loggerFor<InMemoryIdentityService>()
|
private val log = loggerFor<InMemoryIdentityService>()
|
||||||
}
|
}
|
||||||
@ -45,7 +46,7 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
|
|||||||
init {
|
init {
|
||||||
val caCertificatesWithRoot: Set<X509Certificate> = caCertificates.toSet() + trustRoot
|
val caCertificatesWithRoot: Set<X509Certificate> = caCertificates.toSet() + trustRoot
|
||||||
caCertStore = CertStore.getInstance("Collection", CollectionCertStoreParameters(caCertificatesWithRoot))
|
caCertStore = CertStore.getInstance("Collection", CollectionCertStoreParameters(caCertificatesWithRoot))
|
||||||
keyToParties.putAll(identities.associateBy { it.owningKey } )
|
keyToParties.putAll(identities.associateBy { it.owningKey })
|
||||||
principalToParties.putAll(identities.associateBy { it.name })
|
principalToParties.putAll(identities.associateBy { it.name })
|
||||||
confidentialIdentities.forEach { identity ->
|
confidentialIdentities.forEach { identity ->
|
||||||
principalToParties.computeIfAbsent(identity.name) { identity }
|
principalToParties.computeIfAbsent(identity.name) { identity }
|
||||||
@ -94,6 +95,7 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun wellKnownPartyFromAnonymous(partyRef: PartyAndReference) = wellKnownPartyFromAnonymous(partyRef.party)
|
override fun wellKnownPartyFromAnonymous(partyRef: PartyAndReference) = wellKnownPartyFromAnonymous(partyRef.party)
|
||||||
override fun requireWellKnownPartyFromAnonymous(party: AbstractParty): Party {
|
override fun requireWellKnownPartyFromAnonymous(party: AbstractParty): Party {
|
||||||
return wellKnownPartyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}")
|
return wellKnownPartyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}")
|
||||||
|
@ -48,8 +48,10 @@ class PersistentKeyManagementService(val identityService: IdentityService,
|
|||||||
fun createKeyMap(): AppendOnlyPersistentMap<PublicKey, PrivateKey, PersistentKey, String> {
|
fun createKeyMap(): AppendOnlyPersistentMap<PublicKey, PrivateKey, PersistentKey, String> {
|
||||||
return AppendOnlyPersistentMap(
|
return AppendOnlyPersistentMap(
|
||||||
toPersistentEntityKey = { it.toBase58String() },
|
toPersistentEntityKey = { it.toBase58String() },
|
||||||
fromPersistentEntity = { Pair(parsePublicKeyBase58(it.publicKey),
|
fromPersistentEntity = {
|
||||||
it.privateKey.deserialize<PrivateKey>(context = SerializationDefaults.STORAGE_CONTEXT)) },
|
Pair(parsePublicKeyBase58(it.publicKey),
|
||||||
|
it.privateKey.deserialize<PrivateKey>(context = SerializationDefaults.STORAGE_CONTEXT))
|
||||||
|
},
|
||||||
toPersistentEntity = { key: PublicKey, value: PrivateKey ->
|
toPersistentEntity = { key: PublicKey, value: PrivateKey ->
|
||||||
PersistentKey().apply {
|
PersistentKey().apply {
|
||||||
publicKey = key.toBase58String()
|
publicKey = key.toBase58String()
|
||||||
@ -81,7 +83,7 @@ class PersistentKeyManagementService(val identityService: IdentityService,
|
|||||||
override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate =
|
override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate =
|
||||||
freshCertificate(identityService, freshKey(), identity, getSigner(identity.owningKey), revocationEnabled)
|
freshCertificate(identityService, freshKey(), identity, getSigner(identity.owningKey), revocationEnabled)
|
||||||
|
|
||||||
private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey))
|
private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey))
|
||||||
|
|
||||||
//It looks for the PublicKey in the (potentially) CompositeKey that is ours, and then returns the associated PrivateKey to use in signing
|
//It looks for the PublicKey in the (potentially) CompositeKey that is ours, and then returns the associated PrivateKey to use in signing
|
||||||
private fun getSigningKeyPair(publicKey: PublicKey): KeyPair {
|
private fun getSigningKeyPair(publicKey: PublicKey): KeyPair {
|
||||||
|
@ -97,7 +97,8 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = loggerFor<ArtemisMessagingServer>()
|
private val log = loggerFor<ArtemisMessagingServer>()
|
||||||
/** 10 MiB maximum allowed file size for attachments, including message headers. TODO: acquire this value from Network Map when supported. */
|
/** 10 MiB maximum allowed file size for attachments, including message headers. TODO: acquire this value from Network Map when supported. */
|
||||||
@JvmStatic val MAX_FILE_SIZE = 10485760
|
@JvmStatic
|
||||||
|
val MAX_FILE_SIZE = 10485760
|
||||||
|
|
||||||
val ipDetectRequestProperty = "ip-request-id"
|
val ipDetectRequestProperty = "ip-request-id"
|
||||||
val ipDetectResponseProperty = "ip-address"
|
val ipDetectResponseProperty = "ip-address"
|
||||||
|
@ -117,10 +117,12 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
|||||||
fun createMessageToRedeliver(): PersistentMap<Long, Pair<Message, MessageRecipients>, RetryMessage, Long> {
|
fun createMessageToRedeliver(): PersistentMap<Long, Pair<Message, MessageRecipients>, RetryMessage, Long> {
|
||||||
return PersistentMap(
|
return PersistentMap(
|
||||||
toPersistentEntityKey = { it },
|
toPersistentEntityKey = { it },
|
||||||
fromPersistentEntity = { Pair(it.key,
|
fromPersistentEntity = {
|
||||||
Pair(it.message.deserialize( context = SerializationDefaults.STORAGE_CONTEXT),
|
Pair(it.key,
|
||||||
it.recipients.deserialize( context = SerializationDefaults.STORAGE_CONTEXT))
|
Pair(it.message.deserialize(context = SerializationDefaults.STORAGE_CONTEXT),
|
||||||
) },
|
it.recipients.deserialize(context = SerializationDefaults.STORAGE_CONTEXT))
|
||||||
|
)
|
||||||
|
},
|
||||||
toPersistentEntity = { _key: Long, (_message: Message, _recipient: MessageRecipients): Pair<Message, MessageRecipients> ->
|
toPersistentEntity = { _key: Long, (_message: Message, _recipient: MessageRecipients): Pair<Message, MessageRecipients> ->
|
||||||
RetryMessage().apply {
|
RetryMessage().apply {
|
||||||
key = _key
|
key = _key
|
||||||
@ -241,7 +243,7 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
|||||||
log.info("Network map is complete, so removing filter from P2P consumer.")
|
log.info("Network map is complete, so removing filter from P2P consumer.")
|
||||||
try {
|
try {
|
||||||
p2pConsumer!!.close()
|
p2pConsumer!!.close()
|
||||||
} catch(e: ActiveMQObjectClosedException) {
|
} catch (e: ActiveMQObjectClosedException) {
|
||||||
// Ignore it: this can happen if the server has gone away before we do.
|
// Ignore it: this can happen if the server has gone away before we do.
|
||||||
}
|
}
|
||||||
p2pConsumer = makeP2PConsumer(session, false)
|
p2pConsumer = makeP2PConsumer(session, false)
|
||||||
@ -283,8 +285,8 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun resumeMessageRedelivery() {
|
private fun resumeMessageRedelivery() {
|
||||||
messagesToRedeliver.forEach {
|
messagesToRedeliver.forEach { retryId, (message, target) ->
|
||||||
retryId, (message, target) -> send(message, target, retryId)
|
send(message, target, retryId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +303,7 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
|||||||
// It's safe to call into receive simultaneous with other threads calling send on a producer.
|
// It's safe to call into receive simultaneous with other threads calling send on a producer.
|
||||||
val artemisMessage: ClientMessage = try {
|
val artemisMessage: ClientMessage = try {
|
||||||
consumer.receive()
|
consumer.receive()
|
||||||
} catch(e: ActiveMQObjectClosedException) {
|
} catch (e: ActiveMQObjectClosedException) {
|
||||||
null
|
null
|
||||||
} ?: return false
|
} ?: return false
|
||||||
|
|
||||||
@ -433,7 +435,7 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error("Caught exception whilst executing message handler for ${msg.topicSession}", e)
|
log.error("Caught exception whilst executing message handler for ${msg.topicSession}", e)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -454,7 +456,7 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
|||||||
val c = p2pConsumer ?: throw IllegalStateException("stop can't be called twice")
|
val c = p2pConsumer ?: throw IllegalStateException("stop can't be called twice")
|
||||||
try {
|
try {
|
||||||
c.close()
|
c.close()
|
||||||
} catch(e: ActiveMQObjectClosedException) {
|
} catch (e: ActiveMQObjectClosedException) {
|
||||||
// Ignore it: this can happen if the server has gone away before we do.
|
// Ignore it: this can happen if the server has gone away before we do.
|
||||||
}
|
}
|
||||||
p2pConsumer = null
|
p2pConsumer = null
|
||||||
|
@ -86,6 +86,7 @@ class RPCServer(
|
|||||||
private companion object {
|
private companion object {
|
||||||
val log = loggerFor<RPCServer>()
|
val log = loggerFor<RPCServer>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class State {
|
private enum class State {
|
||||||
UNSTARTED,
|
UNSTARTED,
|
||||||
STARTED,
|
STARTED,
|
||||||
@ -350,6 +351,7 @@ class RPCServer(
|
|||||||
|
|
||||||
// TODO remove this User once webserver doesn't need it
|
// TODO remove this User once webserver doesn't need it
|
||||||
private val nodeUser = User(NODE_USER, NODE_USER, setOf())
|
private val nodeUser = User(NODE_USER, NODE_USER, setOf())
|
||||||
|
|
||||||
private fun getUser(message: ClientMessage): User {
|
private fun getUser(message: ClientMessage): User {
|
||||||
val validatedUser = message.getStringProperty(Message.HDR_VALIDATED_USER) ?: throw IllegalArgumentException("Missing validated user from the Artemis message")
|
val validatedUser = message.getStringProperty(Message.HDR_VALIDATED_USER) ?: throw IllegalArgumentException("Missing validated user from the Artemis message")
|
||||||
val rpcUser = userService.getUser(validatedUser)
|
val rpcUser = userService.getUser(validatedUser)
|
||||||
@ -365,6 +367,7 @@ class RPCServer(
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
internal val CURRENT_RPC_CONTEXT: ThreadLocal<RpcContext> = ThreadLocal()
|
internal val CURRENT_RPC_CONTEXT: ThreadLocal<RpcContext> = ThreadLocal()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a context specific to the current RPC call. Note that trying to call this function outside of an RPC will
|
* Returns a context specific to the current RPC call. Note that trying to call this function outside of an RPC will
|
||||||
* throw. If you'd like to use the context outside of the call (e.g. in another thread) then pass the returned reference
|
* throw. If you'd like to use the context outside of the call (e.g. in another thread) then pass the returned reference
|
||||||
@ -422,6 +425,7 @@ class ObservableContext(
|
|||||||
|
|
||||||
object RpcServerObservableSerializer : Serializer<Observable<*>>() {
|
object RpcServerObservableSerializer : Serializer<Observable<*>>() {
|
||||||
private object RpcObservableContextKey
|
private object RpcObservableContextKey
|
||||||
|
|
||||||
private val log = loggerFor<RpcServerObservableSerializer>()
|
private val log = loggerFor<RpcServerObservableSerializer>()
|
||||||
|
|
||||||
fun createContext(observableContext: ObservableContext): SerializationContext {
|
fun createContext(observableContext: ObservableContext): SerializationContext {
|
||||||
@ -448,9 +452,11 @@ object RpcServerObservableSerializer : Serializer<Observable<*>>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(exception: Throwable) {
|
override fun onError(exception: Throwable) {
|
||||||
log.error("onError called in materialize()d RPC Observable", exception)
|
log.error("onError called in materialize()d RPC Observable", exception)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCompleted() {
|
override fun onCompleted() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ class NodeInfoWatcher(private val nodePath: Path,
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processFile(file: Path) : NodeInfo? {
|
private fun processFile(file: Path): NodeInfo? {
|
||||||
try {
|
try {
|
||||||
logger.info("Reading NodeInfo from file: $file")
|
logger.info("Reading NodeInfo from file: $file")
|
||||||
val signedData = file.readAll().deserialize<SignedData<NodeInfo>>()
|
val signedData = file.readAll().deserialize<SignedData<NodeInfo>>()
|
||||||
|
@ -118,6 +118,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
|
|||||||
override fun getNodesByLegalName(name: CordaX500Name): List<NodeInfo> = serviceHub.database.transaction { queryByLegalName(name) }
|
override fun getNodesByLegalName(name: CordaX500Name): List<NodeInfo> = serviceHub.database.transaction { queryByLegalName(name) }
|
||||||
override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo> =
|
override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo> =
|
||||||
serviceHub.database.transaction { queryByIdentityKey(identityKey) }
|
serviceHub.database.transaction { queryByIdentityKey(identityKey) }
|
||||||
|
|
||||||
override fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? {
|
override fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? {
|
||||||
val wellKnownParty = serviceHub.identityService.wellKnownPartyFromAnonymous(party)
|
val wellKnownParty = serviceHub.identityService.wellKnownPartyFromAnonymous(party)
|
||||||
return wellKnownParty?.let {
|
return wellKnownParty?.let {
|
||||||
|
@ -32,7 +32,7 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic
|
|||||||
if (dbData != null) {
|
if (dbData != null) {
|
||||||
val party = identityService.wellKnownPartyFromX500Name(CordaX500Name.parse(dbData))
|
val party = identityService.wellKnownPartyFromX500Name(CordaX500Name.parse(dbData))
|
||||||
if (party != null) return party
|
if (party != null) return party
|
||||||
log.warn ("Identity service unable to resolve X500name: $dbData")
|
log.warn("Identity service unable to resolve X500name: $dbData")
|
||||||
}
|
}
|
||||||
return null // non resolvable anonymous parties are stored as nulls
|
return null // non resolvable anonymous parties are stored as nulls
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,10 @@ class DBTransactionStorage : WritableTransactionStorage, SingletonSerializeAsTok
|
|||||||
fun createTransactionsMap(): AppendOnlyPersistentMap<SecureHash, SignedTransaction, DBTransaction, String> {
|
fun createTransactionsMap(): AppendOnlyPersistentMap<SecureHash, SignedTransaction, DBTransaction, String> {
|
||||||
return AppendOnlyPersistentMap(
|
return AppendOnlyPersistentMap(
|
||||||
toPersistentEntityKey = { it.toString() },
|
toPersistentEntityKey = { it.toString() },
|
||||||
fromPersistentEntity = { Pair(SecureHash.parse(it.txId),
|
fromPersistentEntity = {
|
||||||
it.transaction.deserialize<SignedTransaction>( context = SerializationDefaults.STORAGE_CONTEXT)) },
|
Pair(SecureHash.parse(it.txId),
|
||||||
|
it.transaction.deserialize<SignedTransaction>(context = SerializationDefaults.STORAGE_CONTEXT))
|
||||||
|
},
|
||||||
toPersistentEntity = { key: SecureHash, value: SignedTransaction ->
|
toPersistentEntity = { key: SecureHash, value: SignedTransaction ->
|
||||||
DBTransaction().apply {
|
DBTransaction().apply {
|
||||||
txId = key.toString()
|
txId = key.toString()
|
||||||
@ -46,9 +48,9 @@ class DBTransactionStorage : WritableTransactionStorage, SingletonSerializeAsTok
|
|||||||
private val txStorage = createTransactionsMap()
|
private val txStorage = createTransactionsMap()
|
||||||
|
|
||||||
override fun addTransaction(transaction: SignedTransaction): Boolean =
|
override fun addTransaction(transaction: SignedTransaction): Boolean =
|
||||||
txStorage.addWithDuplicatesAllowed(transaction.id, transaction).apply {
|
txStorage.addWithDuplicatesAllowed(transaction.id, transaction).apply {
|
||||||
updatesPublisher.bufferUntilDatabaseCommit().onNext(transaction)
|
updatesPublisher.bufferUntilDatabaseCommit().onNext(transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTransaction(id: SecureHash): SignedTransaction? = txStorage[id]
|
override fun getTransaction(id: SecureHash): SignedTransaction? = txStorage[id]
|
||||||
|
|
||||||
@ -59,5 +61,6 @@ class DBTransactionStorage : WritableTransactionStorage, SingletonSerializeAsTok
|
|||||||
DataFeed(txStorage.allPersisted().map { it.second }.toList(), updatesPublisher.bufferUntilSubscribed().wrapWithDatabaseTransaction())
|
DataFeed(txStorage.allPersisted().map { it.second }.toList(), updatesPublisher.bufferUntilSubscribed().wrapWithDatabaseTransaction())
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
val transactions: Iterable<SignedTransaction> get() = txStorage.allPersisted().map { it.second }.toList()
|
val transactions: Iterable<SignedTransaction>
|
||||||
|
get() = txStorage.allPersisted().map { it.second }.toList()
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab
|
|||||||
// TODO: make this a guava cache or similar to limit ability for this to grow forever.
|
// TODO: make this a guava cache or similar to limit ability for this to grow forever.
|
||||||
private val sessionFactories = ConcurrentHashMap<Set<MappedSchema>, SessionFactory>()
|
private val sessionFactories = ConcurrentHashMap<Set<MappedSchema>, SessionFactory>()
|
||||||
|
|
||||||
private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel") ?:"")
|
private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel") ?: "")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
logger.info("Init HibernateConfiguration for schemas: ${schemaService.schemaOptions.keys}")
|
logger.info("Init HibernateConfiguration for schemas: ${schemaService.schemaOptions.keys}")
|
||||||
@ -61,7 +61,7 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab
|
|||||||
// necessarily remain and would likely be replaced by something like Liquibase. For now it is very convenient though.
|
// necessarily remain and would likely be replaced by something like Liquibase. For now it is very convenient though.
|
||||||
// TODO: replace auto schema generation as it isn't intended for production use, according to Hibernate docs.
|
// TODO: replace auto schema generation as it isn't intended for production use, according to Hibernate docs.
|
||||||
val config = Configuration(metadataSources).setProperty("hibernate.connection.provider_class", NodeDatabaseConnectionProvider::class.java.name)
|
val config = Configuration(metadataSources).setProperty("hibernate.connection.provider_class", NodeDatabaseConnectionProvider::class.java.name)
|
||||||
.setProperty("hibernate.hbm2ddl.auto", if (databaseProperties.getProperty("initDatabase","true") == "true") "update" else "validate")
|
.setProperty("hibernate.hbm2ddl.auto", if (databaseProperties.getProperty("initDatabase", "true") == "true") "update" else "validate")
|
||||||
.setProperty("hibernate.format_sql", "true")
|
.setProperty("hibernate.format_sql", "true")
|
||||||
.setProperty("hibernate.connection.isolation", transactionIsolationLevel.toString())
|
.setProperty("hibernate.connection.isolation", transactionIsolationLevel.toString())
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab
|
|||||||
schema.mappedTypes.forEach { config.addAnnotatedClass(it) }
|
schema.mappedTypes.forEach { config.addAnnotatedClass(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessionFactory = buildSessionFactory(config, metadataSources, databaseProperties.getProperty("serverNameTablePrefix",""))
|
val sessionFactory = buildSessionFactory(config, metadataSources, databaseProperties.getProperty("serverNameTablePrefix", ""))
|
||||||
logger.info("Created session factory for schemas: $schemas")
|
logger.info("Created session factory for schemas: $schemas")
|
||||||
return sessionFactory
|
return sessionFactory
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ class InMemoryStateMachineRecordedTransactionMappingStorage : StateMachineRecord
|
|||||||
val stateMachineTransactionMap = HashMap<StateMachineRunId, HashSet<SecureHash>>()
|
val stateMachineTransactionMap = HashMap<StateMachineRunId, HashSet<SecureHash>>()
|
||||||
val updates = PublishSubject.create<StateMachineTransactionMapping>()!!
|
val updates = PublishSubject.create<StateMachineTransactionMapping>()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mutex = ThreadBox(InnerState())
|
private val mutex = ThreadBox(InnerState())
|
||||||
|
|
||||||
override fun addMapping(stateMachineRunId: StateMachineRunId, transactionId: SecureHash) {
|
override fun addMapping(stateMachineRunId: StateMachineRunId, transactionId: SecureHash) {
|
||||||
|
@ -29,7 +29,7 @@ class NodeAttachmentService(metrics: MetricRegistry) : AttachmentStorage, Single
|
|||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "${NODE_DATABASE_PREFIX}attachments",
|
@Table(name = "${NODE_DATABASE_PREFIX}attachments",
|
||||||
indexes = arrayOf(Index(name = "att_id_idx", columnList = "att_id")))
|
indexes = arrayOf(Index(name = "att_id_idx", columnList = "att_id")))
|
||||||
class DBAttachment(
|
class DBAttachment(
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "att_id", length = 65535)
|
@Column(name = "att_id", length = 65535)
|
||||||
@ -69,7 +69,8 @@ class NodeAttachmentService(metrics: MetricRegistry) : AttachmentStorage, Single
|
|||||||
* around inside it, we haven't read the whole file, so we can't check the hash. But when copying it over the network
|
* around inside it, we haven't read the whole file, so we can't check the hash. But when copying it over the network
|
||||||
* this will provide an additional safety check against user error.
|
* this will provide an additional safety check against user error.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting @CordaSerializable
|
@VisibleForTesting
|
||||||
|
@CordaSerializable
|
||||||
class HashCheckingStream(val expected: SecureHash.SHA256,
|
class HashCheckingStream(val expected: SecureHash.SHA256,
|
||||||
val expectedSize: Int,
|
val expectedSize: Int,
|
||||||
input: InputStream,
|
input: InputStream,
|
||||||
@ -110,16 +111,17 @@ class NodeAttachmentService(metrics: MetricRegistry) : AttachmentStorage, Single
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var _hash: HashCode? = null // Backing field for hash property
|
private var _hash: HashCode? = null // Backing field for hash property
|
||||||
private val hash: HashCode get() {
|
private val hash: HashCode
|
||||||
var h = _hash
|
get() {
|
||||||
return if (h == null) {
|
var h = _hash
|
||||||
h = stream.hash()
|
return if (h == null) {
|
||||||
_hash = h
|
h = stream.hash()
|
||||||
h
|
_hash = h
|
||||||
} else {
|
h
|
||||||
h
|
} else {
|
||||||
|
h
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AttachmentImpl(override val id: SecureHash, dataLoader: () -> ByteArray, private val checkOnLoad: Boolean) : AbstractAttachment(dataLoader), SerializeAsToken {
|
private class AttachmentImpl(override val id: SecureHash, dataLoader: () -> ByteArray, private val checkOnLoad: Boolean) : AbstractAttachment(dataLoader), SerializeAsToken {
|
||||||
|
@ -57,18 +57,18 @@ class NodeSchemaService(customSchemas: Set<MappedSchema> = emptySet()) : SchemaS
|
|||||||
PersistentIdentityService.PersistentIdentity::class.java,
|
PersistentIdentityService.PersistentIdentity::class.java,
|
||||||
PersistentIdentityService.PersistentIdentityNames::class.java,
|
PersistentIdentityService.PersistentIdentityNames::class.java,
|
||||||
ContractUpgradeServiceImpl.DBContractUpgrade::class.java
|
ContractUpgradeServiceImpl.DBContractUpgrade::class.java
|
||||||
))
|
))
|
||||||
|
|
||||||
// Required schemas are those used by internal Corda services
|
// Required schemas are those used by internal Corda services
|
||||||
// For example, cash is used by the vault for coin selection (but will be extracted as a standalone CorDapp in future)
|
// For example, cash is used by the vault for coin selection (but will be extracted as a standalone CorDapp in future)
|
||||||
private val requiredSchemas: Map<MappedSchema, SchemaService.SchemaOptions> =
|
private val requiredSchemas: Map<MappedSchema, SchemaService.SchemaOptions> =
|
||||||
mapOf(Pair(CommonSchemaV1, SchemaService.SchemaOptions()),
|
mapOf(Pair(CommonSchemaV1, SchemaService.SchemaOptions()),
|
||||||
Pair(VaultSchemaV1, SchemaService.SchemaOptions()),
|
Pair(VaultSchemaV1, SchemaService.SchemaOptions()),
|
||||||
Pair(NodeInfoSchemaV1, SchemaService.SchemaOptions()),
|
Pair(NodeInfoSchemaV1, SchemaService.SchemaOptions()),
|
||||||
Pair(NodeServicesV1, SchemaService.SchemaOptions()))
|
Pair(NodeServicesV1, SchemaService.SchemaOptions()))
|
||||||
|
|
||||||
override var schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = requiredSchemas.plus(customSchemas.map {
|
override var schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = requiredSchemas.plus(customSchemas.map { mappedSchema ->
|
||||||
mappedSchema -> Pair(mappedSchema, SchemaService.SchemaOptions())
|
Pair(mappedSchema, SchemaService.SchemaOptions())
|
||||||
})
|
})
|
||||||
|
|
||||||
// Currently returns all schemas supported by the state, with no filtering or enrichment.
|
// Currently returns all schemas supported by the state, with no filtering or enrichment.
|
||||||
@ -94,8 +94,8 @@ class NodeSchemaService(customSchemas: Set<MappedSchema> = emptySet()) : SchemaS
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun registerCustomSchemas(_customSchemas: Set<MappedSchema>) {
|
override fun registerCustomSchemas(_customSchemas: Set<MappedSchema>) {
|
||||||
schemaOptions = schemaOptions.plus(_customSchemas.map {
|
schemaOptions = schemaOptions.plus(_customSchemas.map { mappedSchema ->
|
||||||
mappedSchema -> Pair(mappedSchema, SchemaService.SchemaOptions())
|
Pair(mappedSchema, SchemaService.SchemaOptions())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
|||||||
val logic: FlowLogic<R>,
|
val logic: FlowLogic<R>,
|
||||||
scheduler: FiberScheduler,
|
scheduler: FiberScheduler,
|
||||||
override val flowInitiator: FlowInitiator,
|
override val flowInitiator: FlowInitiator,
|
||||||
// Store the Party rather than the full cert path with PartyAndCertificate
|
// Store the Party rather than the full cert path with PartyAndCertificate
|
||||||
val ourIdentity: Party) : Fiber<Unit>(id.toString(), scheduler), FlowStateMachine<R> {
|
val ourIdentity: Party) : Fiber<Unit>(id.toString(), scheduler), FlowStateMachine<R> {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -482,7 +482,7 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
|||||||
private fun suspend(ioRequest: FlowIORequest) {
|
private fun suspend(ioRequest: FlowIORequest) {
|
||||||
// We have to pass the thread local database transaction across via a transient field as the fiber park
|
// We have to pass the thread local database transaction across via a transient field as the fiber park
|
||||||
// swaps them out.
|
// swaps them out.
|
||||||
txTrampoline = DatabaseTransactionManager.setThreadLocalTx(null)
|
txTrampoline = DatabaseTransactionManager.setThreadLocalTx(null)
|
||||||
if (ioRequest is WaitingRequest)
|
if (ioRequest is WaitingRequest)
|
||||||
waitingForResponse = ioRequest
|
waitingForResponse = ioRequest
|
||||||
|
|
||||||
@ -541,28 +541,30 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val Class<out FlowLogic<*>>.flowVersionAndInitiatingClass: Pair<Int, Class<out FlowLogic<*>>> get() {
|
val Class<out FlowLogic<*>>.flowVersionAndInitiatingClass: Pair<Int, Class<out FlowLogic<*>>>
|
||||||
var current: Class<*> = this
|
get() {
|
||||||
var found: Pair<Int, Class<out FlowLogic<*>>>? = null
|
var current: Class<*> = this
|
||||||
while (true) {
|
var found: Pair<Int, Class<out FlowLogic<*>>>? = null
|
||||||
val annotation = current.getDeclaredAnnotation(InitiatingFlow::class.java)
|
while (true) {
|
||||||
if (annotation != null) {
|
val annotation = current.getDeclaredAnnotation(InitiatingFlow::class.java)
|
||||||
if (found != null) throw IllegalArgumentException("${InitiatingFlow::class.java.name} can only be annotated once")
|
if (annotation != null) {
|
||||||
require(annotation.version > 0) { "Flow versions have to be greater or equal to 1" }
|
if (found != null) throw IllegalArgumentException("${InitiatingFlow::class.java.name} can only be annotated once")
|
||||||
found = annotation.version to uncheckedCast(current)
|
require(annotation.version > 0) { "Flow versions have to be greater or equal to 1" }
|
||||||
|
found = annotation.version to uncheckedCast(current)
|
||||||
|
}
|
||||||
|
current = current.superclass
|
||||||
|
?: return found
|
||||||
|
?: throw IllegalArgumentException("$name, as a flow that initiates other flows, must be annotated with " +
|
||||||
|
"${InitiatingFlow::class.java.name}. See https://docs.corda.net/api-flows.html#flowlogic-annotations.")
|
||||||
}
|
}
|
||||||
current = current.superclass
|
|
||||||
?: return found
|
|
||||||
?: throw IllegalArgumentException("$name, as a flow that initiates other flows, must be annotated with " +
|
|
||||||
"${InitiatingFlow::class.java.name}. See https://docs.corda.net/api-flows.html#flowlogic-annotations.")
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val Class<out FlowLogic<*>>.appName: String get() {
|
val Class<out FlowLogic<*>>.appName: String
|
||||||
val jarFile = Paths.get(protectionDomain.codeSource.location.toURI())
|
get() {
|
||||||
return if (jarFile.isRegularFile() && jarFile.toString().endsWith(".jar")) {
|
val jarFile = Paths.get(protectionDomain.codeSource.location.toURI())
|
||||||
jarFile.fileName.toString().removeSuffix(".jar")
|
return if (jarFile.isRegularFile() && jarFile.toString().endsWith(".jar")) {
|
||||||
} else {
|
jarFile.fileName.toString().removeSuffix(".jar")
|
||||||
"<unknown>"
|
} else {
|
||||||
|
"<unknown>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -397,7 +397,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val (ourFlowVersion, appName) = when (initiatedFlowFactory) {
|
val (ourFlowVersion, appName) = when (initiatedFlowFactory) {
|
||||||
// The flow version for the core flows is the platform version
|
// The flow version for the core flows is the platform version
|
||||||
is InitiatedFlowFactory.Core -> serviceHub.myInfo.platformVersion to "corda"
|
is InitiatedFlowFactory.Core -> serviceHub.myInfo.platformVersion to "corda"
|
||||||
is InitiatedFlowFactory.CorDapp -> initiatedFlowFactory.flowVersion to initiatedFlowFactory.appName
|
is InitiatedFlowFactory.CorDapp -> initiatedFlowFactory.flowVersion to initiatedFlowFactory.appName
|
||||||
}
|
}
|
||||||
@ -631,8 +631,8 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
|
|||||||
val serialized = try {
|
val serialized = try {
|
||||||
message.serialize()
|
message.serialize()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
when(e) {
|
when (e) {
|
||||||
// Handling Kryo and AMQP serialization problems. Unfortunately the two exception types do not share much of a common exception interface.
|
// Handling Kryo and AMQP serialization problems. Unfortunately the two exception types do not share much of a common exception interface.
|
||||||
is KryoException,
|
is KryoException,
|
||||||
is NotSerializableException -> {
|
is NotSerializableException -> {
|
||||||
if (message !is ErrorSessionEnd || message.errorResponse == null) throw e
|
if (message !is ErrorSessionEnd || message.errorResponse == null) throw e
|
||||||
|
@ -112,7 +112,7 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal,
|
|||||||
name = CordaX500Name.parse(it.party.name),
|
name = CordaX500Name.parse(it.party.name),
|
||||||
owningKey = parsePublicKeyBase58(it.party.owningKey))))
|
owningKey = parsePublicKeyBase58(it.party.owningKey))))
|
||||||
},
|
},
|
||||||
toPersistentEntity = { (txHash, index) : StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx ->
|
toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx ->
|
||||||
PersistedCommittedState(
|
PersistedCommittedState(
|
||||||
id = PersistentStateRef(txHash.toString(), index),
|
id = PersistentStateRef(txHash.toString(), index),
|
||||||
consumingTxHash = id.toString(),
|
consumingTxHash = id.toString(),
|
||||||
|
@ -24,7 +24,7 @@ import javax.persistence.*
|
|||||||
class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsToken() {
|
class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsToken() {
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
open class PersistentUniqueness (
|
open class PersistentUniqueness(
|
||||||
@EmbeddedId
|
@EmbeddedId
|
||||||
var id: PersistentStateRef = PersistentStateRef(),
|
var id: PersistentStateRef = PersistentStateRef(),
|
||||||
|
|
||||||
@ -45,11 +45,11 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok
|
|||||||
|
|
||||||
@Column(name = "requesting_party_key", length = 255)
|
@Column(name = "requesting_party_key", length = 255)
|
||||||
var owningKey: String = ""
|
var owningKey: String = ""
|
||||||
): Serializable
|
) : Serializable
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}notary_commit_log")
|
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}notary_commit_log")
|
||||||
class PersistentNotaryCommit(id: PersistentStateRef, consumingTxHash: String, consumingIndex: Int, party: PersistentParty):
|
class PersistentNotaryCommit(id: PersistentStateRef, consumingTxHash: String, consumingIndex: Int, party: PersistentParty) :
|
||||||
PersistentUniqueness(id, consumingTxHash, consumingIndex, party)
|
PersistentUniqueness(id, consumingTxHash, consumingIndex, party)
|
||||||
|
|
||||||
|
|
||||||
@ -77,37 +77,37 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok
|
|||||||
name = CordaX500Name.parse(it.party.name),
|
name = CordaX500Name.parse(it.party.name),
|
||||||
owningKey = parsePublicKeyBase58(it.party.owningKey))))
|
owningKey = parsePublicKeyBase58(it.party.owningKey))))
|
||||||
},
|
},
|
||||||
toPersistentEntity = { (txHash, index) : StateRef, (id, inputIndex, requestingParty) : UniquenessProvider.ConsumingTx ->
|
toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx ->
|
||||||
PersistentNotaryCommit(
|
PersistentNotaryCommit(
|
||||||
id = PersistentStateRef(txHash.toString(), index),
|
id = PersistentStateRef(txHash.toString(), index),
|
||||||
consumingTxHash = id.toString(),
|
consumingTxHash = id.toString(),
|
||||||
consumingIndex = inputIndex,
|
consumingIndex = inputIndex,
|
||||||
party = PersistentParty(requestingParty.name.toString(), requestingParty.owningKey.toBase58String())
|
party = PersistentParty(requestingParty.name.toString(), requestingParty.owningKey.toBase58String())
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
persistentEntityClass = PersistentNotaryCommit::class.java
|
persistentEntityClass = PersistentNotaryCommit::class.java
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party) {
|
override fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party) {
|
||||||
|
|
||||||
val conflict = mutex.locked {
|
val conflict = mutex.locked {
|
||||||
val conflictingStates = LinkedHashMap<StateRef, UniquenessProvider.ConsumingTx>()
|
val conflictingStates = LinkedHashMap<StateRef, UniquenessProvider.ConsumingTx>()
|
||||||
for (inputState in states) {
|
for (inputState in states) {
|
||||||
val consumingTx = committedStates.get(inputState)
|
val consumingTx = committedStates.get(inputState)
|
||||||
if (consumingTx != null) conflictingStates[inputState] = consumingTx
|
if (consumingTx != null) conflictingStates[inputState] = consumingTx
|
||||||
}
|
}
|
||||||
if (conflictingStates.isNotEmpty()) {
|
if (conflictingStates.isNotEmpty()) {
|
||||||
log.debug("Failure, input states already committed: ${conflictingStates.keys}")
|
log.debug("Failure, input states already committed: ${conflictingStates.keys}")
|
||||||
UniquenessProvider.Conflict(conflictingStates)
|
UniquenessProvider.Conflict(conflictingStates)
|
||||||
} else {
|
} else {
|
||||||
states.forEachIndexed { i, stateRef ->
|
states.forEachIndexed { i, stateRef ->
|
||||||
committedStates[stateRef] = UniquenessProvider.ConsumingTx(txId, i, callerIdentity)
|
committedStates[stateRef] = UniquenessProvider.ConsumingTx(txId, i, callerIdentity)
|
||||||
}
|
|
||||||
log.debug("Successfully committed all input states: $states")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
log.debug("Successfully committed all input states: $states")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (conflict != null) throw UniquenessException(conflict)
|
if (conflict != null) throw UniquenessException(conflict)
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,8 @@ class RaftUniquenessProvider(private val services: ServiceHubInternal, private v
|
|||||||
fun start() {
|
fun start() {
|
||||||
log.info("Creating Copycat server, log stored in: ${storagePath.toFile()}")
|
log.info("Creating Copycat server, log stored in: ${storagePath.toFile()}")
|
||||||
val stateMachineFactory = {
|
val stateMachineFactory = {
|
||||||
DistributedImmutableMap(db, RaftUniquenessProvider.Companion::createMap) }
|
DistributedImmutableMap(db, RaftUniquenessProvider.Companion::createMap)
|
||||||
|
}
|
||||||
val address = raftConfig.nodeAddress.let { Address(it.host, it.port) }
|
val address = raftConfig.nodeAddress.let { Address(it.host, it.port) }
|
||||||
val storage = buildStorage(storagePath)
|
val storage = buildStorage(storagePath)
|
||||||
val transport = buildTransport(transportConfiguration)
|
val transport = buildTransport(transportConfiguration)
|
||||||
@ -110,6 +111,7 @@ class RaftUniquenessProvider(private val services: ServiceHubInternal, private v
|
|||||||
serializer: Serializer) {
|
serializer: Serializer) {
|
||||||
writeMap(obj.entries, buffer, serializer)
|
writeMap(obj.entries, buffer, serializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(type: Class<DistributedImmutableMap.Commands.PutAll<*, *>>,
|
override fun read(type: Class<DistributedImmutableMap.Commands.PutAll<*, *>>,
|
||||||
buffer: BufferInput<out BufferInput<*>>,
|
buffer: BufferInput<out BufferInput<*>>,
|
||||||
serializer: Serializer): DistributedImmutableMap.Commands.PutAll<Any, Any> {
|
serializer: Serializer): DistributedImmutableMap.Commands.PutAll<Any, Any> {
|
||||||
|
@ -36,11 +36,11 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
// incrementally build list of root entities (for later use in Sort parsing)
|
// incrementally build list of root entities (for later use in Sort parsing)
|
||||||
private val rootEntities = mutableMapOf<Class<out PersistentState>, Root<*>>(Pair(VaultSchemaV1.VaultStates::class.java, vaultStates))
|
private val rootEntities = mutableMapOf<Class<out PersistentState>, Root<*>>(Pair(VaultSchemaV1.VaultStates::class.java, vaultStates))
|
||||||
private val aggregateExpressions = mutableListOf<Expression<*>>()
|
private val aggregateExpressions = mutableListOf<Expression<*>>()
|
||||||
private val commonPredicates = mutableMapOf<Pair<String,Operator>, Predicate>() // schema attribute Name, operator -> predicate
|
private val commonPredicates = mutableMapOf<Pair<String, Operator>, Predicate>() // schema attribute Name, operator -> predicate
|
||||||
|
|
||||||
var stateTypes: Vault.StateStatus = Vault.StateStatus.UNCONSUMED
|
var stateTypes: Vault.StateStatus = Vault.StateStatus.UNCONSUMED
|
||||||
|
|
||||||
override fun parseCriteria(criteria: QueryCriteria.VaultQueryCriteria) : Collection<Predicate> {
|
override fun parseCriteria(criteria: QueryCriteria.VaultQueryCriteria): Collection<Predicate> {
|
||||||
log.trace { "Parsing VaultQueryCriteria: $criteria" }
|
log.trace { "Parsing VaultQueryCriteria: $criteria" }
|
||||||
val predicateSet = mutableSetOf<Predicate>()
|
val predicateSet = mutableSetOf<Predicate>()
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
criteria.softLockingCondition?.let {
|
criteria.softLockingCondition?.let {
|
||||||
val softLocking = criteria.softLockingCondition
|
val softLocking = criteria.softLockingCondition
|
||||||
val type = softLocking!!.type
|
val type = softLocking!!.type
|
||||||
when(type) {
|
when (type) {
|
||||||
QueryCriteria.SoftLockingType.UNLOCKED_ONLY ->
|
QueryCriteria.SoftLockingType.UNLOCKED_ONLY ->
|
||||||
predicateSet.add(criteriaBuilder.and(vaultStates.get<String>("lockId").isNull))
|
predicateSet.add(criteriaBuilder.and(vaultStates.get<String>("lockId").isNull))
|
||||||
QueryCriteria.SoftLockingType.LOCKED_ONLY ->
|
QueryCriteria.SoftLockingType.LOCKED_ONLY ->
|
||||||
@ -56,7 +56,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
QueryCriteria.SoftLockingType.UNLOCKED_AND_SPECIFIED -> {
|
QueryCriteria.SoftLockingType.UNLOCKED_AND_SPECIFIED -> {
|
||||||
require(softLocking.lockIds.isNotEmpty()) { "Must specify one or more lockIds" }
|
require(softLocking.lockIds.isNotEmpty()) { "Must specify one or more lockIds" }
|
||||||
predicateSet.add(criteriaBuilder.or(vaultStates.get<String>("lockId").isNull,
|
predicateSet.add(criteriaBuilder.or(vaultStates.get<String>("lockId").isNull,
|
||||||
vaultStates.get<String>("lockId").`in`(softLocking.lockIds.map { it.toString() })))
|
vaultStates.get<String>("lockId").`in`(softLocking.lockIds.map { it.toString() })))
|
||||||
}
|
}
|
||||||
QueryCriteria.SoftLockingType.SPECIFIED -> {
|
QueryCriteria.SoftLockingType.SPECIFIED -> {
|
||||||
require(softLocking.lockIds.isNotEmpty()) { "Must specify one or more lockIds" }
|
require(softLocking.lockIds.isNotEmpty()) { "Must specify one or more lockIds" }
|
||||||
@ -154,7 +154,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun <O> parseExpression(entityRoot: Root<O>, expression: CriteriaExpression<O, Boolean>, predicateSet: MutableSet<Predicate>) {
|
private fun <O> parseExpression(entityRoot: Root<O>, expression: CriteriaExpression<O, Boolean>, predicateSet: MutableSet<Predicate>) {
|
||||||
if (expression is CriteriaExpression.AggregateFunctionExpression<O,*>) {
|
if (expression is CriteriaExpression.AggregateFunctionExpression<O, *>) {
|
||||||
parseAggregateFunction(entityRoot, expression)
|
parseAggregateFunction(entityRoot, expression)
|
||||||
} else {
|
} else {
|
||||||
predicateSet.add(parseExpression(entityRoot, expression) as Predicate)
|
predicateSet.add(parseExpression(entityRoot, expression) as Predicate)
|
||||||
@ -221,7 +221,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseCriteria(criteria: QueryCriteria.FungibleAssetQueryCriteria) : Collection<Predicate> {
|
override fun parseCriteria(criteria: QueryCriteria.FungibleAssetQueryCriteria): Collection<Predicate> {
|
||||||
log.trace { "Parsing FungibleAssetQueryCriteria: $criteria" }
|
log.trace { "Parsing FungibleAssetQueryCriteria: $criteria" }
|
||||||
|
|
||||||
val predicateSet = mutableSetOf<Predicate>()
|
val predicateSet = mutableSetOf<Predicate>()
|
||||||
@ -265,7 +265,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
return predicateSet
|
return predicateSet
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseCriteria(criteria: QueryCriteria.LinearStateQueryCriteria) : Collection<Predicate> {
|
override fun parseCriteria(criteria: QueryCriteria.LinearStateQueryCriteria): Collection<Predicate> {
|
||||||
log.trace { "Parsing LinearStateQueryCriteria: $criteria" }
|
log.trace { "Parsing LinearStateQueryCriteria: $criteria" }
|
||||||
|
|
||||||
val predicateSet = mutableSetOf<Predicate>()
|
val predicateSet = mutableSetOf<Predicate>()
|
||||||
@ -314,8 +314,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
|
|
||||||
// resolve general criteria expressions
|
// resolve general criteria expressions
|
||||||
parseExpression(entityRoot, criteria.expression, predicateSet)
|
parseExpression(entityRoot, criteria.expression, predicateSet)
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch (e: Exception) {
|
|
||||||
e.message?.let { message ->
|
e.message?.let { message ->
|
||||||
if (message.contains("Not an entity"))
|
if (message.contains("Not an entity"))
|
||||||
throw VaultQueryException("""
|
throw VaultQueryException("""
|
||||||
@ -386,8 +385,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
log.warn("Overriding previous attribute [${VaultSchemaV1.VaultStates::stateStatus.name}] value $existingStatus with ${criteria.status}")
|
log.warn("Overriding previous attribute [${VaultSchemaV1.VaultStates::stateStatus.name}] value $existingStatus with ${criteria.status}")
|
||||||
commonPredicates.replace(predicateID, criteriaBuilder.equal(vaultStates.get<Vault.StateStatus>(VaultSchemaV1.VaultStates::stateStatus.name), criteria.status))
|
commonPredicates.replace(predicateID, criteriaBuilder.equal(vaultStates.get<Vault.StateStatus>(VaultSchemaV1.VaultStates::stateStatus.name), criteria.status))
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
commonPredicates.put(predicateID, criteriaBuilder.equal(vaultStates.get<Vault.StateStatus>(VaultSchemaV1.VaultStates::stateStatus.name), criteria.status))
|
commonPredicates.put(predicateID, criteriaBuilder.equal(vaultStates.get<Vault.StateStatus>(VaultSchemaV1.VaultStates::stateStatus.name), criteria.status))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,7 +415,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
|
|
||||||
sorting.columns.map { (sortAttribute, direction) ->
|
sorting.columns.map { (sortAttribute, direction) ->
|
||||||
val (entityStateClass, entityStateAttributeParent, entityStateAttributeChild) =
|
val (entityStateClass, entityStateAttributeParent, entityStateAttributeChild) =
|
||||||
when(sortAttribute) {
|
when (sortAttribute) {
|
||||||
is SortAttribute.Standard -> parse(sortAttribute.attribute)
|
is SortAttribute.Standard -> parse(sortAttribute.attribute)
|
||||||
is SortAttribute.Custom -> Triple(sortAttribute.entityStateClass, sortAttribute.entityStateColumnName, null)
|
is SortAttribute.Custom -> Triple(sortAttribute.entityStateClass, sortAttribute.entityStateColumnName, null)
|
||||||
}
|
}
|
||||||
@ -451,8 +449,8 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parse(sortAttribute: Sort.Attribute): Triple<Class<out PersistentState>, String, String?> {
|
private fun parse(sortAttribute: Sort.Attribute): Triple<Class<out PersistentState>, String, String?> {
|
||||||
val entityClassAndColumnName : Triple<Class<out PersistentState>, String, String?> =
|
val entityClassAndColumnName: Triple<Class<out PersistentState>, String, String?> =
|
||||||
when(sortAttribute) {
|
when (sortAttribute) {
|
||||||
is Sort.CommonStateAttribute -> {
|
is Sort.CommonStateAttribute -> {
|
||||||
Triple(VaultSchemaV1.VaultStates::class.java, sortAttribute.attributeParent, sortAttribute.attributeChild)
|
Triple(VaultSchemaV1.VaultStates::class.java, sortAttribute.attributeParent, sortAttribute.attributeChild)
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ class NodeVaultService(private val clock: Clock, private val keyManagementServic
|
|||||||
val vaultStates = criteriaUpdate.from(VaultSchemaV1.VaultStates::class.java)
|
val vaultStates = criteriaUpdate.from(VaultSchemaV1.VaultStates::class.java)
|
||||||
val stateStatusPredication = criteriaBuilder.equal(vaultStates.get<Vault.StateStatus>(VaultSchemaV1.VaultStates::stateStatus.name), Vault.StateStatus.UNCONSUMED)
|
val stateStatusPredication = criteriaBuilder.equal(vaultStates.get<Vault.StateStatus>(VaultSchemaV1.VaultStates::stateStatus.name), Vault.StateStatus.UNCONSUMED)
|
||||||
val lockIdPredicate = criteriaBuilder.or(vaultStates.get<String>(VaultSchemaV1.VaultStates::lockId.name).isNull,
|
val lockIdPredicate = criteriaBuilder.or(vaultStates.get<String>(VaultSchemaV1.VaultStates::lockId.name).isNull,
|
||||||
criteriaBuilder.equal(vaultStates.get<String>(VaultSchemaV1.VaultStates::lockId.name), lockId.toString()))
|
criteriaBuilder.equal(vaultStates.get<String>(VaultSchemaV1.VaultStates::lockId.name), lockId.toString()))
|
||||||
val persistentStateRefs = stateRefs.map { PersistentStateRef(it.txhash.bytes.toHexString(), it.index) }
|
val persistentStateRefs = stateRefs.map { PersistentStateRef(it.txhash.bytes.toHexString(), it.index) }
|
||||||
val compositeKey = vaultStates.get<PersistentStateRef>(VaultSchemaV1.VaultStates::stateRef.name)
|
val compositeKey = vaultStates.get<PersistentStateRef>(VaultSchemaV1.VaultStates::stateRef.name)
|
||||||
val stateRefsPredicate = criteriaBuilder.and(compositeKey.`in`(persistentStateRefs))
|
val stateRefsPredicate = criteriaBuilder.and(compositeKey.`in`(persistentStateRefs))
|
||||||
@ -468,8 +468,7 @@ class NodeVaultService(private val clock: Clock, private val keyManagementServic
|
|||||||
vaultState.lockId,
|
vaultState.lockId,
|
||||||
vaultState.lockUpdateTime))
|
vaultState.lockUpdateTime))
|
||||||
statesAndRefs.add(StateAndRef(state, stateRef))
|
statesAndRefs.add(StateAndRef(state, stateRef))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// TODO: improve typing of returned other results
|
// TODO: improve typing of returned other results
|
||||||
log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" }
|
log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" }
|
||||||
otherResults.addAll(result.toArray().asList())
|
otherResults.addAll(result.toArray().asList())
|
||||||
|
@ -25,7 +25,7 @@ object VaultSchema
|
|||||||
*/
|
*/
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, version = 1,
|
object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, version = 1,
|
||||||
mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java, VaultTxnNote::class.java)) {
|
mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java, VaultTxnNote::class.java)) {
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "vault_states",
|
@Table(name = "vault_states",
|
||||||
indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status")))
|
indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status")))
|
||||||
@ -90,8 +90,8 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
|
|||||||
) : PersistentState() {
|
) : PersistentState() {
|
||||||
constructor(uid: UniqueIdentifier, _participants: List<AbstractParty>) :
|
constructor(uid: UniqueIdentifier, _participants: List<AbstractParty>) :
|
||||||
this(externalId = uid.externalId,
|
this(externalId = uid.externalId,
|
||||||
uuid = uid.id,
|
uuid = uid.id,
|
||||||
participants = _participants.toMutableSet())
|
participants = _participants.toMutableSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -131,27 +131,27 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
|
|||||||
) : PersistentState() {
|
) : PersistentState() {
|
||||||
constructor(_owner: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: OpaqueBytes, _participants: List<AbstractParty>) :
|
constructor(_owner: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: OpaqueBytes, _participants: List<AbstractParty>) :
|
||||||
this(owner = _owner,
|
this(owner = _owner,
|
||||||
quantity = _quantity,
|
quantity = _quantity,
|
||||||
issuer = _issuerParty,
|
issuer = _issuerParty,
|
||||||
issuerRef = _issuerRef.bytes,
|
issuerRef = _issuerRef.bytes,
|
||||||
participants = _participants.toMutableSet())
|
participants = _participants.toMutableSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "vault_transaction_notes",
|
@Table(name = "vault_transaction_notes",
|
||||||
indexes = arrayOf(Index(name = "seq_no_index", columnList = "seq_no"),
|
indexes = arrayOf(Index(name = "seq_no_index", columnList = "seq_no"),
|
||||||
Index(name = "transaction_id_index", columnList = "transaction_id")))
|
Index(name = "transaction_id_index", columnList = "transaction_id")))
|
||||||
class VaultTxnNote(
|
class VaultTxnNote(
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
@Column(name = "seq_no")
|
@Column(name = "seq_no")
|
||||||
var seqNo: Int,
|
var seqNo: Int,
|
||||||
|
|
||||||
@Column(name = "transaction_id", length = 64)
|
@Column(name = "transaction_id", length = 64)
|
||||||
var txId: String,
|
var txId: String,
|
||||||
|
|
||||||
@Column(name = "note")
|
@Column(name = "note")
|
||||||
var note: String
|
var note: String
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
constructor(txId: String, note: String) : this(0, txId, note)
|
constructor(txId: String, note: String) : this(0, txId, note)
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ class FlowWatchPrintingSubscriber(private val toStream: RenderPrintWriter) : Sub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createStateMachinesTable(): TableElement {
|
private fun createStateMachinesTable(): TableElement {
|
||||||
val table = TableElement(1,2,1,2).overflow(Overflow.HIDDEN).rightCellPadding(1)
|
val table = TableElement(1, 2, 1, 2).overflow(Overflow.HIDDEN).rightCellPadding(1)
|
||||||
val header = RowElement(true).add("Id", "Flow name", "Initiator", "Status").style(Decoration.bold.fg(Color.black).bg(Color.white))
|
val header = RowElement(true).add("Id", "Flow name", "Initiator", "Status").style(Decoration.bold.fg(Color.black).bg(Color.white))
|
||||||
table.add(header)
|
table.add(header)
|
||||||
return table
|
return table
|
||||||
@ -102,12 +102,12 @@ class FlowWatchPrintingSubscriber(private val toStream: RenderPrintWriter) : Sub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun formatFlowId(flowId: StateMachineRunId): String {
|
private fun formatFlowId(flowId: StateMachineRunId): String {
|
||||||
return flowId.toString().removeSurrounding("[","]")
|
return flowId.toString().removeSurrounding("[", "]")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatFlowInitiator(flowInitiator: FlowInitiator): String {
|
private fun formatFlowInitiator(flowInitiator: FlowInitiator): String {
|
||||||
return when (flowInitiator) {
|
return when (flowInitiator) {
|
||||||
is FlowInitiator.Scheduled -> flowInitiator.scheduledState.ref.toString()
|
is FlowInitiator.Scheduled -> flowInitiator.scheduledState.ref.toString()
|
||||||
is FlowInitiator.Shell -> "Shell" // TODO Change when we will have more information on shell user.
|
is FlowInitiator.Shell -> "Shell" // TODO Change when we will have more information on shell user.
|
||||||
is FlowInitiator.Peer -> flowInitiator.party.name.organisation
|
is FlowInitiator.Peer -> flowInitiator.party.name.organisation
|
||||||
is FlowInitiator.RPC -> "RPC: " + flowInitiator.username
|
is FlowInitiator.RPC -> "RPC: " + flowInitiator.username
|
||||||
@ -117,7 +117,7 @@ class FlowWatchPrintingSubscriber(private val toStream: RenderPrintWriter) : Sub
|
|||||||
|
|
||||||
private fun formatFlowResult(flowResult: Try<*>): String {
|
private fun formatFlowResult(flowResult: Try<*>): String {
|
||||||
fun successFormat(value: Any?): String {
|
fun successFormat(value: Any?): String {
|
||||||
return when(value) {
|
return when (value) {
|
||||||
is SignedTransaction -> "Tx ID: " + value.id.toString()
|
is SignedTransaction -> "Tx ID: " + value.id.toString()
|
||||||
is kotlin.Unit -> "No return value"
|
is kotlin.Unit -> "No return value"
|
||||||
null -> "No return value"
|
null -> "No return value"
|
||||||
|
@ -247,11 +247,11 @@ object InteractiveShell {
|
|||||||
// Wait for the flow to end and the progress tracker to notice. By the time the latch is released
|
// Wait for the flow to end and the progress tracker to notice. By the time the latch is released
|
||||||
// the tracker is done with the screen.
|
// the tracker is done with the screen.
|
||||||
latch.await()
|
latch.await()
|
||||||
} catch(e: InterruptedException) {
|
} catch (e: InterruptedException) {
|
||||||
ANSIProgressRenderer.progressTracker = null
|
ANSIProgressRenderer.progressTracker = null
|
||||||
// TODO: When the flow framework allows us to kill flows mid-flight, do so here.
|
// TODO: When the flow framework allows us to kill flows mid-flight, do so here.
|
||||||
}
|
}
|
||||||
} catch(e: NoApplicableConstructor) {
|
} catch (e: NoApplicableConstructor) {
|
||||||
output.println("No matching constructor found:", Color.red)
|
output.println("No matching constructor found:", Color.red)
|
||||||
e.errors.forEach { output.println("- $it", Color.red) }
|
e.errors.forEach { output.println("- $it", Color.red) }
|
||||||
} finally {
|
} finally {
|
||||||
@ -305,14 +305,14 @@ object InteractiveShell {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return invoke(flow)
|
return invoke(flow)
|
||||||
} catch(e: StringToMethodCallParser.UnparseableCallException.MissingParameter) {
|
} catch (e: StringToMethodCallParser.UnparseableCallException.MissingParameter) {
|
||||||
errors.add("${getPrototype()}: missing parameter ${e.paramName}")
|
errors.add("${getPrototype()}: missing parameter ${e.paramName}")
|
||||||
} catch(e: StringToMethodCallParser.UnparseableCallException.TooManyParameters) {
|
} catch (e: StringToMethodCallParser.UnparseableCallException.TooManyParameters) {
|
||||||
errors.add("${getPrototype()}: too many parameters")
|
errors.add("${getPrototype()}: too many parameters")
|
||||||
} catch(e: StringToMethodCallParser.UnparseableCallException.ReflectionDataMissing) {
|
} catch (e: StringToMethodCallParser.UnparseableCallException.ReflectionDataMissing) {
|
||||||
val argTypes = ctor.parameterTypes.map { it.simpleName }
|
val argTypes = ctor.parameterTypes.map { it.simpleName }
|
||||||
errors.add("$argTypes: <constructor missing parameter reflection data>")
|
errors.add("$argTypes: <constructor missing parameter reflection data>")
|
||||||
} catch(e: StringToMethodCallParser.UnparseableCallException) {
|
} catch (e: StringToMethodCallParser.UnparseableCallException) {
|
||||||
val argTypes = ctor.parameterTypes.map { it.simpleName }
|
val argTypes = ctor.parameterTypes.map { it.simpleName }
|
||||||
errors.add("$argTypes: ${e.message}")
|
errors.add("$argTypes: ${e.message}")
|
||||||
}
|
}
|
||||||
@ -506,7 +506,7 @@ object InteractiveShell {
|
|||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
value.close()
|
value.close()
|
||||||
} catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
// Ignore.
|
// Ignore.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@ import java.util.*
|
|||||||
* behaviour is unpredictable! There is a best-effort check for double inserts, but this should *not* be relied on, so
|
* behaviour is unpredictable! There is a best-effort check for double inserts, but this should *not* be relied on, so
|
||||||
* ONLY USE THIS IF YOUR TABLE IS APPEND-ONLY
|
* ONLY USE THIS IF YOUR TABLE IS APPEND-ONLY
|
||||||
*/
|
*/
|
||||||
class AppendOnlyPersistentMap<K, V, E, out EK> (
|
class AppendOnlyPersistentMap<K, V, E, out EK>(
|
||||||
val toPersistentEntityKey: (K) -> EK,
|
val toPersistentEntityKey: (K) -> EK,
|
||||||
val fromPersistentEntity: (E) -> Pair<K,V>,
|
val fromPersistentEntity: (E) -> Pair<K, V>,
|
||||||
val toPersistentEntity: (key: K, value: V) -> E,
|
val toPersistentEntity: (key: K, value: V) -> E,
|
||||||
val persistentEntityClass: Class<E>,
|
val persistentEntityClass: Class<E>,
|
||||||
cacheBound: Long = 1024
|
cacheBound: Long = 1024
|
||||||
@ -48,10 +48,11 @@ class AppendOnlyPersistentMap<K, V, E, out EK> (
|
|||||||
return result.map { x -> fromPersistentEntity(x) }.asSequence()
|
return result.map { x -> fromPersistentEntity(x) }.asSequence()
|
||||||
}
|
}
|
||||||
|
|
||||||
private tailrec fun set(key: K, value: V, logWarning: Boolean, store: (K,V) -> V?): Boolean {
|
private tailrec fun set(key: K, value: V, logWarning: Boolean, store: (K, V) -> V?): Boolean {
|
||||||
var insertionAttempt = false
|
var insertionAttempt = false
|
||||||
var isUnique = true
|
var isUnique = true
|
||||||
val existingInCache = cache.get(key) { // Thread safe, if multiple threads may wait until the first one has loaded.
|
val existingInCache = cache.get(key) {
|
||||||
|
// Thread safe, if multiple threads may wait until the first one has loaded.
|
||||||
insertionAttempt = true
|
insertionAttempt = true
|
||||||
// Key wasn't in the cache and might be in the underlying storage.
|
// Key wasn't in the cache and might be in the underlying storage.
|
||||||
// Depending on 'store' method, this may insert without checking key duplication or it may avoid inserting a duplicated key.
|
// Depending on 'store' method, this may insert without checking key duplication or it may avoid inserting a duplicated key.
|
||||||
@ -85,8 +86,8 @@ class AppendOnlyPersistentMap<K, V, E, out EK> (
|
|||||||
* If the map previously contained a mapping for the key, the behaviour is unpredictable and may throw an error from the underlying storage.
|
* If the map previously contained a mapping for the key, the behaviour is unpredictable and may throw an error from the underlying storage.
|
||||||
*/
|
*/
|
||||||
operator fun set(key: K, value: V) =
|
operator fun set(key: K, value: V) =
|
||||||
set(key, value, logWarning = false) {
|
set(key, value, logWarning = false) { k, v ->
|
||||||
k, v -> DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v))
|
DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v))
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,8 +97,7 @@ class AppendOnlyPersistentMap<K, V, E, out EK> (
|
|||||||
* @return true if added key was unique, otherwise false
|
* @return true if added key was unique, otherwise false
|
||||||
*/
|
*/
|
||||||
fun addWithDuplicatesAllowed(key: K, value: V, logWarning: Boolean = true): Boolean =
|
fun addWithDuplicatesAllowed(key: K, value: V, logWarning: Boolean = true): Boolean =
|
||||||
set(key, value, logWarning) {
|
set(key, value, logWarning) { k, v ->
|
||||||
k, v ->
|
|
||||||
val existingEntry = DatabaseTransactionManager.current().session.find(persistentEntityClass, toPersistentEntityKey(k))
|
val existingEntry = DatabaseTransactionManager.current().session.find(persistentEntityClass, toPersistentEntityKey(k))
|
||||||
if (existingEntry == null) {
|
if (existingEntry == null) {
|
||||||
DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v))
|
DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v))
|
||||||
@ -107,7 +107,7 @@ class AppendOnlyPersistentMap<K, V, E, out EK> (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putAll(entries: Map<K,V>) {
|
fun putAll(entries: Map<K, V>) {
|
||||||
entries.forEach {
|
entries.forEach {
|
||||||
set(it.key, it.value)
|
set(it.key, it.value)
|
||||||
}
|
}
|
||||||
|
@ -24,14 +24,14 @@ const val NODE_DATABASE_PREFIX = "node_"
|
|||||||
|
|
||||||
//HikariDataSource implements Closeable which allows CordaPersistence to be Closeable
|
//HikariDataSource implements Closeable which allows CordaPersistence to be Closeable
|
||||||
class CordaPersistence(var dataSource: HikariDataSource, private val schemaService: SchemaService,
|
class CordaPersistence(var dataSource: HikariDataSource, private val schemaService: SchemaService,
|
||||||
private val createIdentityService: ()-> IdentityService, databaseProperties: Properties): Closeable {
|
private val createIdentityService: () -> IdentityService, databaseProperties: Properties) : Closeable {
|
||||||
var transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel"))
|
var transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel"))
|
||||||
|
|
||||||
val hibernateConfig: HibernateConfiguration by lazy {
|
val hibernateConfig: HibernateConfiguration by lazy {
|
||||||
transaction {
|
transaction {
|
||||||
HibernateConfiguration(schemaService, databaseProperties, createIdentityService)
|
HibernateConfiguration(schemaService, databaseProperties, createIdentityService)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val entityManagerFactory: SessionFactory by lazy {
|
val entityManagerFactory: SessionFactory by lazy {
|
||||||
transaction {
|
transaction {
|
||||||
@ -70,8 +70,7 @@ class CordaPersistence(var dataSource: HikariDataSource, private val schemaServi
|
|||||||
|
|
||||||
return if (outer != null) {
|
return if (outer != null) {
|
||||||
outer.statement()
|
outer.statement()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
inTopLevelTransaction(transactionIsolation, repetitionAttempts, statement)
|
inTopLevelTransaction(transactionIsolation, repetitionAttempts, statement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,19 +83,16 @@ class CordaPersistence(var dataSource: HikariDataSource, private val schemaServi
|
|||||||
val answer = transaction.statement()
|
val answer = transaction.statement()
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
return answer
|
return answer
|
||||||
}
|
} catch (e: SQLException) {
|
||||||
catch (e: SQLException) {
|
|
||||||
transaction.rollback()
|
transaction.rollback()
|
||||||
repetitions++
|
repetitions++
|
||||||
if (repetitions >= repetitionAttempts) {
|
if (repetitions >= repetitionAttempts) {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
} catch (e: Throwable) {
|
||||||
catch (e: Throwable) {
|
|
||||||
transaction.rollback()
|
transaction.rollback()
|
||||||
throw e
|
throw e
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
transaction.close()
|
transaction.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,7 +166,7 @@ private class DatabaseTransactionWrappingSubscriber<U>(val db: CordaPersistence?
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A subscriber that wraps another but does not pass on observations to it.
|
// A subscriber that wraps another but does not pass on observations to it.
|
||||||
private class NoOpSubscriber<U>(t: Subscriber<in U>): Subscriber<U>(t) {
|
private class NoOpSubscriber<U>(t: Subscriber<in U>) : Subscriber<U>(t) {
|
||||||
override fun onCompleted() {
|
override fun onCompleted() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class DatabaseTransaction(isolation: Int, val threadLocal: ThreadLocal<DatabaseT
|
|||||||
}
|
}
|
||||||
|
|
||||||
val session: Session by sessionDelegate
|
val session: Session by sessionDelegate
|
||||||
private lateinit var hibernateTransaction : Transaction
|
private lateinit var hibernateTransaction: Transaction
|
||||||
|
|
||||||
private val outerTransaction: DatabaseTransaction? = threadLocal.get()
|
private val outerTransaction: DatabaseTransaction? = threadLocal.get()
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ fun KeyStore.getCertificateAndKeyPair(alias: String, keyPassword: String): Certi
|
|||||||
*/
|
*/
|
||||||
fun KeyStore.getX509Certificate(alias: String): X509Certificate {
|
fun KeyStore.getX509Certificate(alias: String): X509Certificate {
|
||||||
val certificate = getCertificate(alias) ?: throw IllegalArgumentException("No certificate under alias \"$alias\".")
|
val certificate = getCertificate(alias) ?: throw IllegalArgumentException("No certificate under alias \"$alias\".")
|
||||||
return certificate as? X509Certificate ?: throw IllegalArgumentException("Certificate under alias \"$alias\" is not an X.509 certificate.")
|
return certificate as? X509Certificate ?: throw IllegalArgumentException("Certificate under alias \"$alias\" is not an X.509 certificate.")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,7 +8,7 @@ import com.google.common.util.concurrent.ListenableFuture
|
|||||||
|
|
||||||
class NonInvalidatingCache<K, V> private constructor(
|
class NonInvalidatingCache<K, V> private constructor(
|
||||||
val cache: LoadingCache<K, V>
|
val cache: LoadingCache<K, V>
|
||||||
): LoadingCache<K, V> by cache {
|
) : LoadingCache<K, V> by cache {
|
||||||
|
|
||||||
constructor(bound: Long, concurrencyLevel: Int, loadFunction: (K) -> V) :
|
constructor(bound: Long, concurrencyLevel: Int, loadFunction: (K) -> V) :
|
||||||
this(buildCache(bound, concurrencyLevel, loadFunction))
|
this(buildCache(bound, concurrencyLevel, loadFunction))
|
||||||
@ -25,6 +25,7 @@ class NonInvalidatingCache<K, V> private constructor(
|
|||||||
override fun reload(key: K, oldValue: V): ListenableFuture<V> {
|
override fun reload(key: K, oldValue: V): ListenableFuture<V> {
|
||||||
throw IllegalStateException("Non invalidating cache refreshed")
|
throw IllegalStateException("Non invalidating cache refreshed")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(key: K) = loadFunction(key)
|
override fun load(key: K) = loadFunction(key)
|
||||||
override fun loadAll(keys: Iterable<K>): MutableMap<K, V> {
|
override fun loadAll(keys: Iterable<K>): MutableMap<K, V> {
|
||||||
return super.loadAll(keys)
|
return super.loadAll(keys)
|
||||||
|
@ -6,10 +6,10 @@ import com.google.common.util.concurrent.ListenableFuture
|
|||||||
|
|
||||||
class NonInvalidatingUnboundCache<K, V> private constructor(
|
class NonInvalidatingUnboundCache<K, V> private constructor(
|
||||||
val cache: LoadingCache<K, V>
|
val cache: LoadingCache<K, V>
|
||||||
): LoadingCache<K, V> by cache {
|
) : LoadingCache<K, V> by cache {
|
||||||
|
|
||||||
constructor(concurrencyLevel: Int, loadFunction: (K) -> V, removalListener: RemovalListener<K, V> = RemovalListener {},
|
constructor(concurrencyLevel: Int, loadFunction: (K) -> V, removalListener: RemovalListener<K, V> = RemovalListener {},
|
||||||
keysToPreload: () -> Iterable<K> = { emptyList() } ) :
|
keysToPreload: () -> Iterable<K> = { emptyList() }) :
|
||||||
this(buildCache(concurrencyLevel, loadFunction, removalListener, keysToPreload))
|
this(buildCache(concurrencyLevel, loadFunction, removalListener, keysToPreload))
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
@ -27,6 +27,7 @@ class NonInvalidatingUnboundCache<K, V> private constructor(
|
|||||||
override fun reload(key: K, oldValue: V): ListenableFuture<V> {
|
override fun reload(key: K, oldValue: V): ListenableFuture<V> {
|
||||||
throw IllegalStateException("Non invalidating cache refreshed")
|
throw IllegalStateException("Non invalidating cache refreshed")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(key: K) = loadFunction(key)
|
override fun load(key: K) = loadFunction(key)
|
||||||
override fun loadAll(keys: Iterable<K>): MutableMap<K, V> {
|
override fun loadAll(keys: Iterable<K>): MutableMap<K, V> {
|
||||||
return super.loadAll(keys)
|
return super.loadAll(keys)
|
||||||
|
@ -11,9 +11,9 @@ import java.util.*
|
|||||||
/**
|
/**
|
||||||
* Implements an unbound caching layer on top of a table accessed via Hibernate mapping.
|
* Implements an unbound caching layer on top of a table accessed via Hibernate mapping.
|
||||||
*/
|
*/
|
||||||
class PersistentMap<K, V, E, out EK> (
|
class PersistentMap<K, V, E, out EK>(
|
||||||
val toPersistentEntityKey: (K) -> EK,
|
val toPersistentEntityKey: (K) -> EK,
|
||||||
val fromPersistentEntity: (E) -> Pair<K,V>,
|
val fromPersistentEntity: (E) -> Pair<K, V>,
|
||||||
val toPersistentEntity: (key: K, value: V) -> E,
|
val toPersistentEntity: (key: K, value: V) -> E,
|
||||||
val persistentEntityClass: Class<E>
|
val persistentEntityClass: Class<E>
|
||||||
) : MutableMap<K, V>, AbstractMap<K, V>() {
|
) : MutableMap<K, V>, AbstractMap<K, V>() {
|
||||||
@ -34,7 +34,7 @@ class PersistentMap<K, V, E, out EK> (
|
|||||||
getAll(session.createQuery(criteriaQuery).resultList.map { e -> fromPersistentEntity(e as E).first }.asIterable())
|
getAll(session.createQuery(criteriaQuery).resultList.map { e -> fromPersistentEntity(e as E).first }.asIterable())
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExplicitRemoval<K, V, E, EK>(private val toPersistentEntityKey: (K) -> EK, private val persistentEntityClass: Class<E>): RemovalListener<K,V> {
|
class ExplicitRemoval<K, V, E, EK>(private val toPersistentEntityKey: (K) -> EK, private val persistentEntityClass: Class<E>) : RemovalListener<K, V> {
|
||||||
override fun onRemoval(notification: RemovalNotification<K, V>?) {
|
override fun onRemoval(notification: RemovalNotification<K, V>?) {
|
||||||
when (notification?.cause) {
|
when (notification?.cause) {
|
||||||
RemovalCause.EXPLICIT -> {
|
RemovalCause.EXPLICIT -> {
|
||||||
@ -47,7 +47,8 @@ class PersistentMap<K, V, E, out EK> (
|
|||||||
RemovalCause.EXPIRED, RemovalCause.SIZE, RemovalCause.COLLECTED -> {
|
RemovalCause.EXPIRED, RemovalCause.SIZE, RemovalCause.COLLECTED -> {
|
||||||
log.error("Entry was removed from cache!!!")
|
log.error("Entry was removed from cache!!!")
|
||||||
}
|
}
|
||||||
RemovalCause.REPLACED -> {}
|
RemovalCause.REPLACED -> {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,10 +63,11 @@ class PersistentMap<K, V, E, out EK> (
|
|||||||
|
|
||||||
override val size get() = cache.size().toInt()
|
override val size get() = cache.size().toInt()
|
||||||
|
|
||||||
private tailrec fun set(key: K, value: V, logWarning: Boolean = true, store: (K,V) -> V?, replace: (K, V) -> Unit) : Boolean {
|
private tailrec fun set(key: K, value: V, logWarning: Boolean = true, store: (K, V) -> V?, replace: (K, V) -> Unit): Boolean {
|
||||||
var insertionAttempt = false
|
var insertionAttempt = false
|
||||||
var isUnique = true
|
var isUnique = true
|
||||||
val existingInCache = cache.get(key) { // Thread safe, if multiple threads may wait until the first one has loaded.
|
val existingInCache = cache.get(key) {
|
||||||
|
// Thread safe, if multiple threads may wait until the first one has loaded.
|
||||||
insertionAttempt = true
|
insertionAttempt = true
|
||||||
// Value wasn't in the cache and wasn't in DB (because the cache is unbound).
|
// Value wasn't in the cache and wasn't in DB (because the cache is unbound).
|
||||||
// Store the value, depending on store implementation this may replace existing entry in DB.
|
// Store the value, depending on store implementation this may replace existing entry in DB.
|
||||||
@ -98,7 +100,7 @@ class PersistentMap<K, V, E, out EK> (
|
|||||||
operator fun set(key: K, value: V) =
|
operator fun set(key: K, value: V) =
|
||||||
set(key, value,
|
set(key, value,
|
||||||
logWarning = false,
|
logWarning = false,
|
||||||
store = { k: K, v: V ->
|
store = { k: K, v: V ->
|
||||||
DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v))
|
DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v))
|
||||||
null
|
null
|
||||||
},
|
},
|
||||||
@ -145,10 +147,10 @@ class PersistentMap<K, V, E, out EK> (
|
|||||||
private fun merge(key: K, value: V): V? {
|
private fun merge(key: K, value: V): V? {
|
||||||
val existingEntry = DatabaseTransactionManager.current().session.find(persistentEntityClass, toPersistentEntityKey(key))
|
val existingEntry = DatabaseTransactionManager.current().session.find(persistentEntityClass, toPersistentEntityKey(key))
|
||||||
return if (existingEntry != null) {
|
return if (existingEntry != null) {
|
||||||
DatabaseTransactionManager.current().session.merge(toPersistentEntity(key,value))
|
DatabaseTransactionManager.current().session.merge(toPersistentEntity(key, value))
|
||||||
fromPersistentEntity(existingEntry).second
|
fromPersistentEntity(existingEntry).second
|
||||||
} else {
|
} else {
|
||||||
DatabaseTransactionManager.current().session.save(toPersistentEntity(key,value))
|
DatabaseTransactionManager.current().session.save(toPersistentEntity(key, value))
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,56 +195,59 @@ class PersistentMap<K, V, E, out EK> (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val keys: MutableSet<K> get() {
|
override val keys: MutableSet<K>
|
||||||
return object : AbstractSet<K>() {
|
get() {
|
||||||
override val size: Int get() = this@PersistentMap.size
|
return object : AbstractSet<K>() {
|
||||||
override fun iterator(): MutableIterator<K> {
|
override val size: Int get() = this@PersistentMap.size
|
||||||
return object : MutableIterator<K> {
|
override fun iterator(): MutableIterator<K> {
|
||||||
private val entryIterator = EntryIterator()
|
return object : MutableIterator<K> {
|
||||||
|
private val entryIterator = EntryIterator()
|
||||||
|
|
||||||
override fun hasNext(): Boolean = entryIterator.hasNext()
|
override fun hasNext(): Boolean = entryIterator.hasNext()
|
||||||
override fun next(): K = entryIterator.next().key
|
override fun next(): K = entryIterator.next().key
|
||||||
override fun remove() {
|
override fun remove() {
|
||||||
entryIterator.remove()
|
entryIterator.remove()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override val values: MutableCollection<V> get() {
|
override val values: MutableCollection<V>
|
||||||
return object : AbstractCollection<V>() {
|
get() {
|
||||||
override val size: Int get() = this@PersistentMap.size
|
return object : AbstractCollection<V>() {
|
||||||
override fun iterator(): MutableIterator<V> {
|
override val size: Int get() = this@PersistentMap.size
|
||||||
return object : MutableIterator<V> {
|
override fun iterator(): MutableIterator<V> {
|
||||||
private val entryIterator = EntryIterator()
|
return object : MutableIterator<V> {
|
||||||
|
private val entryIterator = EntryIterator()
|
||||||
|
|
||||||
override fun hasNext(): Boolean = entryIterator.hasNext()
|
override fun hasNext(): Boolean = entryIterator.hasNext()
|
||||||
override fun next(): V = entryIterator.next().value
|
override fun next(): V = entryIterator.next().value
|
||||||
override fun remove() {
|
override fun remove() {
|
||||||
entryIterator.remove()
|
entryIterator.remove()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> get() {
|
override val entries: MutableSet<MutableMap.MutableEntry<K, V>>
|
||||||
return object : AbstractSet<MutableMap.MutableEntry<K, V>>() {
|
get() {
|
||||||
override val size: Int get() = this@PersistentMap.size
|
return object : AbstractSet<MutableMap.MutableEntry<K, V>>() {
|
||||||
override fun iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> {
|
override val size: Int get() = this@PersistentMap.size
|
||||||
return object : MutableIterator<MutableMap.MutableEntry<K, V>> {
|
override fun iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> {
|
||||||
private val entryIterator = EntryIterator()
|
return object : MutableIterator<MutableMap.MutableEntry<K, V>> {
|
||||||
|
private val entryIterator = EntryIterator()
|
||||||
|
|
||||||
override fun hasNext(): Boolean = entryIterator.hasNext()
|
override fun hasNext(): Boolean = entryIterator.hasNext()
|
||||||
override fun next(): MutableMap.MutableEntry<K, V> = entryIterator.next()
|
override fun next(): MutableMap.MutableEntry<K, V> = entryIterator.next()
|
||||||
override fun remove() {
|
override fun remove() {
|
||||||
entryIterator.remove()
|
entryIterator.remove()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun put(key: K, value: V): V? {
|
override fun put(key: K, value: V): V? {
|
||||||
val old = cache.get(key)
|
val old = cache.get(key)
|
||||||
|
@ -21,7 +21,8 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC
|
|||||||
|
|
||||||
override fun toToken(context: SerializeAsTokenContext) = token.registerWithContext(context, this)
|
override fun toToken(context: SerializeAsTokenContext) = token.registerWithContext(context, this)
|
||||||
|
|
||||||
@Synchronized fun updateDate(date: LocalDate): Boolean {
|
@Synchronized
|
||||||
|
fun updateDate(date: LocalDate): Boolean {
|
||||||
val currentDate = LocalDate.now(this)
|
val currentDate = LocalDate.now(this)
|
||||||
if (currentDate.isBefore(date)) {
|
if (currentDate.isBefore(date)) {
|
||||||
// It's ok to increment
|
// It's ok to increment
|
||||||
|
@ -115,7 +115,7 @@ object X509Utilities {
|
|||||||
subjectPublicKey: PublicKey,
|
subjectPublicKey: PublicKey,
|
||||||
validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW,
|
validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW,
|
||||||
nameConstraints: NameConstraints? = null): X509CertificateHolder
|
nameConstraints: NameConstraints? = null): X509CertificateHolder
|
||||||
= createCertificate(certificateType, issuerCertificate, issuerKeyPair, subject.x500Name, subjectPublicKey, validityWindow, nameConstraints)
|
= createCertificate(certificateType, issuerCertificate, issuerKeyPair, subject.x500Name, subjectPublicKey, validityWindow, nameConstraints)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a X509 v3 certificate for use as a CA or for TLS. This does not require a [CordaX500Name] because the
|
* Create a X509 v3 certificate for use as a CA or for TLS. This does not require a [CordaX500Name] because the
|
||||||
@ -267,9 +267,9 @@ object X509Utilities {
|
|||||||
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
|
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
|
||||||
*/
|
*/
|
||||||
internal fun createCertificate(certificateType: CertificateType, issuer: X500Name, issuerKeyPair: KeyPair,
|
internal fun createCertificate(certificateType: CertificateType, issuer: X500Name, issuerKeyPair: KeyPair,
|
||||||
subject: X500Name, subjectPublicKey: PublicKey,
|
subject: X500Name, subjectPublicKey: PublicKey,
|
||||||
validityWindow: Pair<Date, Date>,
|
validityWindow: Pair<Date, Date>,
|
||||||
nameConstraints: NameConstraints? = null): X509CertificateHolder {
|
nameConstraints: NameConstraints? = null): X509CertificateHolder {
|
||||||
|
|
||||||
val signatureScheme = Crypto.findSignatureScheme(issuerKeyPair.private)
|
val signatureScheme = Crypto.findSignatureScheme(issuerKeyPair.private)
|
||||||
val provider = Crypto.findProvider(signatureScheme.providerName)
|
val provider = Crypto.findProvider(signatureScheme.providerName)
|
||||||
|
@ -91,10 +91,10 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
|
|||||||
@Test
|
@Test
|
||||||
public void unconsumedStatesForStateRefsSortedByTxnId() {
|
public void unconsumedStatesForStateRefsSortedByTxnId() {
|
||||||
Vault<LinearState> issuedStates =
|
Vault<LinearState> issuedStates =
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
VaultFiller.fillWithSomeTestLinearStates(services, 8);
|
VaultFiller.fillWithSomeTestLinearStates(services, 8);
|
||||||
return VaultFiller.fillWithSomeTestLinearStates(services, 2);
|
return VaultFiller.fillWithSomeTestLinearStates(services, 2);
|
||||||
});
|
});
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
Stream<StateRef> stateRefsStream = StreamSupport.stream(issuedStates.getStates().spliterator(), false).map(StateAndRef::getRef);
|
Stream<StateRef> stateRefsStream = StreamSupport.stream(issuedStates.getStates().spliterator(), false).map(StateAndRef::getRef);
|
||||||
List<StateRef> stateRefs = stateRefsStream.collect(Collectors.toList());
|
List<StateRef> stateRefs = stateRefsStream.collect(Collectors.toList());
|
||||||
@ -120,7 +120,7 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
|
|||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
VaultFiller.fillWithSomeTestCash(services,
|
VaultFiller.fillWithSomeTestCash(services,
|
||||||
new Amount<Currency>(100, Currency.getInstance("USD")),
|
new Amount<Currency>(100, Currency.getInstance("USD")),
|
||||||
issuerServices,
|
issuerServices,
|
||||||
TestConstants.getDUMMY_NOTARY(),
|
TestConstants.getDUMMY_NOTARY(),
|
||||||
3,
|
3,
|
||||||
3,
|
3,
|
||||||
@ -151,14 +151,14 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
|
|||||||
List<String> dealIds = Arrays.asList("123", "456", "789");
|
List<String> dealIds = Arrays.asList("123", "456", "789");
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Triple<StateAndRef<LinearState>, UniqueIdentifier, Vault<DealState>> ids =
|
Triple<StateAndRef<LinearState>, UniqueIdentifier, Vault<DealState>> ids =
|
||||||
database.transaction((DatabaseTransaction tx) -> {
|
database.transaction((DatabaseTransaction tx) -> {
|
||||||
Vault<LinearState> states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null);
|
Vault<LinearState> states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null);
|
||||||
StateAndRef<LinearState> linearState = states.getStates().iterator().next();
|
StateAndRef<LinearState> linearState = states.getStates().iterator().next();
|
||||||
UniqueIdentifier uid = linearState.component1().getData().getLinearId();
|
UniqueIdentifier uid = linearState.component1().getData().getLinearId();
|
||||||
|
|
||||||
Vault<DealState> dealStates = VaultFiller.fillWithSomeTestDeals(services, dealIds);
|
Vault<DealState> dealStates = VaultFiller.fillWithSomeTestDeals(services, dealIds);
|
||||||
return new Triple(linearState,uid,dealStates);
|
return new Triple(linearState, uid, dealStates);
|
||||||
});
|
});
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
// consume states
|
// consume states
|
||||||
VaultFiller.consumeDeals(services, (List<? extends StateAndRef<? extends DealState>>) ids.getThird().getStates(), getDUMMY_NOTARY());
|
VaultFiller.consumeDeals(services, (List<? extends StateAndRef<? extends DealState>>) ids.getThird().getStates(), getDUMMY_NOTARY());
|
||||||
@ -276,13 +276,13 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
|
|||||||
public void trackDealStatesPagedSorted() {
|
public void trackDealStatesPagedSorted() {
|
||||||
List<String> dealIds = Arrays.asList("123", "456", "789");
|
List<String> dealIds = Arrays.asList("123", "456", "789");
|
||||||
UniqueIdentifier uid =
|
UniqueIdentifier uid =
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
Vault<LinearState> states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null);
|
Vault<LinearState> states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null);
|
||||||
UniqueIdentifier _uid = states.getStates().iterator().next().component1().getData().getLinearId();
|
UniqueIdentifier _uid = states.getStates().iterator().next().component1().getData().getLinearId();
|
||||||
|
|
||||||
VaultFiller.fillWithSomeTestDeals(services, dealIds);
|
VaultFiller.fillWithSomeTestDeals(services, dealIds);
|
||||||
return _uid;
|
return _uid;
|
||||||
});
|
});
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
// DOCSTART VaultJavaQueryExample5
|
// DOCSTART VaultJavaQueryExample5
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -272,6 +272,6 @@ class CordaRPCOpsImplTest {
|
|||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
class VoidRPCFlow : FlowLogic<Void?>() {
|
class VoidRPCFlow : FlowLogic<Void?>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() : Void? = null
|
override fun call(): Void? = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,4 +84,4 @@ class InteractiveShellTest {
|
|||||||
fun party() = check("party: \"${MEGA_CORP.name}\"", MEGA_CORP.name.toString())
|
fun party() = check("party: \"${MEGA_CORP.name}\"", MEGA_CORP.name.toString())
|
||||||
|
|
||||||
class DummyFSM(val logic: FlowA) : FlowStateMachine<Any?> by mock()
|
class DummyFSM(val logic: FlowA) : FlowStateMachine<Any?> by mock()
|
||||||
}
|
}
|
||||||
|
@ -9,25 +9,29 @@ import java.nio.file.Paths
|
|||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
class DummyFlow : FlowLogic<Unit>() {
|
class DummyFlow : FlowLogic<Unit>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() { }
|
override fun call() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitiatedBy(DummyFlow::class)
|
@InitiatedBy(DummyFlow::class)
|
||||||
class LoaderTestFlow(unusedSession: FlowSession) : FlowLogic<Unit>() {
|
class LoaderTestFlow(unusedSession: FlowSession) : FlowLogic<Unit>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() { }
|
override fun call() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SchedulableFlow
|
@SchedulableFlow
|
||||||
class DummySchedulableFlow : FlowLogic<Unit>() {
|
class DummySchedulableFlow : FlowLogic<Unit>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() { }
|
override fun call() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
class DummyRPCFlow : FlowLogic<Unit>() {
|
class DummyRPCFlow : FlowLogic<Unit>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() { }
|
override fun call() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CordappLoaderTest {
|
class CordappLoaderTest {
|
||||||
|
@ -37,7 +37,7 @@ class CordappProviderImplTests {
|
|||||||
val provider = CordappProviderImpl(loader)
|
val provider = CordappProviderImpl(loader)
|
||||||
|
|
||||||
provider.start(attachmentStore)
|
provider.start(attachmentStore)
|
||||||
|
|
||||||
Assert.assertNull(provider.getCordappAttachmentId(provider.cordapps.first()))
|
Assert.assertNull(provider.getCordappAttachmentId(provider.cordapps.first()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
return listOf(true, false)
|
return listOf(true, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@ -164,8 +165,8 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
|
|
||||||
val cashStates = bobNode.database.transaction {
|
val cashStates = bobNode.database.transaction {
|
||||||
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notary, 3, 3,
|
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notary, 3, 3,
|
||||||
issuedBy = issuer)
|
issuedBy = issuer)
|
||||||
}
|
}
|
||||||
|
|
||||||
val alicesFakePaper = aliceNode.database.transaction {
|
val alicesFakePaper = aliceNode.database.transaction {
|
||||||
fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(),
|
fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(),
|
||||||
|
@ -153,7 +153,7 @@ class ScheduledFlowTests {
|
|||||||
val statesFromB: List<StateAndRef<ScheduledState>> = nodeB.database.transaction {
|
val statesFromB: List<StateAndRef<ScheduledState>> = nodeB.database.transaction {
|
||||||
queryStatesWithPaging(nodeB.services.vaultService)
|
queryStatesWithPaging(nodeB.services.vaultService)
|
||||||
}
|
}
|
||||||
assertEquals("Expect all states to be present",2 * N, statesFromA.count())
|
assertEquals("Expect all states to be present", 2 * N, statesFromA.count())
|
||||||
statesFromA.forEach { ref ->
|
statesFromA.forEach { ref ->
|
||||||
if (ref !in statesFromB) {
|
if (ref !in statesFromB) {
|
||||||
throw IllegalStateException("State $ref is only present on node A.")
|
throw IllegalStateException("State $ref is only present on node A.")
|
||||||
|
@ -40,7 +40,9 @@ import kotlin.test.assertNull
|
|||||||
|
|
||||||
//TODO This needs to be merged into P2PMessagingTest as that creates a more realistic environment
|
//TODO This needs to be merged into P2PMessagingTest as that creates a more realistic environment
|
||||||
class ArtemisMessagingTests : TestDependencyInjectionBase() {
|
class ArtemisMessagingTests : TestDependencyInjectionBase() {
|
||||||
@Rule @JvmField val temporaryFolder = TemporaryFolder()
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
val temporaryFolder = TemporaryFolder()
|
||||||
|
|
||||||
val serverPort = freePort()
|
val serverPort = freePort()
|
||||||
val rpcPort = freePort()
|
val rpcPort = freePort()
|
||||||
|
@ -44,7 +44,7 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
|
|||||||
lateinit var alice: StartedNode<MockNode>
|
lateinit var alice: StartedNode<MockNode>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val subscriberLegalName = CordaX500Name(organisation ="Subscriber", locality ="New York", country ="US")
|
val subscriberLegalName = CordaX500Name(organisation = "Subscriber", locality = "New York", country = "US")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@ -205,7 +205,7 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
|
|||||||
private var lastSerial = Long.MIN_VALUE
|
private var lastSerial = Long.MIN_VALUE
|
||||||
|
|
||||||
private fun StartedNode<*>.registration(addOrRemove: AddOrRemove,
|
private fun StartedNode<*>.registration(addOrRemove: AddOrRemove,
|
||||||
serial: Long? = null): CordaFuture<RegistrationResponse> {
|
serial: Long? = null): CordaFuture<RegistrationResponse> {
|
||||||
val distinctSerial = if (serial == null) {
|
val distinctSerial = if (serial == null) {
|
||||||
++lastSerial
|
++lastSerial
|
||||||
} else {
|
} else {
|
||||||
|
@ -42,11 +42,12 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() {
|
|||||||
database.transaction {
|
database.transaction {
|
||||||
|
|
||||||
services = object : MockServices(BOB_KEY) {
|
services = object : MockServices(BOB_KEY) {
|
||||||
override val vaultService: VaultServiceInternal get() {
|
override val vaultService: VaultServiceInternal
|
||||||
val vaultService = NodeVaultService(clock, keyManagementService, stateLoader, database.hibernateConfig)
|
get() {
|
||||||
hibernatePersister = HibernateObserver(vaultService.rawUpdates, database.hibernateConfig)
|
val vaultService = NodeVaultService(clock, keyManagementService, stateLoader, database.hibernateConfig)
|
||||||
return vaultService
|
hibernatePersister = HibernateObserver(vaultService.rawUpdates, database.hibernateConfig)
|
||||||
}
|
return vaultService
|
||||||
|
}
|
||||||
|
|
||||||
override fun recordTransactions(txs: Iterable<SignedTransaction>) {
|
override fun recordTransactions(txs: Iterable<SignedTransaction>) {
|
||||||
for (stx in txs) {
|
for (stx in txs) {
|
||||||
|
@ -89,6 +89,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
// Refactored to use notifyAll() as we have no other unit test for that method with multiple transactions.
|
// Refactored to use notifyAll() as we have no other unit test for that method with multiple transactions.
|
||||||
vaultService.notifyAll(txs.map { it.tx })
|
vaultService.notifyAll(txs.map { it.tx })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun jdbcSession() = database.createSession()
|
override fun jdbcSession() = database.createSession()
|
||||||
}
|
}
|
||||||
hibernatePersister = services.hibernatePersister
|
hibernatePersister = services.hibernatePersister
|
||||||
@ -146,10 +147,10 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
@Test
|
@Test
|
||||||
fun `select by composite primary key`() {
|
fun `select by composite primary key`() {
|
||||||
val issuedStates =
|
val issuedStates =
|
||||||
database.transaction {
|
database.transaction {
|
||||||
services.fillWithSomeTestLinearStates(8)
|
services.fillWithSomeTestLinearStates(8)
|
||||||
services.fillWithSomeTestLinearStates(2)
|
services.fillWithSomeTestLinearStates(2)
|
||||||
}
|
}
|
||||||
val persistentStateRefs = issuedStates.states.map { PersistentStateRef(it.ref) }.toList()
|
val persistentStateRefs = issuedStates.states.map { PersistentStateRef(it.ref) }.toList()
|
||||||
|
|
||||||
// structure query
|
// structure query
|
||||||
@ -383,7 +384,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
|
|
||||||
// aggregate function
|
// aggregate function
|
||||||
criteriaQuery.multiselect(cashStates.get<String>("currency"),
|
criteriaQuery.multiselect(cashStates.get<String>("currency"),
|
||||||
criteriaBuilder.sum(cashStates.get<Long>("pennies")))
|
criteriaBuilder.sum(cashStates.get<Long>("pennies")))
|
||||||
// group by
|
// group by
|
||||||
criteriaQuery.groupBy(cashStates.get<String>("currency"))
|
criteriaQuery.groupBy(cashStates.get<String>("currency"))
|
||||||
|
|
||||||
@ -627,7 +628,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
|
|
||||||
services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), ownedBy = ALICE)
|
services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), ownedBy = ALICE)
|
||||||
val cashStates = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L),
|
val cashStates = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L),
|
||||||
issuedBy = BOB.ref(0), ownedBy = (BOB)).states
|
issuedBy = BOB.ref(0), ownedBy = (BOB)).states
|
||||||
// persist additional cash states explicitly with V3 schema
|
// persist additional cash states explicitly with V3 schema
|
||||||
cashStates.forEach {
|
cashStates.forEach {
|
||||||
val cashState = it.state.data
|
val cashState = it.state.data
|
||||||
@ -662,7 +663,8 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
queryResults.forEach {
|
queryResults.forEach {
|
||||||
val contractState = it.contractState.deserialize<TransactionState<ContractState>>(context = SerializationDefaults.STORAGE_CONTEXT)
|
val contractState = it.contractState.deserialize<TransactionState<ContractState>>(context = SerializationDefaults.STORAGE_CONTEXT)
|
||||||
val cashState = contractState.data as Cash.State
|
val cashState = contractState.data as Cash.State
|
||||||
println("${it.stateRef} with owner: ${cashState.owner.owningKey.toBase58String()}") }
|
println("${it.stateRef} with owner: ${cashState.owner.owningKey.toBase58String()}")
|
||||||
|
}
|
||||||
|
|
||||||
assertThat(queryResults).hasSize(12)
|
assertThat(queryResults).hasSize(12)
|
||||||
}
|
}
|
||||||
@ -697,32 +699,32 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
@Test
|
@Test
|
||||||
fun `query fungible states by participants`() {
|
fun `query fungible states by participants`() {
|
||||||
val firstCashState =
|
val firstCashState =
|
||||||
database.transaction {
|
database.transaction {
|
||||||
// persist original cash states explicitly with V3 schema
|
// persist original cash states explicitly with V3 schema
|
||||||
cashStates.forEach {
|
cashStates.forEach {
|
||||||
val cashState = it.state.data
|
val cashState = it.state.data
|
||||||
val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner)
|
val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner)
|
||||||
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
||||||
}
|
}
|
||||||
|
|
||||||
val moreCash = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L),
|
val moreCash = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L),
|
||||||
issuedBy = BOB.ref(0), ownedBy = BOB).states
|
issuedBy = BOB.ref(0), ownedBy = BOB).states
|
||||||
// persist additional cash states explicitly with V3 schema
|
// persist additional cash states explicitly with V3 schema
|
||||||
moreCash.forEach {
|
moreCash.forEach {
|
||||||
val cashState = it.state.data
|
val cashState = it.state.data
|
||||||
val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner)
|
val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner)
|
||||||
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cashStates = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), ownedBy = (ALICE)).states
|
val cashStates = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), ownedBy = (ALICE)).states
|
||||||
// persist additional cash states explicitly with V3 schema
|
// persist additional cash states explicitly with V3 schema
|
||||||
cashStates.forEach {
|
cashStates.forEach {
|
||||||
val cashState = it.state.data
|
val cashState = it.state.data
|
||||||
val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner)
|
val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner)
|
||||||
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
||||||
|
}
|
||||||
|
cashStates.first()
|
||||||
}
|
}
|
||||||
cashStates.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
// structure query
|
// structure query
|
||||||
val criteriaQuery = criteriaBuilder.createQuery(VaultSchemaV1.VaultStates::class.java)
|
val criteriaQuery = criteriaBuilder.createQuery(VaultSchemaV1.VaultStates::class.java)
|
||||||
@ -874,7 +876,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
val jdbcSession = services.jdbcSession()
|
val jdbcSession = services.jdbcSession()
|
||||||
val prepStatement = jdbcSession.prepareStatement(nativeQuery)
|
val prepStatement = jdbcSession.prepareStatement(nativeQuery)
|
||||||
val rs = prepStatement.executeQuery()
|
val rs = prepStatement.executeQuery()
|
||||||
// DOCEND JdbcSession
|
// DOCEND JdbcSession
|
||||||
var count = 0
|
var count = 0
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
val stateRef = StateRef(SecureHash.parse(rs.getString(1)), rs.getInt(2))
|
val stateRef = StateRef(SecureHash.parse(rs.getString(1)), rs.getInt(2))
|
||||||
|
@ -99,18 +99,18 @@ class NodeAttachmentStorageTest {
|
|||||||
fun `corrupt entry throws exception`() {
|
fun `corrupt entry throws exception`() {
|
||||||
val testJar = makeTestJar()
|
val testJar = makeTestJar()
|
||||||
val id =
|
val id =
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val storage = NodeAttachmentService(MetricRegistry())
|
val storage = NodeAttachmentService(MetricRegistry())
|
||||||
val id = testJar.read { storage.importAttachment(it) }
|
val id = testJar.read { storage.importAttachment(it) }
|
||||||
|
|
||||||
// Corrupt the file in the store.
|
// Corrupt the file in the store.
|
||||||
val bytes = testJar.readAll()
|
val bytes = testJar.readAll()
|
||||||
val corruptBytes = "arggghhhh".toByteArray()
|
val corruptBytes = "arggghhhh".toByteArray()
|
||||||
System.arraycopy(corruptBytes, 0, bytes, 0, corruptBytes.size)
|
System.arraycopy(corruptBytes, 0, bytes, 0, corruptBytes.size)
|
||||||
val corruptAttachment = NodeAttachmentService.DBAttachment(attId = id.toString(), content = bytes)
|
val corruptAttachment = NodeAttachmentService.DBAttachment(attId = id.toString(), content = bytes)
|
||||||
DatabaseTransactionManager.current().session.merge(corruptAttachment)
|
DatabaseTransactionManager.current().session.merge(corruptAttachment)
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val storage = NodeAttachmentService(MetricRegistry())
|
val storage = NodeAttachmentService(MetricRegistry())
|
||||||
val e = assertFailsWith<NodeAttachmentService.HashMismatchException> {
|
val e = assertFailsWith<NodeAttachmentService.HashMismatchException> {
|
||||||
|
@ -41,7 +41,7 @@ class NodeSchemaServiceTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun `auto scanning of custom schemas for testing with Driver`() {
|
fun `auto scanning of custom schemas for testing with Driver`() {
|
||||||
driver (startNodesInProcess = true) {
|
driver(startNodesInProcess = true) {
|
||||||
val node = startNode()
|
val node = startNode()
|
||||||
val nodeHandle = node.getOrThrow()
|
val nodeHandle = node.getOrThrow()
|
||||||
val result = nodeHandle.rpc.startFlow(::MappedSchemasFlow)
|
val result = nodeHandle.rpc.startFlow(::MappedSchemasFlow)
|
||||||
@ -53,7 +53,7 @@ class NodeSchemaServiceTest {
|
|||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
class MappedSchemasFlow : FlowLogic<List<String>>() {
|
class MappedSchemasFlow : FlowLogic<List<String>>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() : List<String> {
|
override fun call(): List<String> {
|
||||||
// returning MappedSchema's as String'ified family names to avoid whitelist serialization errors
|
// returning MappedSchema's as String'ified family names to avoid whitelist serialization errors
|
||||||
return (this.serviceHub as ServiceHubInternal).schemaService.schemaOptions.keys.map { it.name }
|
return (this.serviceHub as ServiceHubInternal).schemaService.schemaOptions.keys.map { it.name }
|
||||||
}
|
}
|
||||||
|
@ -702,8 +702,7 @@ class FlowFrameworkTests {
|
|||||||
private inline fun <reified P : FlowLogic<*>> StartedNode<*>.registerFlowFactory(
|
private inline fun <reified P : FlowLogic<*>> StartedNode<*>.registerFlowFactory(
|
||||||
initiatingFlowClass: KClass<out FlowLogic<*>>,
|
initiatingFlowClass: KClass<out FlowLogic<*>>,
|
||||||
initiatedFlowVersion: Int = 1,
|
initiatedFlowVersion: Int = 1,
|
||||||
noinline flowFactory: (FlowSession) -> P): CordaFuture<P>
|
noinline flowFactory: (FlowSession) -> P): CordaFuture<P> {
|
||||||
{
|
|
||||||
val observable = internals.internalRegisterFlowFactory(
|
val observable = internals.internalRegisterFlowFactory(
|
||||||
initiatingFlowClass.java,
|
initiatingFlowClass.java,
|
||||||
InitiatedFlowFactory.CorDapp(initiatedFlowVersion, "", flowFactory),
|
InitiatedFlowFactory.CorDapp(initiatedFlowVersion, "", flowFactory),
|
||||||
@ -715,6 +714,7 @@ class FlowFrameworkTests {
|
|||||||
private fun sessionInit(clientFlowClass: KClass<out FlowLogic<*>>, flowVersion: Int = 1, payload: Any? = null): SessionInit {
|
private fun sessionInit(clientFlowClass: KClass<out FlowLogic<*>>, flowVersion: Int = 1, payload: Any? = null): SessionInit {
|
||||||
return SessionInit(0, clientFlowClass.java.name, flowVersion, "", payload)
|
return SessionInit(0, clientFlowClass.java.name, flowVersion, "", payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sessionConfirm(flowVersion: Int = 1) = SessionConfirm(0, 0, flowVersion, "")
|
private fun sessionConfirm(flowVersion: Int = 1) = SessionConfirm(0, 0, flowVersion, "")
|
||||||
private fun sessionData(payload: Any) = SessionData(0, payload)
|
private fun sessionData(payload: Any) = SessionData(0, payload)
|
||||||
private val normalEnd = NormalSessionEnd(0)
|
private val normalEnd = NormalSessionEnd(0)
|
||||||
@ -766,14 +766,15 @@ class FlowFrameworkTests {
|
|||||||
private infix fun StartedNode<MockNode>.sent(message: SessionMessage): Pair<Int, SessionMessage> = Pair(internals.id, message)
|
private infix fun StartedNode<MockNode>.sent(message: SessionMessage): Pair<Int, SessionMessage> = Pair(internals.id, message)
|
||||||
private infix fun Pair<Int, SessionMessage>.to(node: StartedNode<*>): SessionTransfer = SessionTransfer(first, second, node.network.myAddress)
|
private infix fun Pair<Int, SessionMessage>.to(node: StartedNode<*>): SessionTransfer = SessionTransfer(first, second, node.network.myAddress)
|
||||||
|
|
||||||
private val FlowLogic<*>.progressSteps: CordaFuture<List<Notification<ProgressTracker.Step>>> get() {
|
private val FlowLogic<*>.progressSteps: CordaFuture<List<Notification<ProgressTracker.Step>>>
|
||||||
return progressTracker!!.changes
|
get() {
|
||||||
.ofType(Change.Position::class.java)
|
return progressTracker!!.changes
|
||||||
.map { it.newStep }
|
.ofType(Change.Position::class.java)
|
||||||
.materialize()
|
.map { it.newStep }
|
||||||
.toList()
|
.materialize()
|
||||||
.toFuture()
|
.toList()
|
||||||
}
|
.toFuture()
|
||||||
|
}
|
||||||
|
|
||||||
private class LazyServiceHubAccessFlow : FlowLogic<Unit>() {
|
private class LazyServiceHubAccessFlow : FlowLogic<Unit>() {
|
||||||
val lazyTime: Instant by lazy { serviceHub.clock.instant() }
|
val lazyTime: Instant by lazy { serviceHub.clock.instant() }
|
||||||
@ -782,7 +783,8 @@ class FlowFrameworkTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class NoOpFlow(val nonTerminating: Boolean = false) : FlowLogic<Unit>() {
|
private class NoOpFlow(val nonTerminating: Boolean = false) : FlowLogic<Unit>() {
|
||||||
@Transient var flowStarted = false
|
@Transient
|
||||||
|
var flowStarted = false
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
@ -833,7 +835,8 @@ class FlowFrameworkTests {
|
|||||||
|
|
||||||
override val progressTracker: ProgressTracker = ProgressTracker(START_STEP, RECEIVED_STEP)
|
override val progressTracker: ProgressTracker = ProgressTracker(START_STEP, RECEIVED_STEP)
|
||||||
private var nonTerminating: Boolean = false
|
private var nonTerminating: Boolean = false
|
||||||
@Transient var receivedPayloads: List<String> = emptyList()
|
@Transient
|
||||||
|
var receivedPayloads: List<String> = emptyList()
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
@ -879,6 +882,7 @@ class FlowFrameworkTests {
|
|||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
private class SendAndReceiveFlow(val otherParty: Party, val payload: Any, val otherPartySession: FlowSession? = null) : FlowLogic<Any>() {
|
private class SendAndReceiveFlow(val otherParty: Party, val payload: Any, val otherPartySession: FlowSession? = null) : FlowLogic<Any>() {
|
||||||
constructor(otherPartySession: FlowSession, payload: Any) : this(otherPartySession.counterparty, payload, otherPartySession)
|
constructor(otherPartySession: FlowSession, payload: Any) : this(otherPartySession.counterparty, payload, otherPartySession)
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): Any = (otherPartySession ?: initiateFlow(otherParty)).sendAndReceive<Any>(payload).unwrap { it }
|
override fun call(): Any = (otherPartySession ?: initiateFlow(otherParty)).sendAndReceive<Any>(payload).unwrap { it }
|
||||||
}
|
}
|
||||||
@ -891,8 +895,11 @@ class FlowFrameworkTests {
|
|||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
private class PingPongFlow(val otherParty: Party, val payload: Long, val otherPartySession: FlowSession? = null) : FlowLogic<Unit>() {
|
private class PingPongFlow(val otherParty: Party, val payload: Long, val otherPartySession: FlowSession? = null) : FlowLogic<Unit>() {
|
||||||
constructor(otherPartySession: FlowSession, payload: Long) : this(otherPartySession.counterparty, payload, otherPartySession)
|
constructor(otherPartySession: FlowSession, payload: Long) : this(otherPartySession.counterparty, payload, otherPartySession)
|
||||||
@Transient var receivedPayload: Long? = null
|
|
||||||
@Transient var receivedPayload2: Long? = null
|
@Transient
|
||||||
|
var receivedPayload: Long? = null
|
||||||
|
@Transient
|
||||||
|
var receivedPayload2: Long? = null
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
@ -959,6 +966,7 @@ class FlowFrameworkTests {
|
|||||||
@InitiatingFlow(version = 2)
|
@InitiatingFlow(version = 2)
|
||||||
private class UpgradedFlow(val otherParty: Party, val otherPartySession: FlowSession? = null) : FlowLogic<Pair<Any, Int>>() {
|
private class UpgradedFlow(val otherParty: Party, val otherPartySession: FlowSession? = null) : FlowLogic<Pair<Any, Int>>() {
|
||||||
constructor(otherPartySession: FlowSession) : this(otherPartySession.counterparty, otherPartySession)
|
constructor(otherPartySession: FlowSession) : this(otherPartySession.counterparty, otherPartySession)
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): Pair<Any, Int> {
|
override fun call(): Pair<Any, Int> {
|
||||||
val otherPartySession = this.otherPartySession ?: initiateFlow(otherParty)
|
val otherPartySession = this.otherPartySession ?: initiateFlow(otherParty)
|
||||||
|
@ -32,7 +32,8 @@ class PersistentUniquenessProviderTests : TestDependencyInjectionBase() {
|
|||||||
LogHelper.reset(PersistentUniquenessProvider::class)
|
LogHelper.reset(PersistentUniquenessProvider::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `should commit a transaction with unused inputs without exception`() {
|
@Test
|
||||||
|
fun `should commit a transaction with unused inputs without exception`() {
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val provider = PersistentUniquenessProvider()
|
val provider = PersistentUniquenessProvider()
|
||||||
val inputState = generateStateRef()
|
val inputState = generateStateRef()
|
||||||
@ -41,7 +42,8 @@ class PersistentUniquenessProviderTests : TestDependencyInjectionBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `should report a conflict for a transaction with previously used inputs`() {
|
@Test
|
||||||
|
fun `should report a conflict for a transaction with previously used inputs`() {
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val provider = PersistentUniquenessProvider()
|
val provider = PersistentUniquenessProvider()
|
||||||
val inputState = generateStateRef()
|
val inputState = generateStateRef()
|
||||||
|
@ -55,7 +55,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
|||||||
setCordappPackages("net.corda.finance.contracts.asset")
|
setCordappPackages("net.corda.finance.contracts.asset")
|
||||||
LogHelper.setLevel(NodeVaultService::class)
|
LogHelper.setLevel(NodeVaultService::class)
|
||||||
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(BOC_KEY, DUMMY_CASH_ISSUER_KEY),
|
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(BOC_KEY, DUMMY_CASH_ISSUER_KEY),
|
||||||
customSchemas = setOf(CashSchemaV1))
|
customSchemas = setOf(CashSchemaV1))
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, BOC_KEY)
|
issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, BOC_KEY)
|
||||||
@ -195,7 +195,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
|||||||
assertThat(vaultService.queryBy<Cash.State>(criteriaByLockId1).states).hasSize(3)
|
assertThat(vaultService.queryBy<Cash.State>(criteriaByLockId1).states).hasSize(3)
|
||||||
}
|
}
|
||||||
println("SOFT LOCK STATES #1 succeeded")
|
println("SOFT LOCK STATES #1 succeeded")
|
||||||
} catch(e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
println("SOFT LOCK STATES #1 failed")
|
println("SOFT LOCK STATES #1 failed")
|
||||||
} finally {
|
} finally {
|
||||||
countDown.countDown()
|
countDown.countDown()
|
||||||
@ -211,7 +211,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
|||||||
assertThat(vaultService.queryBy<Cash.State>(criteriaByLockId2).states).hasSize(3)
|
assertThat(vaultService.queryBy<Cash.State>(criteriaByLockId2).states).hasSize(3)
|
||||||
}
|
}
|
||||||
println("SOFT LOCK STATES #2 succeeded")
|
println("SOFT LOCK STATES #2 succeeded")
|
||||||
} catch(e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
println("SOFT LOCK STATES #2 failed")
|
println("SOFT LOCK STATES #2 failed")
|
||||||
} finally {
|
} finally {
|
||||||
countDown.countDown()
|
countDown.countDown()
|
||||||
|
@ -65,8 +65,8 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
|||||||
identitySvc.verifyAndRegisterIdentity(CASH_NOTARY_IDENTITY)
|
identitySvc.verifyAndRegisterIdentity(CASH_NOTARY_IDENTITY)
|
||||||
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
|
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
|
||||||
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY),
|
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY),
|
||||||
createIdentityService = { identitySvc },
|
createIdentityService = { identitySvc },
|
||||||
customSchemas = setOf(CashSchemaV1, CommercialPaperSchemaV1, DummyLinearStateSchemaV1))
|
customSchemas = setOf(CashSchemaV1, CommercialPaperSchemaV1, DummyLinearStateSchemaV1))
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY)
|
notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY)
|
||||||
@ -1064,7 +1064,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
|||||||
}
|
}
|
||||||
database.transaction {
|
database.transaction {
|
||||||
@Suppress("EXPECTED_CONDITION")
|
@Suppress("EXPECTED_CONDITION")
|
||||||
val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, @Suppress("INTEGER_OVERFLOW")MAX_PAGE_SIZE + 1) // overflow = -2147483648
|
val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, @Suppress("INTEGER_OVERFLOW") MAX_PAGE_SIZE + 1) // overflow = -2147483648
|
||||||
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
|
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
|
||||||
vaultService.queryBy<ContractState>(criteria, paging = pagingSpec)
|
vaultService.queryBy<ContractState>(criteria, paging = pagingSpec)
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
|||||||
|
|
||||||
LogHelper.setLevel(VaultWithCashTest::class)
|
LogHelper.setLevel(VaultWithCashTest::class)
|
||||||
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(DUMMY_CASH_ISSUER_KEY, DUMMY_NOTARY_KEY),
|
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(DUMMY_CASH_ISSUER_KEY, DUMMY_NOTARY_KEY),
|
||||||
customSchemas = setOf(CashSchemaV1))
|
customSchemas = setOf(CashSchemaV1))
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY)
|
issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY)
|
||||||
@ -85,24 +85,24 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
|||||||
val freshKey = services.keyManagementService.freshKey()
|
val freshKey = services.keyManagementService.freshKey()
|
||||||
|
|
||||||
val usefulTX =
|
val usefulTX =
|
||||||
database.transaction {
|
database.transaction {
|
||||||
// A tx that sends us money.
|
// A tx that sends us money.
|
||||||
val usefulBuilder = TransactionBuilder(null)
|
val usefulBuilder = TransactionBuilder(null)
|
||||||
Cash().generateIssue(usefulBuilder, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
|
Cash().generateIssue(usefulBuilder, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
|
||||||
megaCorpServices.signInitialTransaction(usefulBuilder)
|
megaCorpServices.signInitialTransaction(usefulBuilder)
|
||||||
}
|
}
|
||||||
database.transaction {
|
database.transaction {
|
||||||
assertEquals(0.DOLLARS, services.getCashBalance(USD))
|
assertEquals(0.DOLLARS, services.getCashBalance(USD))
|
||||||
services.recordTransactions(usefulTX)
|
services.recordTransactions(usefulTX)
|
||||||
}
|
}
|
||||||
val spendTX =
|
val spendTX =
|
||||||
database.transaction {
|
database.transaction {
|
||||||
// A tx that spends our money.
|
// A tx that spends our money.
|
||||||
val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY)
|
val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY)
|
||||||
Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, BOB)
|
Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, BOB)
|
||||||
val spendPTX = services.signInitialTransaction(spendTXBuilder, freshKey)
|
val spendPTX = services.signInitialTransaction(spendTXBuilder, freshKey)
|
||||||
notaryServices.addSignature(spendPTX)
|
notaryServices.addSignature(spendPTX)
|
||||||
}
|
}
|
||||||
database.transaction {
|
database.transaction {
|
||||||
assertEquals(100.DOLLARS, services.getCashBalance(USD))
|
assertEquals(100.DOLLARS, services.getCashBalance(USD))
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
|||||||
LOCKED: ${lockedStates2.count()} : $lockedStates2
|
LOCKED: ${lockedStates2.count()} : $lockedStates2
|
||||||
""")
|
""")
|
||||||
txn1
|
txn1
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(e)
|
println(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
|||||||
LOCKED: ${lockedStates2.count()} : $lockedStates2
|
LOCKED: ${lockedStates2.count()} : $lockedStates2
|
||||||
""")
|
""")
|
||||||
txn2
|
txn2
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(e)
|
println(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,18 +254,19 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
|||||||
val linearId = UniqueIdentifier()
|
val linearId = UniqueIdentifier()
|
||||||
|
|
||||||
val dummyIssue =
|
val dummyIssue =
|
||||||
database.transaction { // Issue a linear state
|
database.transaction {
|
||||||
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
|
// Issue a linear state
|
||||||
.addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
|
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
|
||||||
.addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
|
.addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
|
||||||
val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder)
|
.addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
|
||||||
val dummyIssue = services.addSignature(dummyIssuePtx)
|
val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder)
|
||||||
|
val dummyIssue = services.addSignature(dummyIssuePtx)
|
||||||
|
|
||||||
dummyIssue.toLedgerTransaction(services).verify()
|
dummyIssue.toLedgerTransaction(services).verify()
|
||||||
|
|
||||||
services.recordTransactions(dummyIssue)
|
services.recordTransactions(dummyIssue)
|
||||||
dummyIssue
|
dummyIssue
|
||||||
}
|
}
|
||||||
database.transaction {
|
database.transaction {
|
||||||
assertThat(vaultService.queryBy<DummyLinearContract.State>().states).hasSize(1)
|
assertThat(vaultService.queryBy<DummyLinearContract.State>().states).hasSize(1)
|
||||||
|
|
||||||
@ -333,9 +334,9 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
|||||||
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
|
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
|
||||||
}
|
}
|
||||||
val deals =
|
val deals =
|
||||||
database.transaction {
|
database.transaction {
|
||||||
vaultService.queryBy<DummyDealContract.State>().states
|
vaultService.queryBy<DummyDealContract.State>().states
|
||||||
}
|
}
|
||||||
database.transaction {
|
database.transaction {
|
||||||
services.fillWithSomeTestLinearStates(3)
|
services.fillWithSomeTestLinearStates(3)
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,14 @@ class AffinityExecutorTests {
|
|||||||
var _executor: AffinityExecutor.ServiceAffinityExecutor? = null
|
var _executor: AffinityExecutor.ServiceAffinityExecutor? = null
|
||||||
val executor: AffinityExecutor.ServiceAffinityExecutor get() = _executor!!
|
val executor: AffinityExecutor.ServiceAffinityExecutor get() = _executor!!
|
||||||
|
|
||||||
@After fun shutdown() {
|
@After
|
||||||
|
fun shutdown() {
|
||||||
_executor?.shutdown()
|
_executor?.shutdown()
|
||||||
_executor = null
|
_executor = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `flush handles nested executes`() {
|
@Test
|
||||||
|
fun `flush handles nested executes`() {
|
||||||
_executor = AffinityExecutor.ServiceAffinityExecutor("test4", 1)
|
_executor = AffinityExecutor.ServiceAffinityExecutor("test4", 1)
|
||||||
var nestedRan = false
|
var nestedRan = false
|
||||||
val latch = CountDownLatch(1)
|
val latch = CountDownLatch(1)
|
||||||
@ -29,7 +31,8 @@ class AffinityExecutorTests {
|
|||||||
assertTrue(nestedRan)
|
assertTrue(nestedRan)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `single threaded affinity executor runs on correct thread`() {
|
@Test
|
||||||
|
fun `single threaded affinity executor runs on correct thread`() {
|
||||||
val thisThread = Thread.currentThread()
|
val thisThread = Thread.currentThread()
|
||||||
_executor = AffinityExecutor.ServiceAffinityExecutor("test thread", 1)
|
_executor = AffinityExecutor.ServiceAffinityExecutor("test thread", 1)
|
||||||
assertTrue(!executor.isOnThread)
|
assertTrue(!executor.isOnThread)
|
||||||
@ -50,7 +53,8 @@ class AffinityExecutorTests {
|
|||||||
assertEquals(thread2.get(), thread.get())
|
assertEquals(thread2.get(), thread.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `pooled executor`() {
|
@Test
|
||||||
|
fun `pooled executor`() {
|
||||||
_executor = AffinityExecutor.ServiceAffinityExecutor("test2", 3)
|
_executor = AffinityExecutor.ServiceAffinityExecutor("test2", 3)
|
||||||
assertFalse(executor.isOnThread)
|
assertFalse(executor.isOnThread)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user