mirror of
https://github.com/corda/corda.git
synced 2025-02-04 02:01:13 +00:00
CORDA-676 Eager cordapp schemas (#1839)
* Retire customSchemas. * Key cordapp-to-hash map by url as native equality too strict.
This commit is contained in:
parent
d3d87c2497
commit
38cf4a489e
@ -32,7 +32,7 @@ import static net.corda.testing.TestConstants.getALICE;
|
|||||||
|
|
||||||
public class CordaRPCJavaClientTest extends NodeBasedTest {
|
public class CordaRPCJavaClientTest extends NodeBasedTest {
|
||||||
public CordaRPCJavaClientTest() {
|
public CordaRPCJavaClientTest() {
|
||||||
super(Collections.singletonList("net.corda.finance.contracts"));
|
super(Arrays.asList("net.corda.finance.contracts", CashSchemaV1.class.getPackage().getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> perms = Arrays.asList(startFlowPermission(CashPaymentFlow.class), startFlowPermission(CashIssueFlow.class));
|
private List<String> perms = Arrays.asList(startFlowPermission(CashPaymentFlow.class), startFlowPermission(CashIssueFlow.class));
|
||||||
@ -53,7 +53,6 @@ public class CordaRPCJavaClientTest extends NodeBasedTest {
|
|||||||
public void setUp() throws ExecutionException, InterruptedException {
|
public void setUp() throws ExecutionException, InterruptedException {
|
||||||
CordaFuture<StartedNode<Node>> nodeFuture = startNotaryNode(getALICE().getName(), singletonList(rpcUser), true);
|
CordaFuture<StartedNode<Node>> nodeFuture = startNotaryNode(getALICE().getName(), singletonList(rpcUser), true);
|
||||||
node = nodeFuture.get();
|
node = nodeFuture.get();
|
||||||
node.getInternals().registerCustomSchemas(Collections.singleton(CashSchemaV1.INSTANCE));
|
|
||||||
client = new CordaRPCClient(requireNonNull(node.getInternals().getConfiguration().getRpcAddress()));
|
client = new CordaRPCClient(requireNonNull(node.getInternals().getConfiguration().getRpcAddress()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.client.rpc
|
|||||||
|
|
||||||
import net.corda.core.crypto.random63BitValue
|
import net.corda.core.crypto.random63BitValue
|
||||||
import net.corda.core.flows.FlowInitiator
|
import net.corda.core.flows.FlowInitiator
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.messaging.FlowProgressHandle
|
import net.corda.core.messaging.FlowProgressHandle
|
||||||
import net.corda.core.messaging.StateMachineUpdate
|
import net.corda.core.messaging.StateMachineUpdate
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
@ -32,7 +33,7 @@ import kotlin.test.assertEquals
|
|||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts")) {
|
class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", CashSchemaV1::class.packageName)) {
|
||||||
private val rpcUser = User("user1", "test", permissions = setOf(
|
private val rpcUser = User("user1", "test", permissions = setOf(
|
||||||
startFlowPermission<CashIssueFlow>(),
|
startFlowPermission<CashIssueFlow>(),
|
||||||
startFlowPermission<CashPaymentFlow>()
|
startFlowPermission<CashPaymentFlow>()
|
||||||
@ -48,7 +49,6 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts"))
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
node = startNotaryNode(ALICE.name, rpcUsers = listOf(rpcUser)).getOrThrow()
|
node = startNotaryNode(ALICE.name, rpcUsers = listOf(rpcUser)).getOrThrow()
|
||||||
node.internals.registerCustomSchemas(setOf(CashSchemaV1))
|
|
||||||
client = CordaRPCClient(node.internals.configuration.rpcAddress!!)
|
client = CordaRPCClient(node.internals.configuration.rpcAddress!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,3 +300,6 @@ fun TransactionBuilder.toWireTransaction(services: ServicesForResolution, serial
|
|||||||
* @suppress
|
* @suppress
|
||||||
*/
|
*/
|
||||||
fun TransactionBuilder.toLedgerTransaction(services: ServiceHub, serializationContext: SerializationContext) = toLedgerTransactionWithContext(services, serializationContext)
|
fun TransactionBuilder.toLedgerTransaction(services: ServiceHub, serializationContext: SerializationContext) = toLedgerTransactionWithContext(services, serializationContext)
|
||||||
|
|
||||||
|
/** Convenience method to get the package name of a class literal. */
|
||||||
|
val KClass<*>.packageName get() = java.`package`.name
|
||||||
|
@ -61,6 +61,7 @@ class InternalUtilsTest {
|
|||||||
assertArrayEquals(intArrayOf(1, 2, 3, 4), (1 until 5).stream().toArray())
|
assertArrayEquals(intArrayOf(1, 2, 3, 4), (1 until 5).stream().toArray())
|
||||||
assertArrayEquals(intArrayOf(1, 3), (1..4 step 2).stream().toArray())
|
assertArrayEquals(intArrayOf(1, 3), (1..4 step 2).stream().toArray())
|
||||||
assertArrayEquals(intArrayOf(1, 3), (1..3 step 2).stream().toArray())
|
assertArrayEquals(intArrayOf(1, 3), (1..3 step 2).stream().toArray())
|
||||||
|
@Suppress("EmptyRange") // It's supposed to be empty.
|
||||||
assertArrayEquals(intArrayOf(), (1..0).stream().toArray())
|
assertArrayEquals(intArrayOf(), (1..0).stream().toArray())
|
||||||
assertArrayEquals(intArrayOf(1, 0), (1 downTo 0).stream().toArray())
|
assertArrayEquals(intArrayOf(1, 0), (1 downTo 0).stream().toArray())
|
||||||
assertArrayEquals(intArrayOf(3, 1), (3 downTo 0 step 2).stream().toArray())
|
assertArrayEquals(intArrayOf(3, 1), (3 downTo 0 step 2).stream().toArray())
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.docs
|
|||||||
|
|
||||||
import net.corda.core.contracts.Amount
|
import net.corda.core.contracts.Amount
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.finance.*
|
import net.corda.finance.*
|
||||||
@ -26,15 +27,12 @@ class CustomVaultQueryTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset", CashSchemaV1::class.packageName))
|
||||||
mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
||||||
nodeA = mockNet.createPartyNode()
|
nodeA = mockNet.createPartyNode()
|
||||||
nodeB = mockNet.createPartyNode()
|
nodeB = mockNet.createPartyNode()
|
||||||
|
|
||||||
nodeA.internals.registerInitiatedFlow(TopupIssuerFlow.TopupIssuer::class.java)
|
nodeA.internals.registerInitiatedFlow(TopupIssuerFlow.TopupIssuer::class.java)
|
||||||
nodeA.internals.installCordaService(CustomVaultQuery.Service::class.java)
|
nodeA.internals.installCordaService(CustomVaultQuery.Service::class.java)
|
||||||
nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1))
|
|
||||||
nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1))
|
|
||||||
notary = nodeA.services.getDefaultNotary()
|
notary = nodeA.services.getDefaultNotary()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.docs
|
package net.corda.docs
|
||||||
|
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.toFuture
|
import net.corda.core.toFuture
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
@ -24,12 +25,10 @@ class FxTransactionBuildTutorialTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset", CashSchemaV1::class.packageName))
|
||||||
mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
||||||
nodeA = mockNet.createPartyNode()
|
nodeA = mockNet.createPartyNode()
|
||||||
nodeB = mockNet.createPartyNode()
|
nodeB = mockNet.createPartyNode()
|
||||||
nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1))
|
|
||||||
nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1))
|
|
||||||
nodeB.internals.registerInitiatedFlow(ForeignExchangeRemoteFlow::class.java)
|
nodeB.internals.registerInitiatedFlow(ForeignExchangeRemoteFlow::class.java)
|
||||||
notary = nodeA.services.getDefaultNotary()
|
notary = nodeA.services.getDefaultNotary()
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() {
|
|||||||
|
|
||||||
class DummyServiceHub : MockServices() {
|
class DummyServiceHub : MockServices() {
|
||||||
override val cordappProvider: CordappProviderImpl
|
override val cordappProvider: CordappProviderImpl
|
||||||
= CordappProviderImpl(CordappLoader.createDevMode(listOf(ISOLATED_CONTRACTS_JAR_PATH))).start(attachments)
|
= CordappProviderImpl(CordappLoader.createDevMode(listOf(ISOLATED_CONTRACTS_JAR_PATH)), attachments)
|
||||||
|
|
||||||
private val cordapp get() = cordappProvider.cordapps.first()
|
private val cordapp get() = cordappProvider.cordapps.first()
|
||||||
val attachmentId get() = cordappProvider.getCordappAttachmentId(cordapp)!!
|
val attachmentId get() = cordappProvider.getCordappAttachmentId(cordapp)!!
|
||||||
val appContext get() = cordappProvider.getAppContext(cordapp)
|
val appContext get() = cordappProvider.getAppContext(cordapp)
|
||||||
|
@ -37,7 +37,7 @@ import kotlin.test.assertFailsWith
|
|||||||
|
|
||||||
class AttachmentLoadingTests : TestDependencyInjectionBase() {
|
class AttachmentLoadingTests : TestDependencyInjectionBase() {
|
||||||
private class Services : MockServices() {
|
private class Services : MockServices() {
|
||||||
private val provider = CordappProviderImpl(CordappLoader.createDevMode(listOf(isolatedJAR))).start(attachments)
|
private val provider = CordappProviderImpl(CordappLoader.createDevMode(listOf(isolatedJAR)), attachments)
|
||||||
private val cordapp get() = provider.cordapps.first()
|
private val cordapp get() = provider.cordapps.first()
|
||||||
val attachmentId get() = provider.getCordappAttachmentId(cordapp)!!
|
val attachmentId get() = provider.getCordappAttachmentId(cordapp)!!
|
||||||
val appContext get() = provider.getAppContext(cordapp)
|
val appContext get() = provider.getAppContext(cordapp)
|
||||||
|
@ -7,7 +7,6 @@ import net.corda.confidential.SwapIdentitiesFlow
|
|||||||
import net.corda.confidential.SwapIdentitiesHandler
|
import net.corda.confidential.SwapIdentitiesHandler
|
||||||
import net.corda.core.CordaException
|
import net.corda.core.CordaException
|
||||||
import net.corda.core.concurrent.CordaFuture
|
import net.corda.core.concurrent.CordaFuture
|
||||||
import net.corda.core.cordapp.CordappProvider
|
|
||||||
import net.corda.core.flows.*
|
import net.corda.core.flows.*
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
@ -26,7 +25,6 @@ import net.corda.core.node.ServiceHub
|
|||||||
import net.corda.core.node.StateLoader
|
import net.corda.core.node.StateLoader
|
||||||
import net.corda.core.node.services.*
|
import net.corda.core.node.services.*
|
||||||
import net.corda.core.node.services.NetworkMapCache.MapChange
|
import net.corda.core.node.services.NetworkMapCache.MapChange
|
||||||
import net.corda.core.schemas.MappedSchema
|
|
||||||
import net.corda.core.serialization.SerializationWhitelist
|
import net.corda.core.serialization.SerializationWhitelist
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
@ -37,6 +35,7 @@ import net.corda.node.VersionInfo
|
|||||||
import net.corda.node.internal.classloading.requireAnnotation
|
import net.corda.node.internal.classloading.requireAnnotation
|
||||||
import net.corda.node.internal.cordapp.CordappLoader
|
import net.corda.node.internal.cordapp.CordappLoader
|
||||||
import net.corda.node.internal.cordapp.CordappProviderImpl
|
import net.corda.node.internal.cordapp.CordappProviderImpl
|
||||||
|
import net.corda.node.internal.cordapp.CordappProviderInternal
|
||||||
import net.corda.node.services.ContractUpgradeHandler
|
import net.corda.node.services.ContractUpgradeHandler
|
||||||
import net.corda.node.services.FinalityHandler
|
import net.corda.node.services.FinalityHandler
|
||||||
import net.corda.node.services.NotaryChangeHandler
|
import net.corda.node.services.NotaryChangeHandler
|
||||||
@ -148,7 +147,6 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
protected lateinit var network: MessagingService
|
protected lateinit var network: MessagingService
|
||||||
protected val runOnStop = ArrayList<() -> Any?>()
|
protected val runOnStop = ArrayList<() -> Any?>()
|
||||||
protected lateinit var database: CordaPersistence
|
protected lateinit var database: CordaPersistence
|
||||||
lateinit var cordappProvider: CordappProviderImpl
|
|
||||||
protected val _nodeReadyFuture = openFuture<Unit>()
|
protected val _nodeReadyFuture = openFuture<Unit>()
|
||||||
/** Completes once the node has successfully registered with the network map service
|
/** Completes once the node has successfully registered with the network map service
|
||||||
* or has loaded network map data from local database */
|
* or has loaded network map data from local database */
|
||||||
@ -161,7 +159,7 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
open val serializationWhitelists: List<SerializationWhitelist> by lazy {
|
open val serializationWhitelists: List<SerializationWhitelist> by lazy {
|
||||||
cordappProvider.cordapps.flatMap { it.serializationWhitelists }
|
cordappLoader.cordapps.flatMap { it.serializationWhitelists }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set to non-null once [start] has been successfully called. */
|
/** Set to non-null once [start] has been successfully called. */
|
||||||
@ -185,11 +183,12 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
validateKeystore()
|
validateKeystore()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun makeSchemaService() = NodeSchemaService(cordappLoader)
|
||||||
open fun generateNodeInfo() {
|
open fun generateNodeInfo() {
|
||||||
check(started == null) { "Node has already been started" }
|
check(started == null) { "Node has already been started" }
|
||||||
initCertificate()
|
initCertificate()
|
||||||
log.info("Generating nodeInfo ...")
|
log.info("Generating nodeInfo ...")
|
||||||
val schemaService = NodeSchemaService()
|
val schemaService = makeSchemaService()
|
||||||
initialiseDatabasePersistence(schemaService) {
|
initialiseDatabasePersistence(schemaService) {
|
||||||
makeServices(schemaService)
|
makeServices(schemaService)
|
||||||
saveOwnNodeInfo()
|
saveOwnNodeInfo()
|
||||||
@ -200,7 +199,7 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
check(started == null) { "Node has already been started" }
|
check(started == null) { "Node has already been started" }
|
||||||
initCertificate()
|
initCertificate()
|
||||||
log.info("Node starting up ...")
|
log.info("Node starting up ...")
|
||||||
val schemaService = NodeSchemaService()
|
val schemaService = makeSchemaService()
|
||||||
// Do all of this in a database transaction so anything that might need a connection has one.
|
// Do all of this in a database transaction so anything that might need a connection has one.
|
||||||
val startedImpl = initialiseDatabasePersistence(schemaService) {
|
val startedImpl = initialiseDatabasePersistence(schemaService) {
|
||||||
val tokenizableServices = makeServices(schemaService)
|
val tokenizableServices = makeServices(schemaService)
|
||||||
@ -231,8 +230,7 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
|
|
||||||
installCordaServices()
|
installCordaServices()
|
||||||
registerCordappFlows()
|
registerCordappFlows()
|
||||||
_services.rpcFlows += cordappProvider.cordapps.flatMap { it.rpcFlows }
|
_services.rpcFlows += cordappLoader.cordapps.flatMap { it.rpcFlows }
|
||||||
registerCustomSchemas(cordappProvider.cordapps.flatMap { it.customSchemas }.toSet())
|
|
||||||
FlowLogicRefFactoryImpl.classloader = cordappLoader.appClassLoader
|
FlowLogicRefFactoryImpl.classloader = cordappLoader.appClassLoader
|
||||||
|
|
||||||
runOnStop += network::stop
|
runOnStop += network::stop
|
||||||
@ -254,7 +252,7 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
private class ServiceInstantiationException(cause: Throwable?) : CordaException("Service Instantiation Error", cause)
|
private class ServiceInstantiationException(cause: Throwable?) : CordaException("Service Instantiation Error", cause)
|
||||||
|
|
||||||
private fun installCordaServices() {
|
private fun installCordaServices() {
|
||||||
val loadedServices = cordappProvider.cordapps.flatMap { it.services }
|
val loadedServices = cordappLoader.cordapps.flatMap { it.services }
|
||||||
filterServicesToInstall(loadedServices).forEach {
|
filterServicesToInstall(loadedServices).forEach {
|
||||||
try {
|
try {
|
||||||
installCordaService(it)
|
installCordaService(it)
|
||||||
@ -374,7 +372,7 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerCordappFlows() {
|
private fun registerCordappFlows() {
|
||||||
cordappProvider.cordapps.flatMap { it.initiatedFlows }
|
cordappLoader.cordapps.flatMap { it.initiatedFlows }
|
||||||
.forEach {
|
.forEach {
|
||||||
try {
|
try {
|
||||||
registerInitiatedFlowInternal(it, track = false)
|
registerInitiatedFlowInternal(it, track = false)
|
||||||
@ -471,11 +469,11 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
*/
|
*/
|
||||||
private fun makeServices(schemaService: SchemaService): MutableList<Any> {
|
private fun makeServices(schemaService: SchemaService): MutableList<Any> {
|
||||||
checkpointStorage = DBCheckpointStorage()
|
checkpointStorage = DBCheckpointStorage()
|
||||||
cordappProvider = CordappProviderImpl(cordappLoader)
|
|
||||||
val transactionStorage = makeTransactionStorage()
|
val transactionStorage = makeTransactionStorage()
|
||||||
_services = ServiceHubInternalImpl(schemaService, transactionStorage, StateLoaderImpl(transactionStorage))
|
val metrics = MetricRegistry()
|
||||||
attachments = NodeAttachmentService(services.monitoringService.metrics)
|
attachments = NodeAttachmentService(metrics)
|
||||||
cordappProvider.start(attachments)
|
val cordappProvider = CordappProviderImpl(cordappLoader, attachments)
|
||||||
|
_services = ServiceHubInternalImpl(schemaService, transactionStorage, StateLoaderImpl(transactionStorage), MonitoringService(metrics), cordappProvider)
|
||||||
legalIdentity = obtainIdentity(notaryConfig = null)
|
legalIdentity = obtainIdentity(notaryConfig = null)
|
||||||
network = makeMessagingService(legalIdentity)
|
network = makeMessagingService(legalIdentity)
|
||||||
info = makeInfo(legalIdentity)
|
info = makeInfo(legalIdentity)
|
||||||
@ -541,7 +539,7 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
protected open fun <T> initialiseDatabasePersistence(schemaService: SchemaService, insideTransaction: () -> T): T {
|
protected open fun <T> initialiseDatabasePersistence(schemaService: SchemaService, insideTransaction: () -> T): T {
|
||||||
val props = configuration.dataSourceProperties
|
val props = configuration.dataSourceProperties
|
||||||
if (props.isNotEmpty()) {
|
if (props.isNotEmpty()) {
|
||||||
this.database = configureDatabase(props, configuration.database, schemaService, { _services.identityService })
|
this.database = configureDatabase(props, configuration.database, { _services.identityService }, schemaService)
|
||||||
// Now log the vendor string as this will also cause a connection to be tested eagerly.
|
// Now log the vendor string as this will also cause a connection to be tested eagerly.
|
||||||
database.transaction {
|
database.transaction {
|
||||||
log.info("Connected to ${database.dataSource.connection.metaData.databaseProductName} database.")
|
log.info("Connected to ${database.dataSource.connection.metaData.databaseProductName} database.")
|
||||||
@ -764,12 +762,13 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
private inner class ServiceHubInternalImpl(
|
private inner class ServiceHubInternalImpl(
|
||||||
override val schemaService: SchemaService,
|
override val schemaService: SchemaService,
|
||||||
override val validatedTransactions: WritableTransactionStorage,
|
override val validatedTransactions: WritableTransactionStorage,
|
||||||
private val stateLoader: StateLoader
|
private val stateLoader: StateLoader,
|
||||||
|
override val monitoringService: MonitoringService,
|
||||||
|
override val cordappProvider: CordappProviderInternal
|
||||||
) : SingletonSerializeAsToken(), ServiceHubInternal, StateLoader by stateLoader {
|
) : SingletonSerializeAsToken(), ServiceHubInternal, StateLoader by stateLoader {
|
||||||
override val rpcFlows = ArrayList<Class<out FlowLogic<*>>>()
|
override val rpcFlows = ArrayList<Class<out FlowLogic<*>>>()
|
||||||
override val stateMachineRecordedTransactionMapping = DBTransactionMappingStorage()
|
override val stateMachineRecordedTransactionMapping = DBTransactionMappingStorage()
|
||||||
override val auditService = DummyAuditService()
|
override val auditService = DummyAuditService()
|
||||||
override val monitoringService = MonitoringService(MetricRegistry())
|
|
||||||
override val transactionVerifierService by lazy { makeTransactionVerifierService() }
|
override val transactionVerifierService by lazy { makeTransactionVerifierService() }
|
||||||
override val networkMapCache by lazy { PersistentNetworkMapCache(this) }
|
override val networkMapCache by lazy { PersistentNetworkMapCache(this) }
|
||||||
override val vaultService by lazy { NodeVaultService(platformClock, keyManagementService, stateLoader, this@AbstractNode.database.hibernateConfig) }
|
override val vaultService by lazy { NodeVaultService(platformClock, keyManagementService, stateLoader, this@AbstractNode.database.hibernateConfig) }
|
||||||
@ -794,8 +793,6 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
override val myInfo: NodeInfo get() = info
|
override val myInfo: NodeInfo get() = info
|
||||||
override val database: CordaPersistence get() = this@AbstractNode.database
|
override val database: CordaPersistence get() = this@AbstractNode.database
|
||||||
override val configuration: NodeConfiguration get() = this@AbstractNode.configuration
|
override val configuration: NodeConfiguration get() = this@AbstractNode.configuration
|
||||||
override val cordappProvider: CordappProvider = this@AbstractNode.cordappProvider
|
|
||||||
|
|
||||||
override fun <T : SerializeAsToken> cordaService(type: Class<T>): T {
|
override fun <T : SerializeAsToken> cordaService(type: Class<T>): T {
|
||||||
require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" }
|
require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" }
|
||||||
return cordappServices.getInstance(type) ?: throw IllegalArgumentException("Corda service ${type.name} does not exist")
|
return cordappServices.getInstance(type) ?: throw IllegalArgumentException("Corda service ${type.name} does not exist")
|
||||||
@ -817,9 +814,4 @@ abstract class AbstractNode(config: NodeConfiguration,
|
|||||||
|
|
||||||
override fun jdbcSession(): Connection = database.createSession()
|
override fun jdbcSession(): Connection = database.createSession()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerCustomSchemas(schemas: Set<MappedSchema>) {
|
|
||||||
database.hibernateConfig.schemaService.registerCustomSchemas(schemas)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ import kotlin.system.exitProcess
|
|||||||
*
|
*
|
||||||
* @param configuration This is typically loaded from a TypeSafe HOCON configuration file.
|
* @param configuration This is typically loaded from a TypeSafe HOCON configuration file.
|
||||||
*/
|
*/
|
||||||
open class Node(override val configuration: FullNodeConfiguration,
|
open class Node(configuration: FullNodeConfiguration,
|
||||||
versionInfo: VersionInfo,
|
versionInfo: VersionInfo,
|
||||||
val initialiseSerialization: Boolean = true,
|
val initialiseSerialization: Boolean = true,
|
||||||
cordappLoader: CordappLoader = makeCordappLoader(configuration)
|
cordappLoader: CordappLoader = makeCordappLoader(configuration)
|
||||||
@ -99,6 +99,7 @@ open class Node(override val configuration: FullNodeConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val log: Logger get() = logger
|
override val log: Logger get() = logger
|
||||||
|
override val configuration get() = super.configuration as FullNodeConfiguration // Necessary to avoid init order NPE.
|
||||||
override val networkMapAddress: NetworkMapAddress? get() = configuration.networkMapService?.address?.let(::NetworkMapAddress)
|
override val networkMapAddress: NetworkMapAddress? get() = configuration.networkMapService?.address?.let(::NetworkMapAddress)
|
||||||
override fun makeTransactionVerifierService() = (network as NodeMessagingClient).verifierService
|
override fun makeTransactionVerifierService() = (network as NodeMessagingClient).verifierService
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ open class NodeStartup(val args: Array<String>) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val startedNode = node.start()
|
val startedNode = node.start()
|
||||||
Node.printBasicNodeInfo("Loaded CorDapps", startedNode.internals.cordappProvider.cordapps.joinToString { it.name })
|
Node.printBasicNodeInfo("Loaded CorDapps", startedNode.services.cordappProvider.cordapps.joinToString { it.name })
|
||||||
startedNode.internals.nodeReadyFuture.thenMatch({
|
startedNode.internals.nodeReadyFuture.thenMatch({
|
||||||
val elapsed = (System.currentTimeMillis() - startTime) / 10 / 100.0
|
val elapsed = (System.currentTimeMillis() - startTime) / 10 / 100.0
|
||||||
val name = startedNode.info.legalIdentitiesAndCerts.first().name.organisation
|
val name = startedNode.info.legalIdentitiesAndCerts.first().name.organisation
|
||||||
|
@ -38,10 +38,10 @@ import kotlin.streams.toList
|
|||||||
*
|
*
|
||||||
* @property cordappJarPaths The classpath of cordapp JARs
|
* @property cordappJarPaths The classpath of cordapp JARs
|
||||||
*/
|
*/
|
||||||
class CordappLoader private constructor(private val cordappJarPaths: List<URL>) {
|
class CordappLoader private constructor(private val cordappJarPaths: List<RestrictedURL>) {
|
||||||
val cordapps: List<Cordapp> by lazy { loadCordapps() + coreCordapp }
|
val cordapps: List<Cordapp> by lazy { loadCordapps() + coreCordapp }
|
||||||
|
|
||||||
internal val appClassLoader: ClassLoader = URLClassLoader(cordappJarPaths.toTypedArray(), javaClass.classLoader)
|
internal val appClassLoader: ClassLoader = URLClassLoader(cordappJarPaths.stream().map { it.url }.toTypedArray(), javaClass.classLoader)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (cordappJarPaths.isEmpty()) {
|
if (cordappJarPaths.isEmpty()) {
|
||||||
@ -97,20 +97,22 @@ class CordappLoader private constructor(private val cordappJarPaths: List<URL>)
|
|||||||
* @param scanJars Uses the JAR URLs provided for classpath scanning and Cordapp detection
|
* @param scanJars Uses the JAR URLs provided for classpath scanning and Cordapp detection
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
fun createDevMode(scanJars: List<URL>) = CordappLoader(scanJars)
|
fun createDevMode(scanJars: List<URL>) = CordappLoader(scanJars.map { RestrictedURL(it, null) })
|
||||||
|
|
||||||
private fun getCordappsPath(baseDir: Path): Path = baseDir / CORDAPPS_DIR_NAME
|
private fun getCordappsPath(baseDir: Path): Path = baseDir / CORDAPPS_DIR_NAME
|
||||||
|
|
||||||
private fun createScanPackage(scanPackage: String): List<URL> {
|
private fun createScanPackage(scanPackage: String): List<RestrictedURL> {
|
||||||
val resource = scanPackage.replace('.', '/')
|
val resource = scanPackage.replace('.', '/')
|
||||||
return this::class.java.classLoader.getResources(resource)
|
return this::class.java.classLoader.getResources(resource)
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.map { path ->
|
.map { path ->
|
||||||
if (path.protocol == "jar") {
|
if (path.protocol == "jar") {
|
||||||
(path.openConnection() as JarURLConnection).jarFileURL.toURI()
|
// When running tests from gradle this may be a corda module jar, so restrict to scanPackage:
|
||||||
|
RestrictedURL((path.openConnection() as JarURLConnection).jarFileURL, scanPackage)
|
||||||
} else {
|
} else {
|
||||||
createDevCordappJar(scanPackage, path, resource)
|
// No need to restrict as createDevCordappJar has already done that:
|
||||||
}.toURL()
|
RestrictedURL(createDevCordappJar(scanPackage, path, resource).toURL(), null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
@ -143,12 +145,12 @@ class CordappLoader private constructor(private val cordappJarPaths: List<URL>)
|
|||||||
return generatedCordapps[path]!!
|
return generatedCordapps[path]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCordappsInDirectory(cordappsDir: Path): List<URL> {
|
private fun getCordappsInDirectory(cordappsDir: Path): List<RestrictedURL> {
|
||||||
return if (!cordappsDir.exists()) {
|
return if (!cordappsDir.exists()) {
|
||||||
emptyList<URL>()
|
emptyList()
|
||||||
} else {
|
} else {
|
||||||
cordappsDir.list {
|
cordappsDir.list {
|
||||||
it.filter { it.isRegularFile() && it.toString().endsWith(".jar") }.map { it.toUri().toURL() }.toList()
|
it.filter { it.isRegularFile() && it.toString().endsWith(".jar") }.map { RestrictedURL(it.toUri().toURL(), null) }.toList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,15 +189,15 @@ class CordappLoader private constructor(private val cordappJarPaths: List<URL>)
|
|||||||
findServices(scanResult),
|
findServices(scanResult),
|
||||||
findPlugins(it),
|
findPlugins(it),
|
||||||
findCustomSchemas(scanResult),
|
findCustomSchemas(scanResult),
|
||||||
it)
|
it.url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findServices(scanResult: ScanResult): List<Class<out SerializeAsToken>> {
|
private fun findServices(scanResult: RestrictedScanResult): List<Class<out SerializeAsToken>> {
|
||||||
return scanResult.getClassesWithAnnotation(SerializeAsToken::class, CordaService::class)
|
return scanResult.getClassesWithAnnotation(SerializeAsToken::class, CordaService::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findInitiatedFlows(scanResult: ScanResult): List<Class<out FlowLogic<*>>> {
|
private fun findInitiatedFlows(scanResult: RestrictedScanResult): List<Class<out FlowLogic<*>>> {
|
||||||
return scanResult.getClassesWithAnnotation(FlowLogic::class, InitiatedBy::class)
|
return scanResult.getClassesWithAnnotation(FlowLogic::class, InitiatedBy::class)
|
||||||
// First group by the initiating flow class in case there are multiple mappings
|
// First group by the initiating flow class in case there are multiple mappings
|
||||||
.groupBy { it.requireAnnotation<InitiatedBy>().value.java }
|
.groupBy { it.requireAnnotation<InitiatedBy>().value.java }
|
||||||
@ -214,35 +216,35 @@ class CordappLoader private constructor(private val cordappJarPaths: List<URL>)
|
|||||||
return Modifier.isPublic(modifiers) && !isLocalClass && !isAnonymousClass && (!isMemberClass || Modifier.isStatic(modifiers))
|
return Modifier.isPublic(modifiers) && !isLocalClass && !isAnonymousClass && (!isMemberClass || Modifier.isStatic(modifiers))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findRPCFlows(scanResult: ScanResult): List<Class<out FlowLogic<*>>> {
|
private fun findRPCFlows(scanResult: RestrictedScanResult): List<Class<out FlowLogic<*>>> {
|
||||||
return scanResult.getClassesWithAnnotation(FlowLogic::class, StartableByRPC::class).filter { it.isUserInvokable() }
|
return scanResult.getClassesWithAnnotation(FlowLogic::class, StartableByRPC::class).filter { it.isUserInvokable() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findServiceFlows(scanResult: ScanResult): List<Class<out FlowLogic<*>>> {
|
private fun findServiceFlows(scanResult: RestrictedScanResult): List<Class<out FlowLogic<*>>> {
|
||||||
return scanResult.getClassesWithAnnotation(FlowLogic::class, StartableByService::class)
|
return scanResult.getClassesWithAnnotation(FlowLogic::class, StartableByService::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findSchedulableFlows(scanResult: ScanResult): List<Class<out FlowLogic<*>>> {
|
private fun findSchedulableFlows(scanResult: RestrictedScanResult): List<Class<out FlowLogic<*>>> {
|
||||||
return scanResult.getClassesWithAnnotation(FlowLogic::class, SchedulableFlow::class)
|
return scanResult.getClassesWithAnnotation(FlowLogic::class, SchedulableFlow::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findContractClassNames(scanResult: ScanResult): List<String> {
|
private fun findContractClassNames(scanResult: RestrictedScanResult): List<String> {
|
||||||
return (scanResult.getNamesOfClassesImplementing(Contract::class.java) + scanResult.getNamesOfClassesImplementing(UpgradedContract::class.java)).distinct()
|
return (scanResult.getNamesOfClassesImplementing(Contract::class) + scanResult.getNamesOfClassesImplementing(UpgradedContract::class)).distinct()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findPlugins(cordappJarPath: URL): List<SerializationWhitelist> {
|
private fun findPlugins(cordappJarPath: RestrictedURL): List<SerializationWhitelist> {
|
||||||
return ServiceLoader.load(SerializationWhitelist::class.java, URLClassLoader(arrayOf(cordappJarPath), appClassLoader)).toList().filter {
|
return ServiceLoader.load(SerializationWhitelist::class.java, URLClassLoader(arrayOf(cordappJarPath.url), appClassLoader)).toList().filter {
|
||||||
cordappJarPath == it.javaClass.protectionDomain.codeSource.location
|
it.javaClass.protectionDomain.codeSource.location == cordappJarPath.url && it.javaClass.name.startsWith(cordappJarPath.qualifiedNamePrefix)
|
||||||
} + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app.
|
} + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app.
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findCustomSchemas(scanResult: ScanResult): Set<MappedSchema> {
|
private fun findCustomSchemas(scanResult: RestrictedScanResult): Set<MappedSchema> {
|
||||||
return scanResult.getClassesWithSuperclass(MappedSchema::class).toSet()
|
return scanResult.getClassesWithSuperclass(MappedSchema::class).toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scanCordapp(cordappJarPath: URL): ScanResult {
|
private fun scanCordapp(cordappJarPath: RestrictedURL): RestrictedScanResult {
|
||||||
logger.info("Scanning CorDapp in $cordappJarPath")
|
logger.info("Scanning CorDapp in $cordappJarPath")
|
||||||
return FastClasspathScanner().addClassLoader(appClassLoader).overrideClasspath(cordappJarPath).scan()
|
return RestrictedScanResult(FastClasspathScanner().addClassLoader(appClassLoader).overrideClasspath(cordappJarPath.url).scan(), cordappJarPath.qualifiedNamePrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FlowTypeHierarchyComparator(val initiatingFlow: Class<out FlowLogic<*>>) : Comparator<Class<out FlowLogic<*>>> {
|
private class FlowTypeHierarchyComparator(val initiatingFlow: Class<out FlowLogic<*>>) : Comparator<Class<out FlowLogic<*>>> {
|
||||||
@ -269,16 +271,30 @@ class CordappLoader private constructor(private val cordappJarPaths: List<URL>)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : Any> ScanResult.getClassesWithSuperclass(type: KClass<T>): List<T> {
|
/** @param rootPackageName only this package and subpackages may be extracted from [url], or null to allow all packages. */
|
||||||
return getNamesOfSubclassesOf(type.java)
|
private class RestrictedURL(val url: URL, rootPackageName: String?) {
|
||||||
.mapNotNull { loadClass(it, type) }
|
val qualifiedNamePrefix = rootPackageName?.let { it + '.' } ?: ""
|
||||||
.filterNot { Modifier.isAbstract(it.modifiers) }
|
|
||||||
.map { it.kotlin.objectOrNewInstance() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : Any> ScanResult.getClassesWithAnnotation(type: KClass<T>, annotation: KClass<out Annotation>): List<Class<out T>> {
|
private inner class RestrictedScanResult(private val scanResult: ScanResult, private val qualifiedNamePrefix: String) {
|
||||||
return getNamesOfClassesWithAnnotation(annotation.java)
|
fun getNamesOfClassesImplementing(type: KClass<*>): List<String> {
|
||||||
.mapNotNull { loadClass(it, type) }
|
return scanResult.getNamesOfClassesImplementing(type.java)
|
||||||
.filterNot { Modifier.isAbstract(it.modifiers) }
|
.filter { it.startsWith(qualifiedNamePrefix) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : Any> getClassesWithSuperclass(type: KClass<T>): List<T> {
|
||||||
|
return scanResult.getNamesOfSubclassesOf(type.java)
|
||||||
|
.filter { it.startsWith(qualifiedNamePrefix) }
|
||||||
|
.mapNotNull { loadClass(it, type) }
|
||||||
|
.filterNot { Modifier.isAbstract(it.modifiers) }
|
||||||
|
.map { it.kotlin.objectOrNewInstance() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : Any> getClassesWithAnnotation(type: KClass<T>, annotation: KClass<out Annotation>): List<Class<out T>> {
|
||||||
|
return scanResult.getNamesOfClassesWithAnnotation(annotation.java)
|
||||||
|
.filter { it.startsWith(qualifiedNamePrefix) }
|
||||||
|
.mapNotNull { loadClass(it, type) }
|
||||||
|
.filterNot { Modifier.isAbstract(it.modifiers) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,14 @@ import net.corda.core.crypto.SecureHash
|
|||||||
import net.corda.core.node.services.AttachmentStorage
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
import net.corda.core.cordapp.Cordapp
|
import net.corda.core.cordapp.Cordapp
|
||||||
import net.corda.core.cordapp.CordappContext
|
import net.corda.core.cordapp.CordappContext
|
||||||
import net.corda.core.cordapp.CordappProvider
|
|
||||||
import net.corda.core.node.services.AttachmentId
|
import net.corda.core.node.services.AttachmentId
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import java.net.URLClassLoader
|
import java.net.URL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cordapp provider and store. For querying CorDapps for their attachment and vice versa.
|
* Cordapp provider and store. For querying CorDapps for their attachment and vice versa.
|
||||||
*/
|
*/
|
||||||
open class CordappProviderImpl(private val cordappLoader: CordappLoader) : SingletonSerializeAsToken(), CordappProvider {
|
open class CordappProviderImpl(private val cordappLoader: CordappLoader, attachmentStorage: AttachmentStorage) : SingletonSerializeAsToken(), CordappProviderInternal {
|
||||||
override fun getAppContext(): CordappContext {
|
override fun getAppContext(): CordappContext {
|
||||||
// TODO: Use better supported APIs in Java 9
|
// TODO: Use better supported APIs in Java 9
|
||||||
Exception().stackTrace.forEach { stackFrame ->
|
Exception().stackTrace.forEach { stackFrame ->
|
||||||
@ -34,28 +33,19 @@ open class CordappProviderImpl(private val cordappLoader: CordappLoader) : Singl
|
|||||||
/**
|
/**
|
||||||
* Current known CorDapps loaded on this node
|
* Current known CorDapps loaded on this node
|
||||||
*/
|
*/
|
||||||
val cordapps get() = cordappLoader.cordapps
|
override val cordapps get() = cordappLoader.cordapps
|
||||||
private lateinit var cordappAttachments: HashBiMap<SecureHash, Cordapp>
|
private val cordappAttachments = HashBiMap.create(loadContractsIntoAttachmentStore(attachmentStorage))
|
||||||
|
|
||||||
/**
|
|
||||||
* Should only be called once from the initialisation routine of the node or tests
|
|
||||||
*/
|
|
||||||
fun start(attachmentStorage: AttachmentStorage): CordappProviderImpl {
|
|
||||||
cordappAttachments = HashBiMap.create(loadContractsIntoAttachmentStore(attachmentStorage))
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the attachment ID of this CorDapp. Only CorDapps with contracts have an attachment ID
|
* Gets the attachment ID of this CorDapp. Only CorDapps with contracts have an attachment ID
|
||||||
*
|
*
|
||||||
* @param cordapp The cordapp to get the attachment ID
|
* @param cordapp The cordapp to get the attachment ID
|
||||||
* @return An attachment ID if it exists, otherwise nothing
|
* @return An attachment ID if it exists, otherwise nothing
|
||||||
*/
|
*/
|
||||||
fun getCordappAttachmentId(cordapp: Cordapp): SecureHash? = cordappAttachments.inverse().get(cordapp)
|
fun getCordappAttachmentId(cordapp: Cordapp): SecureHash? = cordappAttachments.inverse().get(cordapp.jarPath)
|
||||||
|
|
||||||
private fun loadContractsIntoAttachmentStore(attachmentStorage: AttachmentStorage): Map<SecureHash, Cordapp> {
|
private fun loadContractsIntoAttachmentStore(attachmentStorage: AttachmentStorage): Map<SecureHash, URL> {
|
||||||
val cordappsWithAttachments = cordapps.filter { !it.contractClassNames.isEmpty() }
|
val cordappsWithAttachments = cordapps.filter { !it.contractClassNames.isEmpty() }.map { it.jarPath }
|
||||||
val attachmentIds = cordappsWithAttachments.map { it.jarPath.openStream().use { attachmentStorage.importAttachment(it) } }
|
val attachmentIds = cordappsWithAttachments.map { it.openStream().use { attachmentStorage.importAttachment(it) } }
|
||||||
return attachmentIds.zip(cordappsWithAttachments).toMap()
|
return attachmentIds.zip(cordappsWithAttachments).toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package net.corda.node.internal.cordapp
|
||||||
|
|
||||||
|
import net.corda.core.cordapp.Cordapp
|
||||||
|
import net.corda.core.cordapp.CordappProvider
|
||||||
|
|
||||||
|
interface CordappProviderInternal : CordappProvider {
|
||||||
|
val cordapps: List<Cordapp>
|
||||||
|
}
|
@ -30,11 +30,5 @@ interface SchemaService {
|
|||||||
* or via custom logic in this service.
|
* or via custom logic in this service.
|
||||||
*/
|
*/
|
||||||
fun generateMappedObject(state: ContractState, schema: MappedSchema): PersistentState
|
fun generateMappedObject(state: ContractState, schema: MappedSchema): PersistentState
|
||||||
|
|
||||||
/**
|
|
||||||
* Registration mechanism to add custom contract schemas that extend the [MappedSchema] class.
|
|
||||||
*/
|
|
||||||
fun registerCustomSchemas(customSchemas: Set<MappedSchema>)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//DOCEND SchemaService
|
//DOCEND SchemaService
|
||||||
|
@ -21,6 +21,7 @@ import net.corda.core.serialization.CordaSerializable
|
|||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.internal.InitiatedFlowFactory
|
import net.corda.node.internal.InitiatedFlowFactory
|
||||||
|
import net.corda.node.internal.cordapp.CordappProviderInternal
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
import net.corda.node.services.messaging.MessagingService
|
import net.corda.node.services.messaging.MessagingService
|
||||||
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
|
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
|
||||||
@ -89,7 +90,7 @@ interface ServiceHubInternal : ServiceHub {
|
|||||||
val networkService: MessagingService
|
val networkService: MessagingService
|
||||||
val database: CordaPersistence
|
val database: CordaPersistence
|
||||||
val configuration: NodeConfiguration
|
val configuration: NodeConfiguration
|
||||||
|
override val cordappProvider: CordappProviderInternal
|
||||||
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
||||||
require(txs.any()) { "No transactions passed in for recording" }
|
require(txs.any()) { "No transactions passed in for recording" }
|
||||||
val recordedTransactions = txs.filter { validatedTransactions.addTransaction(it) }
|
val recordedTransactions = txs.filter { validatedTransactions.addTransaction(it) }
|
||||||
|
@ -33,25 +33,13 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab
|
|||||||
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") ?: "")
|
||||||
|
val sessionFactoryForRegisteredSchemas = schemaService.schemaOptions.keys.let {
|
||||||
init {
|
logger.info("Init HibernateConfiguration for schemas: $it")
|
||||||
logger.info("Init HibernateConfiguration for schemas: ${schemaService.schemaOptions.keys}")
|
sessionFactoryForSchemas(it)
|
||||||
sessionFactoryForRegisteredSchemas()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sessionFactoryForRegisteredSchemas(): SessionFactory {
|
/** @param key must be immutable, not just read-only. */
|
||||||
return sessionFactoryForSchemas(*schemaService.schemaOptions.keys.toTypedArray())
|
fun sessionFactoryForSchemas(key: Set<MappedSchema>) = sessionFactories.computeIfAbsent(key, { makeSessionFactoryForSchemas(key) })
|
||||||
}
|
|
||||||
|
|
||||||
fun sessionFactoryForSchema(schema: MappedSchema): SessionFactory {
|
|
||||||
return sessionFactoryForSchemas(schema)
|
|
||||||
}
|
|
||||||
|
|
||||||
//vararg to set conversions left to preserve method signature for now
|
|
||||||
fun sessionFactoryForSchemas(vararg schemas: MappedSchema): SessionFactory {
|
|
||||||
val schemaSet: Set<MappedSchema> = schemas.toSet()
|
|
||||||
return sessionFactories.computeIfAbsent(schemaSet, { makeSessionFactoryForSchemas(schemaSet) })
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun makeSessionFactoryForSchemas(schemas: Set<MappedSchema>): SessionFactory {
|
private fun makeSessionFactoryForSchemas(schemas: Set<MappedSchema>): SessionFactory {
|
||||||
logger.info("Creating session factory for schemas: $schemas")
|
logger.info("Creating session factory for schemas: $schemas")
|
||||||
|
@ -38,7 +38,7 @@ class HibernateObserver(vaultUpdates: Observable<Vault.Update<ContractState>>, v
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun persistStateWithSchema(state: ContractState, stateRef: StateRef, schema: MappedSchema) {
|
fun persistStateWithSchema(state: ContractState, stateRef: StateRef, schema: MappedSchema) {
|
||||||
val sessionFactory = config.sessionFactoryForSchema(schema)
|
val sessionFactory = config.sessionFactoryForSchemas(setOf(schema))
|
||||||
val session = sessionFactory.withOptions().
|
val session = sessionFactory.withOptions().
|
||||||
connection(DatabaseTransactionManager.current().connection).
|
connection(DatabaseTransactionManager.current().connection).
|
||||||
flushMode(FlushMode.MANUAL).
|
flushMode(FlushMode.MANUAL).
|
||||||
|
@ -9,6 +9,7 @@ import net.corda.core.schemas.NodeInfoSchemaV1
|
|||||||
import net.corda.core.schemas.PersistentState
|
import net.corda.core.schemas.PersistentState
|
||||||
import net.corda.core.schemas.QueryableState
|
import net.corda.core.schemas.QueryableState
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
|
import net.corda.node.internal.cordapp.CordappLoader
|
||||||
import net.corda.node.services.api.SchemaService
|
import net.corda.node.services.api.SchemaService
|
||||||
import net.corda.node.services.events.NodeSchedulerService
|
import net.corda.node.services.events.NodeSchedulerService
|
||||||
import net.corda.node.services.identity.PersistentIdentityService
|
import net.corda.node.services.identity.PersistentIdentityService
|
||||||
@ -27,13 +28,13 @@ import net.corda.node.services.vault.VaultSchemaV1
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Most basic implementation of [SchemaService].
|
* Most basic implementation of [SchemaService].
|
||||||
*
|
* @param cordappLoader if not null, custom schemas will be extracted from its cordapps.
|
||||||
* TODO: support loading schema options from node configuration.
|
* TODO: support loading schema options from node configuration.
|
||||||
* TODO: support configuring what schemas are to be selected for persistence.
|
* TODO: support configuring what schemas are to be selected for persistence.
|
||||||
* TODO: support plugins for schema version upgrading or custom mapping not supported by original [QueryableState].
|
* TODO: support plugins for schema version upgrading or custom mapping not supported by original [QueryableState].
|
||||||
* TODO: create whitelisted tables when a CorDapp is first installed
|
* TODO: create whitelisted tables when a CorDapp is first installed
|
||||||
*/
|
*/
|
||||||
class NodeSchemaService(customSchemas: Set<MappedSchema> = emptySet()) : SchemaService, SingletonSerializeAsToken() {
|
class NodeSchemaService(cordappLoader: CordappLoader?) : SchemaService, SingletonSerializeAsToken() {
|
||||||
|
|
||||||
// Entities for compulsory services
|
// Entities for compulsory services
|
||||||
object NodeServices
|
object NodeServices
|
||||||
@ -67,9 +68,12 @@ class NodeSchemaService(customSchemas: Set<MappedSchema> = emptySet()) : SchemaS
|
|||||||
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 { mappedSchema ->
|
override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = if (cordappLoader == null) {
|
||||||
Pair(mappedSchema, SchemaService.SchemaOptions())
|
requiredSchemas
|
||||||
})
|
} else {
|
||||||
|
val customSchemas = cordappLoader.cordapps.flatMap { it.customSchemas }.toSet()
|
||||||
|
requiredSchemas.plus(customSchemas.map { mappedSchema -> 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.
|
||||||
override fun selectSchemas(state: ContractState): Iterable<MappedSchema> {
|
override fun selectSchemas(state: ContractState): Iterable<MappedSchema> {
|
||||||
@ -92,10 +96,4 @@ class NodeSchemaService(customSchemas: Set<MappedSchema> = emptySet()) : SchemaS
|
|||||||
return VaultSchemaV1.VaultFungibleStates(state.owner, state.amount.quantity, state.amount.token.issuer.party, state.amount.token.issuer.reference, state.participants)
|
return VaultSchemaV1.VaultFungibleStates(state.owner, state.amount.quantity, state.amount.token.issuer.party, state.amount.token.issuer.reference, state.participants)
|
||||||
return (state as QueryableState).generateMappedObject(schema)
|
return (state as QueryableState).generateMappedObject(schema)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerCustomSchemas(_customSchemas: Set<MappedSchema>) {
|
|
||||||
schemaOptions = schemaOptions.plus(_customSchemas.map { mappedSchema ->
|
|
||||||
Pair(mappedSchema, SchemaService.SchemaOptions())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ private fun CriteriaBuilder.executeUpdate(session: Session, configure: Root<*>.(
|
|||||||
* TODO: keep an audit trail with time stamps of previously unconsumed states "as of" a particular point in time.
|
* TODO: keep an audit trail with time stamps of previously unconsumed states "as of" a particular point in time.
|
||||||
* TODO: have transaction storage do some caching.
|
* TODO: have transaction storage do some caching.
|
||||||
*/
|
*/
|
||||||
class NodeVaultService(private val clock: Clock, private val keyManagementService: KeyManagementService, private val stateLoader: StateLoader, private val hibernateConfig: HibernateConfiguration) : SingletonSerializeAsToken(), VaultServiceInternal {
|
class NodeVaultService(private val clock: Clock, private val keyManagementService: KeyManagementService, private val stateLoader: StateLoader, hibernateConfig: HibernateConfiguration) : SingletonSerializeAsToken(), VaultServiceInternal {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val log = loggerFor<NodeVaultService>()
|
val log = loggerFor<NodeVaultService>()
|
||||||
@ -377,9 +377,8 @@ class NodeVaultService(private val clock: Clock, private val keyManagementServic
|
|||||||
return keysToCheck.any { it in myKeys }
|
return keysToCheck.any { it in myKeys }
|
||||||
}
|
}
|
||||||
|
|
||||||
private var sessionFactory = hibernateConfig.sessionFactoryForRegisteredSchemas()
|
private val sessionFactory = hibernateConfig.sessionFactoryForRegisteredSchemas
|
||||||
private var criteriaBuilder = sessionFactory.criteriaBuilder
|
private val criteriaBuilder = sessionFactory.criteriaBuilder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintain a list of contract state interfaces to concrete types stored in the vault
|
* Maintain a list of contract state interfaces to concrete types stored in the vault
|
||||||
* for usage in generic queries of type queryBy<LinearState> or queryBy<FungibleState<*>>
|
* for usage in generic queries of type queryBy<LinearState> or queryBy<FungibleState<*>>
|
||||||
@ -406,11 +405,6 @@ class NodeVaultService(private val clock: Clock, private val keyManagementServic
|
|||||||
@Throws(VaultQueryException::class)
|
@Throws(VaultQueryException::class)
|
||||||
override fun <T : ContractState> _queryBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractStateType: Class<out T>): Vault.Page<T> {
|
override fun <T : ContractState> _queryBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractStateType: Class<out T>): Vault.Page<T> {
|
||||||
log.info("Vault Query for contract type: $contractStateType, criteria: $criteria, pagination: $paging, sorting: $sorting")
|
log.info("Vault Query for contract type: $contractStateType, criteria: $criteria, pagination: $paging, sorting: $sorting")
|
||||||
|
|
||||||
// refresh to include any schemas registered after initial VQ service initialisation
|
|
||||||
sessionFactory = hibernateConfig.sessionFactoryForRegisteredSchemas()
|
|
||||||
criteriaBuilder = sessionFactory.criteriaBuilder
|
|
||||||
|
|
||||||
// calculate total results where a page specification has been defined
|
// calculate total results where a page specification has been defined
|
||||||
var totalStates = -1L
|
var totalStates = -1L
|
||||||
if (!paging.isDefault) {
|
if (!paging.isDefault) {
|
||||||
|
@ -6,8 +6,6 @@ import net.corda.core.node.services.IdentityService
|
|||||||
import net.corda.node.services.api.SchemaService
|
import net.corda.node.services.api.SchemaService
|
||||||
import net.corda.node.services.persistence.HibernateConfiguration
|
import net.corda.node.services.persistence.HibernateConfiguration
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import org.hibernate.SessionFactory
|
|
||||||
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscriber
|
import rx.Subscriber
|
||||||
import rx.subjects.UnicastSubject
|
import rx.subjects.UnicastSubject
|
||||||
@ -32,12 +30,7 @@ class CordaPersistence(var dataSource: HikariDataSource, private val schemaServi
|
|||||||
HibernateConfiguration(schemaService, databaseProperties, createIdentityService)
|
HibernateConfiguration(schemaService, databaseProperties, createIdentityService)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val entityManagerFactory get() = hibernateConfig.sessionFactoryForRegisteredSchemas
|
||||||
val entityManagerFactory: SessionFactory by lazy {
|
|
||||||
transaction {
|
|
||||||
hibernateConfig.sessionFactoryForRegisteredSchemas()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun connect(dataSource: HikariDataSource, schemaService: SchemaService, createIdentityService: () -> IdentityService, databaseProperties: Properties): CordaPersistence {
|
fun connect(dataSource: HikariDataSource, schemaService: SchemaService, createIdentityService: () -> IdentityService, databaseProperties: Properties): CordaPersistence {
|
||||||
@ -103,7 +96,7 @@ class CordaPersistence(var dataSource: HikariDataSource, private val schemaServi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun configureDatabase(dataSourceProperties: Properties, databaseProperties: Properties?, schemaService: SchemaService = NodeSchemaService(), createIdentityService: () -> IdentityService): CordaPersistence {
|
fun configureDatabase(dataSourceProperties: Properties, databaseProperties: Properties?, createIdentityService: () -> IdentityService, schemaService: SchemaService = NodeSchemaService(null)): CordaPersistence {
|
||||||
val config = HikariConfig(dataSourceProperties)
|
val config = HikariConfig(dataSourceProperties)
|
||||||
val dataSource = HikariDataSource(config)
|
val dataSource = HikariDataSource(config)
|
||||||
val persistence = CordaPersistence.connect(dataSource, schemaService, createIdentityService, databaseProperties ?: Properties())
|
val persistence = CordaPersistence.connect(dataSource, schemaService, createIdentityService, databaseProperties ?: Properties())
|
||||||
|
@ -8,7 +8,6 @@ import net.corda.core.messaging.*;
|
|||||||
import net.corda.core.node.services.*;
|
import net.corda.core.node.services.*;
|
||||||
import net.corda.core.node.services.vault.*;
|
import net.corda.core.node.services.vault.*;
|
||||||
import net.corda.core.node.services.vault.QueryCriteria.*;
|
import net.corda.core.node.services.vault.QueryCriteria.*;
|
||||||
import net.corda.core.schemas.*;
|
|
||||||
import net.corda.core.utilities.*;
|
import net.corda.core.utilities.*;
|
||||||
import net.corda.finance.contracts.*;
|
import net.corda.finance.contracts.*;
|
||||||
import net.corda.finance.contracts.asset.*;
|
import net.corda.finance.contracts.asset.*;
|
||||||
@ -43,14 +42,13 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
List<String> cordappPackages = Arrays.asList("net.corda.testing.contracts", "net.corda.finance.contracts.asset");
|
List<String> cordappPackages = Arrays.asList("net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName());
|
||||||
ArrayList<KeyPair> keys = new ArrayList<>();
|
ArrayList<KeyPair> keys = new ArrayList<>();
|
||||||
keys.add(getMEGA_CORP_KEY());
|
keys.add(getMEGA_CORP_KEY());
|
||||||
keys.add(getDUMMY_NOTARY_KEY());
|
keys.add(getDUMMY_NOTARY_KEY());
|
||||||
Set<MappedSchema> requiredSchemas = Collections.singleton(CashSchemaV1.INSTANCE);
|
|
||||||
IdentityService identitySvc = makeTestIdentityService();
|
IdentityService identitySvc = makeTestIdentityService();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(requiredSchemas, keys, () -> identitySvc, cordappPackages);
|
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(keys, () -> identitySvc, cordappPackages);
|
||||||
issuerServices = new MockServices(cordappPackages, getDUMMY_CASH_ISSUER_KEY(), getBOC_KEY());
|
issuerServices = new MockServices(cordappPackages, getDUMMY_CASH_ISSUER_KEY(), getBOC_KEY());
|
||||||
database = databaseAndServices.getFirst();
|
database = databaseAndServices.getFirst();
|
||||||
services = databaseAndServices.getSecond();
|
services = databaseAndServices.getSecond();
|
||||||
|
@ -26,7 +26,7 @@ import kotlin.test.assertEquals
|
|||||||
class InteractiveShellTest {
|
class InteractiveShellTest {
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
InteractiveShell.database = configureDatabase(MockServices.makeTestDataSourceProperties(), MockServices.makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
InteractiveShell.database = configureDatabase(MockServices.makeTestDataSourceProperties(), MockServices.makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.corda.node.internal.cordapp
|
package net.corda.node.internal.cordapp
|
||||||
|
|
||||||
|
import com.nhaarman.mockito_kotlin.mock
|
||||||
import net.corda.core.node.services.AttachmentStorage
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
import net.corda.testing.node.MockAttachmentStorage
|
import net.corda.testing.node.MockAttachmentStorage
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
@ -22,9 +23,7 @@ class CordappProviderImplTests {
|
|||||||
@Test
|
@Test
|
||||||
fun `isolated jar is loaded into the attachment store`() {
|
fun `isolated jar is loaded into the attachment store`() {
|
||||||
val loader = CordappLoader.createDevMode(listOf(isolatedJAR))
|
val loader = CordappLoader.createDevMode(listOf(isolatedJAR))
|
||||||
val provider = CordappProviderImpl(loader)
|
val provider = CordappProviderImpl(loader, attachmentStore)
|
||||||
|
|
||||||
provider.start(attachmentStore)
|
|
||||||
val maybeAttachmentId = provider.getCordappAttachmentId(provider.cordapps.first())
|
val maybeAttachmentId = provider.getCordappAttachmentId(provider.cordapps.first())
|
||||||
|
|
||||||
Assert.assertNotNull(maybeAttachmentId)
|
Assert.assertNotNull(maybeAttachmentId)
|
||||||
@ -34,17 +33,14 @@ class CordappProviderImplTests {
|
|||||||
@Test
|
@Test
|
||||||
fun `empty jar is not loaded into the attachment store`() {
|
fun `empty jar is not loaded into the attachment store`() {
|
||||||
val loader = CordappLoader.createDevMode(listOf(emptyJAR))
|
val loader = CordappLoader.createDevMode(listOf(emptyJAR))
|
||||||
val provider = CordappProviderImpl(loader)
|
val provider = CordappProviderImpl(loader, attachmentStore)
|
||||||
|
|
||||||
provider.start(attachmentStore)
|
|
||||||
|
|
||||||
Assert.assertNull(provider.getCordappAttachmentId(provider.cordapps.first()))
|
Assert.assertNull(provider.getCordappAttachmentId(provider.cordapps.first()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test that we find a cordapp class that is loaded into the store`() {
|
fun `test that we find a cordapp class that is loaded into the store`() {
|
||||||
val loader = CordappLoader.createDevMode(listOf(isolatedJAR))
|
val loader = CordappLoader.createDevMode(listOf(isolatedJAR))
|
||||||
val provider = CordappProviderImpl(loader)
|
val provider = CordappProviderImpl(loader, mock())
|
||||||
val className = "net.corda.finance.contracts.isolated.AnotherDummyContract"
|
val className = "net.corda.finance.contracts.isolated.AnotherDummyContract"
|
||||||
|
|
||||||
val expected = provider.cordapps.first()
|
val expected = provider.cordapps.first()
|
||||||
@ -57,10 +53,8 @@ class CordappProviderImplTests {
|
|||||||
@Test
|
@Test
|
||||||
fun `test that we find an attachment for a cordapp contrat class`() {
|
fun `test that we find an attachment for a cordapp contrat class`() {
|
||||||
val loader = CordappLoader.createDevMode(listOf(isolatedJAR))
|
val loader = CordappLoader.createDevMode(listOf(isolatedJAR))
|
||||||
val provider = CordappProviderImpl(loader)
|
val provider = CordappProviderImpl(loader, attachmentStore)
|
||||||
val className = "net.corda.finance.contracts.isolated.AnotherDummyContract"
|
val className = "net.corda.finance.contracts.isolated.AnotherDummyContract"
|
||||||
|
|
||||||
provider.start(attachmentStore)
|
|
||||||
val expected = provider.getAppContext(provider.cordapps.first()).attachmentId
|
val expected = provider.getAppContext(provider.cordapps.first()).attachmentId
|
||||||
val actual = provider.getContractAttachmentID(className)
|
val actual = provider.getContractAttachmentID(className)
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
|||||||
calls = 0
|
calls = 0
|
||||||
val dataSourceProps = makeTestDataSourceProperties()
|
val dataSourceProps = makeTestDataSourceProperties()
|
||||||
val databaseProperties = makeTestDatabaseProperties()
|
val databaseProperties = makeTestDatabaseProperties()
|
||||||
database = configureDatabase(dataSourceProps, databaseProperties, createIdentityService = ::makeTestIdentityService)
|
database = configureDatabase(dataSourceProps, databaseProperties, ::makeTestIdentityService)
|
||||||
val identityService = InMemoryIdentityService(trustRoot = DEV_TRUST_ROOT)
|
val identityService = InMemoryIdentityService(trustRoot = DEV_TRUST_ROOT)
|
||||||
val kms = MockKeyManagementService(identityService, ALICE_KEY)
|
val kms = MockKeyManagementService(identityService, ALICE_KEY)
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
|||||||
network = mockMessagingService), TestReference {
|
network = mockMessagingService), TestReference {
|
||||||
override val vaultService: VaultServiceInternal = NodeVaultService(testClock, kms, stateLoader, database.hibernateConfig)
|
override val vaultService: VaultServiceInternal = NodeVaultService(testClock, kms, stateLoader, database.hibernateConfig)
|
||||||
override val testReference = this@NodeSchedulerServiceTest
|
override val testReference = this@NodeSchedulerServiceTest
|
||||||
override val cordappProvider = CordappProviderImpl(CordappLoader.createWithTestPackages(listOf("net.corda.testing.contracts"))).start(attachments)
|
override val cordappProvider = CordappProviderImpl(CordappLoader.createWithTestPackages(listOf("net.corda.testing.contracts")), attachments)
|
||||||
}
|
}
|
||||||
smmExecutor = AffinityExecutor.ServiceAffinityExecutor("test", 1)
|
smmExecutor = AffinityExecutor.ServiceAffinityExecutor("test", 1)
|
||||||
scheduler = NodeSchedulerService(services, schedulerGatedExecutor, serverThread = smmExecutor)
|
scheduler = NodeSchedulerService(services, schedulerGatedExecutor, serverThread = smmExecutor)
|
||||||
|
@ -71,7 +71,7 @@ class ArtemisMessagingTests : TestDependencyInjectionBase() {
|
|||||||
baseDirectory = baseDirectory,
|
baseDirectory = baseDirectory,
|
||||||
myLegalName = ALICE.name)
|
myLegalName = ALICE.name)
|
||||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
networkMapRegistrationFuture = doneFuture(Unit)
|
networkMapRegistrationFuture = doneFuture(Unit)
|
||||||
networkMapCache = PersistentNetworkMapCache(serviceHub = object : MockServiceHubInternal(database, config) {})
|
networkMapCache = PersistentNetworkMapCache(serviceHub = object : MockServiceHubInternal(database, config) {})
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class DBCheckpointStorageTests : TestDependencyInjectionBase() {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
newCheckpointStorage()
|
newCheckpointStorage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||||
val dataSourceProps = makeTestDataSourceProperties()
|
val dataSourceProps = makeTestDataSourceProperties()
|
||||||
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties(), NodeSchemaService(), ::makeTestIdentityService)
|
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
database.transaction {
|
database.transaction {
|
||||||
|
|
||||||
services = object : MockServices(BOB_KEY) {
|
services = object : MockServices(BOB_KEY) {
|
||||||
|
@ -9,6 +9,7 @@ import net.corda.core.utilities.toBase58String
|
|||||||
import net.corda.core.node.services.Vault
|
import net.corda.core.node.services.Vault
|
||||||
import net.corda.core.node.services.VaultService
|
import net.corda.core.node.services.VaultService
|
||||||
import net.corda.core.schemas.CommonSchemaV1
|
import net.corda.core.schemas.CommonSchemaV1
|
||||||
|
import net.corda.core.schemas.MappedSchema
|
||||||
import net.corda.core.schemas.PersistentStateRef
|
import net.corda.core.schemas.PersistentStateRef
|
||||||
import net.corda.core.serialization.SerializationDefaults
|
import net.corda.core.serialization.SerializationDefaults
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
@ -25,7 +26,6 @@ import net.corda.finance.schemas.SampleCashSchemaV2
|
|||||||
import net.corda.finance.schemas.SampleCashSchemaV3
|
import net.corda.finance.schemas.SampleCashSchemaV3
|
||||||
import net.corda.finance.utils.sumCash
|
import net.corda.finance.utils.sumCash
|
||||||
import net.corda.node.services.schema.HibernateObserver
|
import net.corda.node.services.schema.HibernateObserver
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
|
||||||
import net.corda.node.services.vault.VaultSchemaV1
|
import net.corda.node.services.vault.VaultSchemaV1
|
||||||
import net.corda.node.utilities.CordaPersistence
|
import net.corda.node.utilities.CordaPersistence
|
||||||
import net.corda.node.utilities.configureDatabase
|
import net.corda.node.utilities.configureDatabase
|
||||||
@ -77,7 +77,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_KEY, BOB_KEY, BOC_KEY)
|
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_KEY, BOB_KEY, BOC_KEY)
|
||||||
val dataSourceProps = makeTestDataSourceProperties()
|
val dataSourceProps = makeTestDataSourceProperties()
|
||||||
val defaultDatabaseProperties = makeTestDatabaseProperties()
|
val defaultDatabaseProperties = makeTestDatabaseProperties()
|
||||||
database = configureDatabase(dataSourceProps, defaultDatabaseProperties, NodeSchemaService(), ::makeTestIdentityService)
|
database = configureDatabase(dataSourceProps, defaultDatabaseProperties, ::makeTestIdentityService)
|
||||||
database.transaction {
|
database.transaction {
|
||||||
hibernateConfig = database.hibernateConfig
|
hibernateConfig = database.hibernateConfig
|
||||||
services = object : MockServices(cordappPackages, BOB_KEY, BOC_KEY, DUMMY_NOTARY_KEY) {
|
services = object : MockServices(cordappPackages, BOB_KEY, BOC_KEY, DUMMY_NOTARY_KEY) {
|
||||||
@ -95,13 +95,13 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
hibernatePersister = services.hibernatePersister
|
hibernatePersister = services.hibernatePersister
|
||||||
}
|
}
|
||||||
setUpDb()
|
setUpDb()
|
||||||
|
sessionFactory = sessionFactoryForSchemas(VaultSchemaV1, CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3)
|
||||||
val customSchemas = setOf(VaultSchemaV1, CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3)
|
|
||||||
sessionFactory = hibernateConfig.sessionFactoryForSchemas(*customSchemas.toTypedArray())
|
|
||||||
entityManager = sessionFactory.createEntityManager()
|
entityManager = sessionFactory.createEntityManager()
|
||||||
criteriaBuilder = sessionFactory.criteriaBuilder
|
criteriaBuilder = sessionFactory.criteriaBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun sessionFactoryForSchemas(vararg schemas: MappedSchema) = hibernateConfig.sessionFactoryForSchemas(schemas.toSet())
|
||||||
|
|
||||||
@After
|
@After
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
database.close()
|
database.close()
|
||||||
@ -536,8 +536,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
|
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
|
||||||
services.fillWithSomeTestLinearStates(2)
|
services.fillWithSomeTestLinearStates(2)
|
||||||
}
|
}
|
||||||
|
val sessionFactory = sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV1)
|
||||||
val sessionFactory = hibernateConfig.sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV1)
|
|
||||||
val criteriaBuilder = sessionFactory.criteriaBuilder
|
val criteriaBuilder = sessionFactory.criteriaBuilder
|
||||||
val entityManager = sessionFactory.createEntityManager()
|
val entityManager = sessionFactory.createEntityManager()
|
||||||
|
|
||||||
@ -568,8 +567,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
|
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
|
||||||
services.fillWithSomeTestLinearStates(2)
|
services.fillWithSomeTestLinearStates(2)
|
||||||
}
|
}
|
||||||
|
val sessionFactory = sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV2)
|
||||||
val sessionFactory = hibernateConfig.sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV2)
|
|
||||||
val criteriaBuilder = sessionFactory.criteriaBuilder
|
val criteriaBuilder = sessionFactory.criteriaBuilder
|
||||||
val entityManager = sessionFactory.createEntityManager()
|
val entityManager = sessionFactory.createEntityManager()
|
||||||
|
|
||||||
@ -635,8 +633,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val sessionFactory = sessionFactoryForSchemas(VaultSchemaV1, CommonSchemaV1, SampleCashSchemaV3)
|
||||||
val sessionFactory = hibernateConfig.sessionFactoryForSchemas(VaultSchemaV1, CommonSchemaV1, SampleCashSchemaV3)
|
|
||||||
val criteriaBuilder = sessionFactory.criteriaBuilder
|
val criteriaBuilder = sessionFactory.criteriaBuilder
|
||||||
val entityManager = sessionFactory.createEntityManager()
|
val entityManager = sessionFactory.createEntityManager()
|
||||||
|
|
||||||
@ -764,8 +761,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
services.fillWithSomeTestLinearStates(2, externalId = "222")
|
services.fillWithSomeTestLinearStates(2, externalId = "222")
|
||||||
services.fillWithSomeTestLinearStates(3, externalId = "333")
|
services.fillWithSomeTestLinearStates(3, externalId = "333")
|
||||||
}
|
}
|
||||||
|
val sessionFactory = sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV2)
|
||||||
val sessionFactory = hibernateConfig.sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV2)
|
|
||||||
val criteriaBuilder = sessionFactory.criteriaBuilder
|
val criteriaBuilder = sessionFactory.criteriaBuilder
|
||||||
val entityManager = sessionFactory.createEntityManager()
|
val entityManager = sessionFactory.createEntityManager()
|
||||||
|
|
||||||
@ -817,8 +813,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
services.fillWithSomeTestLinearStates(2, externalId = "222")
|
services.fillWithSomeTestLinearStates(2, externalId = "222")
|
||||||
services.fillWithSomeTestLinearStates(3, externalId = "333")
|
services.fillWithSomeTestLinearStates(3, externalId = "333")
|
||||||
}
|
}
|
||||||
|
val sessionFactory = sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV1)
|
||||||
val sessionFactory = hibernateConfig.sessionFactoryForSchemas(VaultSchemaV1, DummyLinearStateSchemaV1)
|
|
||||||
val criteriaBuilder = sessionFactory.criteriaBuilder
|
val criteriaBuilder = sessionFactory.criteriaBuilder
|
||||||
val entityManager = sessionFactory.createEntityManager()
|
val entityManager = sessionFactory.createEntityManager()
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class NodeAttachmentStorageTest {
|
|||||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||||
|
|
||||||
val dataSourceProperties = makeTestDataSourceProperties()
|
val dataSourceProperties = makeTestDataSourceProperties()
|
||||||
database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
fs = Jimfs.newFileSystem(Configuration.unix())
|
fs = Jimfs.newFileSystem(Configuration.unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +57,6 @@ class HibernateObserverTests {
|
|||||||
val testSchema = TestSchema
|
val testSchema = TestSchema
|
||||||
val rawUpdatesPublisher = PublishSubject.create<Vault.Update<ContractState>>()
|
val rawUpdatesPublisher = PublishSubject.create<Vault.Update<ContractState>>()
|
||||||
val schemaService = object : SchemaService {
|
val schemaService = object : SchemaService {
|
||||||
override fun registerCustomSchemas(customSchemas: Set<MappedSchema>) {}
|
|
||||||
|
|
||||||
override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = emptyMap()
|
override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = emptyMap()
|
||||||
|
|
||||||
override fun selectSchemas(state: ContractState): Iterable<MappedSchema> = setOf(testSchema)
|
override fun selectSchemas(state: ContractState): Iterable<MappedSchema> = setOf(testSchema)
|
||||||
@ -70,7 +68,7 @@ class HibernateObserverTests {
|
|||||||
return parent
|
return parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), schemaService, createIdentityService = ::makeTestIdentityService)
|
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService, schemaService)
|
||||||
@Suppress("UNUSED_VARIABLE")
|
@Suppress("UNUSED_VARIABLE")
|
||||||
val observer = HibernateObserver(rawUpdatesPublisher, database.hibernateConfig)
|
val observer = HibernateObserver(rawUpdatesPublisher, database.hibernateConfig)
|
||||||
database.transaction {
|
database.transaction {
|
||||||
|
@ -3,11 +3,13 @@ package net.corda.node.services.schema
|
|||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.schemas.MappedSchema
|
import net.corda.core.schemas.MappedSchema
|
||||||
import net.corda.core.schemas.PersistentState
|
import net.corda.core.schemas.PersistentState
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.services.api.ServiceHubInternal
|
import net.corda.node.services.api.ServiceHubInternal
|
||||||
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
import net.corda.testing.schemas.DummyLinearStateSchemaV1
|
import net.corda.testing.schemas.DummyLinearStateSchemaV1
|
||||||
@ -15,6 +17,7 @@ import org.hibernate.annotations.Cascade
|
|||||||
import org.hibernate.annotations.CascadeType
|
import org.hibernate.annotations.CascadeType
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class NodeSchemaServiceTest {
|
class NodeSchemaServiceTest {
|
||||||
@ -23,11 +26,9 @@ class NodeSchemaServiceTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun `registering custom schemas for testing with MockNode`() {
|
fun `registering custom schemas for testing with MockNode`() {
|
||||||
val mockNet = MockNetwork()
|
val mockNet = MockNetwork(cordappPackages = listOf(DummyLinearStateSchemaV1::class.packageName))
|
||||||
val mockNode = mockNet.createNode()
|
val mockNode = mockNet.createNode()
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
|
|
||||||
mockNode.internals.registerCustomSchemas(setOf(DummyLinearStateSchemaV1))
|
|
||||||
val schemaService = mockNode.services.schemaService
|
val schemaService = mockNode.services.schemaService
|
||||||
assertTrue(schemaService.schemaOptions.containsKey(DummyLinearStateSchemaV1))
|
assertTrue(schemaService.schemaOptions.containsKey(DummyLinearStateSchemaV1))
|
||||||
|
|
||||||
@ -50,6 +51,16 @@ class NodeSchemaServiceTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `custom schemas are loaded eagerly`() {
|
||||||
|
val expected = setOf("PARENTS", "CHILDREN")
|
||||||
|
assertEquals<Set<*>>(expected, driver {
|
||||||
|
(startNode(startInSameProcess = true).getOrThrow() as NodeHandle.InProcess).node.database.transaction {
|
||||||
|
session.createNativeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES").list()
|
||||||
|
}
|
||||||
|
}.toMutableSet().apply { retainAll(expected) })
|
||||||
|
}
|
||||||
|
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
class MappedSchemasFlow : FlowLogic<List<String>>() {
|
class MappedSchemasFlow : FlowLogic<List<String>>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
|
@ -86,7 +86,7 @@ class DistributedImmutableMapTests : TestDependencyInjectionBase() {
|
|||||||
private fun createReplica(myAddress: NetworkHostAndPort, clusterAddress: NetworkHostAndPort? = null): CompletableFuture<Member> {
|
private fun createReplica(myAddress: NetworkHostAndPort, clusterAddress: NetworkHostAndPort? = null): CompletableFuture<Member> {
|
||||||
val storage = Storage.builder().withStorageLevel(StorageLevel.MEMORY).build()
|
val storage = Storage.builder().withStorageLevel(StorageLevel.MEMORY).build()
|
||||||
val address = Address(myAddress.host, myAddress.port)
|
val address = Address(myAddress.host, myAddress.port)
|
||||||
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties("serverNameTablePrefix", "PORT_${myAddress.port}_"), createIdentityService = ::makeTestIdentityService)
|
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties("serverNameTablePrefix", "PORT_${myAddress.port}_"), ::makeTestIdentityService)
|
||||||
databases.add(database)
|
databases.add(database)
|
||||||
val stateMachineFactory = { DistributedImmutableMap(database, RaftUniquenessProvider.Companion::createMap) }
|
val stateMachineFactory = { DistributedImmutableMap(database, RaftUniquenessProvider.Companion::createMap) }
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class PersistentUniquenessProviderTests : TestDependencyInjectionBase() {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -9,6 +9,7 @@ import net.corda.core.crypto.generateKeyPair
|
|||||||
import net.corda.core.identity.AbstractParty
|
import net.corda.core.identity.AbstractParty
|
||||||
import net.corda.core.identity.AnonymousParty
|
import net.corda.core.identity.AnonymousParty
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.node.services.*
|
import net.corda.core.node.services.*
|
||||||
import net.corda.core.node.services.vault.QueryCriteria
|
import net.corda.core.node.services.vault.QueryCriteria
|
||||||
import net.corda.core.node.services.vault.QueryCriteria.*
|
import net.corda.core.node.services.vault.QueryCriteria.*
|
||||||
@ -46,7 +47,7 @@ import kotlin.test.assertTrue
|
|||||||
|
|
||||||
class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||||
companion object {
|
companion object {
|
||||||
private val cordappPackages = listOf("net.corda.finance.contracts.asset")
|
private val cordappPackages = listOf("net.corda.finance.contracts.asset", CashSchemaV1::class.packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var services: MockServices
|
lateinit var services: MockServices
|
||||||
@ -58,7 +59,6 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
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),
|
|
||||||
cordappPackages = cordappPackages)
|
cordappPackages = cordappPackages)
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.crypto.entropyToKeyPair
|
|||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.node.services.*
|
import net.corda.core.node.services.*
|
||||||
import net.corda.core.node.services.vault.*
|
import net.corda.core.node.services.vault.*
|
||||||
import net.corda.core.node.services.vault.QueryCriteria.*
|
import net.corda.core.node.services.vault.QueryCriteria.*
|
||||||
@ -45,10 +46,9 @@ import java.time.temporal.ChronoUnit
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class VaultQueryTests : TestDependencyInjectionBase() {
|
class VaultQueryTests : TestDependencyInjectionBase() {
|
||||||
companion object {
|
private val cordappPackages = setOf(
|
||||||
private val cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts")
|
"net.corda.testing.contracts", "net.corda.finance.contracts",
|
||||||
}
|
CashSchemaV1::class.packageName, CommercialPaperSchemaV1::class.packageName, DummyLinearStateSchemaV1::class.packageName).toMutableList()
|
||||||
|
|
||||||
private lateinit var services: MockServices
|
private lateinit var services: MockServices
|
||||||
private lateinit var notaryServices: MockServices
|
private lateinit var notaryServices: MockServices
|
||||||
private val vaultService: VaultService get() = services.vaultService
|
private val vaultService: VaultService get() = services.vaultService
|
||||||
@ -67,7 +67,6 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
|||||||
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),
|
|
||||||
cordappPackages = cordappPackages)
|
cordappPackages = cordappPackages)
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
@ -85,8 +84,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
|||||||
@Ignore
|
@Ignore
|
||||||
@Test
|
@Test
|
||||||
fun createPersistentTestDb() {
|
fun createPersistentTestDb() {
|
||||||
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = { identitySvc })
|
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), { identitySvc })
|
||||||
|
|
||||||
setUpDb(database, 5000)
|
setUpDb(database, 5000)
|
||||||
|
|
||||||
database.close()
|
database.close()
|
||||||
@ -1753,6 +1751,9 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `query attempting to use unregistered schema`() {
|
fun `query attempting to use unregistered schema`() {
|
||||||
|
tearDown()
|
||||||
|
cordappPackages -= SampleCashSchemaV3::class.packageName
|
||||||
|
setUp()
|
||||||
database.transaction {
|
database.transaction {
|
||||||
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
|
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
|
||||||
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
|
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
|
||||||
|
@ -4,6 +4,7 @@ import net.corda.core.contracts.ContractState
|
|||||||
import net.corda.core.contracts.LinearState
|
import net.corda.core.contracts.LinearState
|
||||||
import net.corda.core.contracts.UniqueIdentifier
|
import net.corda.core.contracts.UniqueIdentifier
|
||||||
import net.corda.core.identity.AnonymousParty
|
import net.corda.core.identity.AnonymousParty
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.node.services.Vault
|
import net.corda.core.node.services.Vault
|
||||||
import net.corda.core.node.services.VaultService
|
import net.corda.core.node.services.VaultService
|
||||||
import net.corda.core.node.services.queryBy
|
import net.corda.core.node.services.queryBy
|
||||||
@ -35,7 +36,7 @@ import kotlin.test.assertEquals
|
|||||||
|
|
||||||
class VaultWithCashTest : TestDependencyInjectionBase() {
|
class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||||
companion object {
|
companion object {
|
||||||
private val cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset")
|
private val cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1::class.packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var services: MockServices
|
lateinit var services: MockServices
|
||||||
@ -48,7 +49,6 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
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),
|
|
||||||
cordappPackages = cordappPackages)
|
cordappPackages = cordappPackages)
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
|
@ -21,7 +21,7 @@ class ObservablesTests {
|
|||||||
val toBeClosed = mutableListOf<Closeable>()
|
val toBeClosed = mutableListOf<Closeable>()
|
||||||
|
|
||||||
fun createDatabase(): CordaPersistence {
|
fun createDatabase(): CordaPersistence {
|
||||||
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
toBeClosed += database
|
toBeClosed += database
|
||||||
return database
|
return database
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService)
|
||||||
database.transaction {
|
database.transaction {
|
||||||
oracle = createMockCordaService(services, NodeInterestRates::Oracle)
|
oracle = createMockCordaService(services, NodeInterestRates::Oracle)
|
||||||
oracle.knownFixes = TEST_DATA
|
oracle.knownFixes = TEST_DATA
|
||||||
|
@ -12,7 +12,6 @@ import net.corda.node.internal.StartedNode
|
|||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
import net.corda.node.services.statemachine.StateMachineManager
|
import net.corda.node.services.statemachine.StateMachineManager
|
||||||
import net.corda.nodeapi.internal.ServiceInfo
|
import net.corda.nodeapi.internal.ServiceInfo
|
||||||
import net.corda.nodeapi.internal.ServiceType
|
|
||||||
import net.corda.testing.*
|
import net.corda.testing.*
|
||||||
import net.corda.testing.node.InMemoryMessagingNetwork
|
import net.corda.testing.node.InMemoryMessagingNetwork
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
@ -270,9 +269,3 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
|
|||||||
mockNet.stopNodes()
|
mockNet.stopNodes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function for verifying that a service info contains the given type of advertised service. For non-simulation cases
|
|
||||||
* this is a configuration matter rather than implementation.
|
|
||||||
*/
|
|
||||||
fun Iterable<ServiceInfo>.containsType(type: ServiceType) = any { it.type == type }
|
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.traderdemo
|
package net.corda.traderdemo
|
||||||
|
|
||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.millis
|
import net.corda.core.utilities.millis
|
||||||
import net.corda.finance.DOLLARS
|
import net.corda.finance.DOLLARS
|
||||||
@ -20,7 +21,9 @@ import org.assertj.core.api.Assertions.assertThat
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
class TraderDemoTest : NodeBasedTest(listOf("net.corda.finance.contracts.asset", "net.corda.finance.contracts")) {
|
class TraderDemoTest : NodeBasedTest(listOf(
|
||||||
|
"net.corda.finance.contracts.asset", "net.corda.finance.contracts",
|
||||||
|
CashSchemaV1::class.packageName, CommercialPaperSchemaV1::class.packageName)) {
|
||||||
@Test
|
@Test
|
||||||
fun `runs trader demo`() {
|
fun `runs trader demo`() {
|
||||||
val demoUser = User("demo", "demo", setOf(startFlowPermission<SellerFlow>()))
|
val demoUser = User("demo", "demo", setOf(startFlowPermission<SellerFlow>()))
|
||||||
@ -35,9 +38,6 @@ class TraderDemoTest : NodeBasedTest(listOf("net.corda.finance.contracts.asset",
|
|||||||
val (nodeA, nodeB, bankNode) = listOf(nodeAFuture, nodeBFuture, bankNodeFuture, notaryFuture).map { it.getOrThrow() }
|
val (nodeA, nodeB, bankNode) = listOf(nodeAFuture, nodeBFuture, bankNodeFuture, notaryFuture).map { it.getOrThrow() }
|
||||||
|
|
||||||
nodeA.internals.registerInitiatedFlow(BuyerFlow::class.java)
|
nodeA.internals.registerInitiatedFlow(BuyerFlow::class.java)
|
||||||
nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1))
|
|
||||||
nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1, CommercialPaperSchemaV1))
|
|
||||||
|
|
||||||
val (nodeARpc, nodeBRpc) = listOf(nodeA, nodeB).map {
|
val (nodeARpc, nodeBRpc) = listOf(nodeA, nodeB).map {
|
||||||
val client = CordaRPCClient(it.internals.configuration.rpcAddress!!)
|
val client = CordaRPCClient(it.internals.configuration.rpcAddress!!)
|
||||||
client.start(demoUser.username, demoUser.password).proxy
|
client.start(demoUser.username, demoUser.password).proxy
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.node.testing
|
package net.corda.node.testing
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry
|
import com.codahale.metrics.MetricRegistry
|
||||||
import net.corda.core.cordapp.CordappProvider
|
|
||||||
import net.corda.core.flows.FlowInitiator
|
import net.corda.core.flows.FlowInitiator
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
@ -13,11 +12,11 @@ import net.corda.node.internal.InitiatedFlowFactory
|
|||||||
import net.corda.node.internal.StateLoaderImpl
|
import net.corda.node.internal.StateLoaderImpl
|
||||||
import net.corda.node.internal.cordapp.CordappLoader
|
import net.corda.node.internal.cordapp.CordappLoader
|
||||||
import net.corda.node.internal.cordapp.CordappProviderImpl
|
import net.corda.node.internal.cordapp.CordappProviderImpl
|
||||||
|
import net.corda.node.internal.cordapp.CordappProviderInternal
|
||||||
import net.corda.node.serialization.NodeClock
|
import net.corda.node.serialization.NodeClock
|
||||||
import net.corda.node.services.api.*
|
import net.corda.node.services.api.*
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
import net.corda.node.services.messaging.MessagingService
|
import net.corda.node.services.messaging.MessagingService
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
|
||||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||||
import net.corda.node.services.statemachine.StateMachineManager
|
import net.corda.node.services.statemachine.StateMachineManager
|
||||||
import net.corda.node.services.transactions.InMemoryTransactionVerifierService
|
import net.corda.node.services.transactions.InMemoryTransactionVerifierService
|
||||||
@ -46,10 +45,9 @@ open class MockServiceHubInternal(
|
|||||||
val mapCache: NetworkMapCacheInternal? = null,
|
val mapCache: NetworkMapCacheInternal? = null,
|
||||||
val scheduler: SchedulerService? = null,
|
val scheduler: SchedulerService? = null,
|
||||||
val overrideClock: Clock? = NodeClock(),
|
val overrideClock: Clock? = NodeClock(),
|
||||||
val schemas: SchemaService? = NodeSchemaService(),
|
|
||||||
val customContractUpgradeService: ContractUpgradeService? = null,
|
val customContractUpgradeService: ContractUpgradeService? = null,
|
||||||
val customTransactionVerifierService: TransactionVerifierService? = InMemoryTransactionVerifierService(2),
|
val customTransactionVerifierService: TransactionVerifierService? = InMemoryTransactionVerifierService(2),
|
||||||
override val cordappProvider: CordappProvider = CordappProviderImpl(CordappLoader.createDefault(Paths.get("."))).start(attachments),
|
override val cordappProvider: CordappProviderInternal = CordappProviderImpl(CordappLoader.createDefault(Paths.get(".")), attachments),
|
||||||
protected val stateLoader: StateLoaderImpl = StateLoaderImpl(validatedTransactions)
|
protected val stateLoader: StateLoaderImpl = StateLoaderImpl(validatedTransactions)
|
||||||
) : ServiceHubInternal, StateLoader by stateLoader {
|
) : ServiceHubInternal, StateLoader by stateLoader {
|
||||||
override val transactionVerifierService: TransactionVerifierService
|
override val transactionVerifierService: TransactionVerifierService
|
||||||
@ -75,8 +73,7 @@ open class MockServiceHubInternal(
|
|||||||
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
|
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
|
||||||
override val rpcFlows: List<Class<out FlowLogic<*>>>
|
override val rpcFlows: List<Class<out FlowLogic<*>>>
|
||||||
get() = throw UnsupportedOperationException()
|
get() = throw UnsupportedOperationException()
|
||||||
override val schemaService: SchemaService
|
override val schemaService get() = throw UnsupportedOperationException()
|
||||||
get() = schemas ?: throw UnsupportedOperationException()
|
|
||||||
override val auditService: AuditService = DummyAuditService()
|
override val auditService: AuditService = DummyAuditService()
|
||||||
|
|
||||||
lateinit var smm: StateMachineManager
|
lateinit var smm: StateMachineManager
|
||||||
|
@ -14,7 +14,6 @@ import net.corda.core.node.NodeInfo
|
|||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
import net.corda.core.node.StateLoader
|
import net.corda.core.node.StateLoader
|
||||||
import net.corda.core.node.services.*
|
import net.corda.core.node.services.*
|
||||||
import net.corda.core.schemas.MappedSchema
|
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
@ -51,7 +50,7 @@ import java.util.*
|
|||||||
* building chains of transactions and verifying them. It isn't sufficient for testing flows however.
|
* building chains of transactions and verifying them. It isn't sufficient for testing flows however.
|
||||||
*/
|
*/
|
||||||
open class MockServices(
|
open class MockServices(
|
||||||
cordappPackages: List<String>,
|
cordappLoader: CordappLoader,
|
||||||
override val validatedTransactions: WritableTransactionStorage,
|
override val validatedTransactions: WritableTransactionStorage,
|
||||||
protected val stateLoader: StateLoaderImpl = StateLoaderImpl(validatedTransactions),
|
protected val stateLoader: StateLoaderImpl = StateLoaderImpl(validatedTransactions),
|
||||||
vararg val keys: KeyPair
|
vararg val keys: KeyPair
|
||||||
@ -101,24 +100,22 @@ open class MockServices(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes database and mock services appropriate for unit tests.
|
* Makes database and mock services appropriate for unit tests.
|
||||||
*
|
* @param keys a list of [KeyPair] instances to be used by [MockServices]. Defualts to [MEGA_CORP_KEY]
|
||||||
* @param customSchemas a set of schemas being used by [NodeSchemaService]
|
|
||||||
* @param keys a lis of [KeyPair] instances to be used by [MockServices]. Defualts to [MEGA_CORP_KEY]
|
|
||||||
* @param createIdentityService a lambda function returning an instance of [IdentityService]. Defauts to [InMemoryIdentityService].
|
* @param createIdentityService a lambda function returning an instance of [IdentityService]. Defauts to [InMemoryIdentityService].
|
||||||
*
|
*
|
||||||
* @return a pair where the first element is the instance of [CordaPersistence] and the second is [MockServices].
|
* @return a pair where the first element is the instance of [CordaPersistence] and the second is [MockServices].
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun makeTestDatabaseAndMockServices(customSchemas: Set<MappedSchema> = emptySet(),
|
fun makeTestDatabaseAndMockServices(keys: List<KeyPair> = listOf(MEGA_CORP_KEY),
|
||||||
keys: List<KeyPair> = listOf(MEGA_CORP_KEY),
|
|
||||||
createIdentityService: () -> IdentityService = { makeTestIdentityService() },
|
createIdentityService: () -> IdentityService = { makeTestIdentityService() },
|
||||||
cordappPackages: List<String> = emptyList()): Pair<CordaPersistence, MockServices> {
|
cordappPackages: List<String> = emptyList()): Pair<CordaPersistence, MockServices> {
|
||||||
|
val cordappLoader = CordappLoader.createWithTestPackages(cordappPackages)
|
||||||
val dataSourceProps = makeTestDataSourceProperties()
|
val dataSourceProps = makeTestDataSourceProperties()
|
||||||
val databaseProperties = makeTestDatabaseProperties()
|
val databaseProperties = makeTestDatabaseProperties()
|
||||||
val identityServiceRef: IdentityService by lazy { createIdentityService() }
|
val identityServiceRef: IdentityService by lazy { createIdentityService() }
|
||||||
val database = configureDatabase(dataSourceProps, databaseProperties, NodeSchemaService(customSchemas), { identityServiceRef })
|
val database = configureDatabase(dataSourceProps, databaseProperties, { identityServiceRef }, NodeSchemaService(cordappLoader))
|
||||||
val mockService = database.transaction {
|
val mockService = database.transaction {
|
||||||
object : MockServices(cordappPackages, *(keys.toTypedArray())) {
|
object : MockServices(cordappLoader, *(keys.toTypedArray())) {
|
||||||
override val identityService: IdentityService = database.transaction { identityServiceRef }
|
override val identityService: IdentityService = database.transaction { identityServiceRef }
|
||||||
override val vaultService = makeVaultService(database.hibernateConfig)
|
override val vaultService = makeVaultService(database.hibernateConfig)
|
||||||
|
|
||||||
@ -137,7 +134,8 @@ open class MockServices(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(cordappPackages: List<String>, vararg keys: KeyPair) : this(cordappPackages, MockTransactionStorage(), keys = *keys)
|
private constructor(cordappLoader: CordappLoader, vararg keys: KeyPair) : this(cordappLoader, MockTransactionStorage(), keys = *keys)
|
||||||
|
constructor(cordappPackages: List<String>, vararg keys: KeyPair) : this(CordappLoader.createWithTestPackages(cordappPackages), keys = *keys)
|
||||||
constructor(vararg keys: KeyPair) : this(emptyList(), *keys)
|
constructor(vararg keys: KeyPair) : this(emptyList(), *keys)
|
||||||
constructor() : this(generateKeyPair())
|
constructor() : this(generateKeyPair())
|
||||||
|
|
||||||
@ -167,11 +165,11 @@ open class MockServices(
|
|||||||
return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L)
|
return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L)
|
||||||
}
|
}
|
||||||
override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2)
|
override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2)
|
||||||
val mockCordappProvider = MockCordappProvider(CordappLoader.createWithTestPackages(cordappPackages)).start(attachments) as MockCordappProvider
|
val mockCordappProvider = MockCordappProvider(cordappLoader, attachments)
|
||||||
override val cordappProvider: CordappProvider get() = mockCordappProvider
|
override val cordappProvider: CordappProvider get() = mockCordappProvider
|
||||||
lateinit var hibernatePersister: HibernateObserver
|
lateinit var hibernatePersister: HibernateObserver
|
||||||
|
|
||||||
fun makeVaultService(hibernateConfig: HibernateConfiguration = HibernateConfiguration(NodeSchemaService(), makeTestDatabaseProperties(), { identityService })): VaultServiceInternal {
|
fun makeVaultService(hibernateConfig: HibernateConfiguration): VaultServiceInternal {
|
||||||
val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, stateLoader, hibernateConfig)
|
val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, stateLoader, hibernateConfig)
|
||||||
hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig)
|
hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig)
|
||||||
return vaultService
|
return vaultService
|
||||||
|
@ -37,7 +37,7 @@ class SimpleNode(val config: NodeConfiguration, val address: NetworkHostAndPort
|
|||||||
val monitoringService = MonitoringService(MetricRegistry())
|
val monitoringService = MonitoringService(MetricRegistry())
|
||||||
val identity: KeyPair = generateKeyPair()
|
val identity: KeyPair = generateKeyPair()
|
||||||
val identityService: IdentityService = InMemoryIdentityService(trustRoot = trustRoot)
|
val identityService: IdentityService = InMemoryIdentityService(trustRoot = trustRoot)
|
||||||
val database: CordaPersistence = configureDatabase(config.dataSourceProperties, config.database, NodeSchemaService(), { InMemoryIdentityService(trustRoot = trustRoot) })
|
val database: CordaPersistence = configureDatabase(config.dataSourceProperties, config.database, { InMemoryIdentityService(trustRoot = trustRoot) })
|
||||||
val keyService: KeyManagementService = E2ETestKeyManagementService(identityService, setOf(identity))
|
val keyService: KeyManagementService = E2ETestKeyManagementService(identityService, setOf(identity))
|
||||||
val executor = ServiceAffinityExecutor(config.myLegalName.organisation, 1)
|
val executor = ServiceAffinityExecutor(config.myLegalName.organisation, 1)
|
||||||
// TODO: We should have a dummy service hub rather than change behaviour in tests
|
// TODO: We should have a dummy service hub rather than change behaviour in tests
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.corda.testing
|
package net.corda.testing
|
||||||
|
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import org.apache.logging.log4j.Level
|
import org.apache.logging.log4j.Level
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import org.apache.logging.log4j.core.LoggerContext
|
import org.apache.logging.log4j.core.LoggerContext
|
||||||
@ -25,7 +26,7 @@ object LogHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setLevel(vararg classes: KClass<*>) = setLevel(*classes.map { "+" + it.java.`package`.name }.toTypedArray())
|
fun setLevel(vararg classes: KClass<*>) = setLevel(*classes.map { "+" + it.packageName }.toTypedArray())
|
||||||
|
|
||||||
/** Removes custom configuration for the specified logger names */
|
/** Removes custom configuration for the specified logger names */
|
||||||
fun reset(vararg names: String) {
|
fun reset(vararg names: String) {
|
||||||
@ -35,7 +36,7 @@ object LogHelper {
|
|||||||
loggerContext.updateLoggers(config)
|
loggerContext.updateLoggers(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset(vararg classes: KClass<*>) = reset(*classes.map { it.java.`package`.name }.toTypedArray())
|
fun reset(vararg classes: KClass<*>) = reset(*classes.map { it.packageName }.toTypedArray())
|
||||||
|
|
||||||
/** Updates logging level for the specified Log4j logger name */
|
/** Updates logging level for the specified Log4j logger name */
|
||||||
private fun setLevel(name: String, level: Level) {
|
private fun setLevel(name: String, level: Level) {
|
||||||
|
@ -4,12 +4,13 @@ import net.corda.core.contracts.ContractClassName
|
|||||||
import net.corda.core.cordapp.Cordapp
|
import net.corda.core.cordapp.Cordapp
|
||||||
import net.corda.core.internal.cordapp.CordappImpl
|
import net.corda.core.internal.cordapp.CordappImpl
|
||||||
import net.corda.core.node.services.AttachmentId
|
import net.corda.core.node.services.AttachmentId
|
||||||
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
import net.corda.node.internal.cordapp.CordappLoader
|
import net.corda.node.internal.cordapp.CordappLoader
|
||||||
import net.corda.node.internal.cordapp.CordappProviderImpl
|
import net.corda.node.internal.cordapp.CordappProviderImpl
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MockCordappProvider(cordappLoader: CordappLoader) : CordappProviderImpl(cordappLoader) {
|
class MockCordappProvider(cordappLoader: CordappLoader, attachmentStorage: AttachmentStorage) : CordappProviderImpl(cordappLoader, attachmentStorage) {
|
||||||
val cordappRegistry = mutableListOf<Pair<Cordapp, AttachmentId>>()
|
val cordappRegistry = mutableListOf<Pair<Cordapp, AttachmentId>>()
|
||||||
|
|
||||||
fun addMockCordapp(contractClassName: ContractClassName, attachments: MockAttachmentStorage) {
|
fun addMockCordapp(contractClassName: ContractClassName, attachments: MockAttachmentStorage) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user