Feature/corda 1847/remove hibernate observers (#3696)

* CORDA-1847 Fix hibernate observer issue

* CORDA-1847 Fix hibernate observer issue

* CORDA-1847 Fix hibernate observer issue

* CORDA-1847 Fix tests

* CORDA-1847 Fix tests

* CORDA-1847 Fix tests
This commit is contained in:
Tudor Malene
2018-07-31 13:52:13 +01:00
committed by GitHub
parent 4542e0cd06
commit 85caa9ee9d
28 changed files with 83 additions and 91 deletions

View File

@ -35,7 +35,7 @@ class IdentitySyncFlowTests {
fun before() { fun before() {
// We run this in parallel threads to help catch any race conditions that may exist. // We run this in parallel threads to help catch any race conditions that may exist.
mockNet = InternalMockNetwork( mockNet = InternalMockNetwork(
cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts.asset"), cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts.asset", "net.corda.finance.schemas"),
networkSendManuallyPumped = false, networkSendManuallyPumped = false,
threadPerNode = true threadPerNode = true
) )

View File

@ -12,6 +12,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.excludeHostNode import net.corda.core.identity.excludeHostNode
import net.corda.core.identity.groupAbstractPartyByWellKnownParty import net.corda.core.identity.groupAbstractPartyByWellKnownParty
import net.corda.core.node.services.IdentityService
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
@ -27,7 +28,7 @@ import org.junit.Test
class CollectSignaturesFlowTests : WithContracts { class CollectSignaturesFlowTests : WithContracts {
companion object { companion object {
private val miniCorp = TestIdentity(CordaX500Name("MiniCorp", "London", "GB")) private val miniCorp = TestIdentity(CordaX500Name("MiniCorp", "London", "GB"))
private val miniCorpServices = MockServices(listOf("net.corda.testing.contracts"), miniCorp, rigorousMock()) private val miniCorpServices = MockServices(listOf("net.corda.testing.contracts"), miniCorp, rigorousMock<IdentityService>())
private val classMockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts", "net.corda.core.flows")) private val classMockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts", "net.corda.core.flows"))
private const val MAGIC_NUMBER = 1337 private const val MAGIC_NUMBER = 1337

View File

@ -33,7 +33,7 @@ import java.util.*
class ContractUpgradeFlowTest : WithContracts, WithFinality { class ContractUpgradeFlowTest : WithContracts, WithFinality {
companion object { companion object {
private val classMockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows")) private val classMockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows", "net.corda.finance.schemas"))
@JvmStatic @JvmStatic
@AfterClass @AfterClass

View File

@ -21,7 +21,7 @@ import org.junit.Test
class FinalityFlowTests : WithFinality { class FinalityFlowTests : WithFinality {
companion object { companion object {
private val CHARLIE = TestIdentity(CHARLIE_NAME, 90).party private val CHARLIE = TestIdentity(CHARLIE_NAME, 90).party
private val classMockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts.asset")) private val classMockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts.asset","net.corda.finance.schemas"))
@JvmStatic @JvmStatic
@AfterClass @AfterClass

View File

@ -18,9 +18,7 @@ import net.corda.testing.node.User;
import org.junit.Test; import org.junit.Test;
import rx.Observable; import rx.Observable;
import java.util.Currency; import java.util.*;
import java.util.HashSet;
import java.util.List;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
@ -40,7 +38,7 @@ public class JavaIntegrationTestingTutorial {
// START 1 // START 1
driver(new DriverParameters() driver(new DriverParameters()
.withStartNodesInProcess(true) .withStartNodesInProcess(true)
.withExtraCordappPackagesToScan(singletonList("net.corda.finance.contracts.asset")), dsl -> { .withExtraCordappPackagesToScan(Arrays.asList("net.corda.finance.contracts.asset", "net.corda.finance.schemas")), dsl -> {
User aliceUser = new User("aliceUser", "testPassword1", new HashSet<>(asList( User aliceUser = new User("aliceUser", "testPassword1", new HashSet<>(asList(
startFlow(CashIssueAndPaymentFlow.class), startFlow(CashIssueAndPaymentFlow.class),

View File

@ -31,7 +31,7 @@ class KotlinIntegrationTestingTutorial {
// START 1 // START 1
driver(DriverParameters( driver(DriverParameters(
startNodesInProcess = true, startNodesInProcess = true,
extraCordappPackagesToScan = listOf("net.corda.finance.contracts.asset") extraCordappPackagesToScan = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas")
)) { )) {
val aliceUser = User("aliceUser", "testPassword1", permissions = setOf( val aliceUser = User("aliceUser", "testPassword1", permissions = setOf(
startFlow<CashIssueAndPaymentFlow>(), startFlow<CashIssueAndPaymentFlow>(),

View File

@ -109,7 +109,7 @@ class CommercialPaperTestsGeneric {
val testSerialization = SerializationEnvironmentRule() val testSerialization = SerializationEnvironmentRule()
private val megaCorpRef = megaCorp.ref(123) private val megaCorpRef = megaCorp.ref(123)
private val ledgerServices = MockServices(megaCorp, miniCorp) private val ledgerServices = MockServices(listOf("net.corda.finance.schemas"), megaCorp, miniCorp)
@Test @Test
fun `trade lifecycle test`() { fun `trade lifecycle test`() {
@ -245,10 +245,10 @@ class CommercialPaperTestsGeneric {
// of the dummy cash issuer. // of the dummy cash issuer.
val allIdentities = arrayOf(megaCorp.identity, alice.identity, dummyCashIssuer.identity, dummyNotary.identity) val allIdentities = arrayOf(megaCorp.identity, alice.identity, dummyCashIssuer.identity, dummyNotary.identity)
val notaryServices = MockServices(dummyNotary) val notaryServices = MockServices(listOf("net.corda.finance.contracts", "net.corda.finance.contracts.asset", "net.corda.finance.schemas"), dummyNotary)
val issuerServices = MockServices(dummyCashIssuer, dummyNotary) val issuerServices = MockServices(listOf("net.corda.finance.contracts", "net.corda.finance.contracts.asset", "net.corda.finance.schemas"), dummyCashIssuer, dummyNotary)
val (aliceDatabase, aliceServices) = makeTestDatabaseAndMockServices( val (aliceDatabase, aliceServices) = makeTestDatabaseAndMockServices(
listOf("net.corda.finance.contracts"), listOf("net.corda.finance.contracts", "net.corda.finance.contracts.asset", "net.corda.finance.schemas"),
makeTestIdentityService(*allIdentities), makeTestIdentityService(*allIdentities),
alice alice
) )
@ -257,7 +257,7 @@ class CommercialPaperTestsGeneric {
} }
val (megaCorpDatabase, megaCorpServices) = makeTestDatabaseAndMockServices( val (megaCorpDatabase, megaCorpServices) = makeTestDatabaseAndMockServices(
listOf("net.corda.finance.contracts"), listOf("net.corda.finance.contracts", "net.corda.finance.contracts.asset", "net.corda.finance.schemas"),
makeTestIdentityService(*allIdentities), makeTestIdentityService(*allIdentities),
megaCorp megaCorp
) )

View File

@ -79,12 +79,13 @@ class CashTests {
// TODO: Optimise this so that we don't throw away and rebuild state that can be shared across tests. // TODO: Optimise this so that we don't throw away and rebuild state that can be shared across tests.
@Before @Before
fun setUp() { fun setUp() {
val cordapps = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas")
LogHelper.setLevel(NodeVaultService::class) LogHelper.setLevel(NodeVaultService::class)
megaCorpServices = MockServices(megaCorp) megaCorpServices = MockServices(cordapps, megaCorp)
miniCorpServices = MockServices(miniCorp) miniCorpServices = MockServices(cordapps, miniCorp)
val myself = TestIdentity(CordaX500Name("Me", "London", "GB")) val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
val databaseAndServices = makeTestDatabaseAndMockServices( val databaseAndServices = makeTestDatabaseAndMockServices(
listOf("net.corda.finance.contracts.asset"), cordapps,
makeTestIdentityService(megaCorp.identity, miniCorp.identity, dummyCashIssuer.identity, dummyNotary.identity, myself.identity), makeTestIdentityService(megaCorp.identity, miniCorp.identity, dummyCashIssuer.identity, dummyNotary.identity, myself.identity),
myself myself
) )

View File

@ -9,6 +9,7 @@ import net.corda.core.crypto.sha256
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.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.IdentityService
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.NonEmptySet import net.corda.core.utilities.NonEmptySet
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
@ -80,7 +81,7 @@ class ObligationTests {
beneficiary = CHARLIE beneficiary = CHARLIE
) )
private val outState = inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY)) private val outState = inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY))
private val miniCorpServices = MockServices(listOf("net.corda.finance.contracts.asset"), miniCorp, rigorousMock()) private val miniCorpServices = MockServices(listOf("net.corda.finance.contracts.asset"), miniCorp, rigorousMock<IdentityService>())
private val notaryServices = MockServices(emptyList(), MEGA_CORP.name, rigorousMock(), dummyNotary.keyPair) private val notaryServices = MockServices(emptyList(), MEGA_CORP.name, rigorousMock(), dummyNotary.keyPair)
private val identityService = rigorousMock<IdentityServiceInternal>().also { private val identityService = rigorousMock<IdentityServiceInternal>().also {
doReturn(null).whenever(it).partyFromKey(ALICE_PUBKEY) doReturn(null).whenever(it).partyFromKey(ALICE_PUBKEY)

View File

@ -27,7 +27,7 @@ class CashExitFlowTests {
@Before @Before
fun start() { fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("net.corda.finance.contracts.asset")) cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME) bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME) bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity notary = mockNet.defaultNotaryIdentity

View File

@ -24,7 +24,7 @@ class CashIssueFlowTests {
@Before @Before
fun start() { fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset")) mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts", "net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME) bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME) bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity notary = mockNet.defaultNotaryIdentity

View File

@ -29,7 +29,7 @@ class CashPaymentFlowTests {
@Before @Before
fun start() { fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset")) mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME) bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME) bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
aliceNode = mockNet.createPartyNode(ALICE_NAME) aliceNode = mockNet.createPartyNode(ALICE_NAME)

View File

@ -33,6 +33,8 @@ class FlowCheckpointVersionNodeStartupCheckTest {
val classes = setOf(net.corda.testMessage.MessageState::class.java, val classes = setOf(net.corda.testMessage.MessageState::class.java,
net.corda.testMessage.MessageContract::class.java, net.corda.testMessage.MessageContract::class.java,
net.test.cordapp.v1.SendMessageFlow::class.java, net.test.cordapp.v1.SendMessageFlow::class.java,
net.corda.testMessage.MessageSchema::class.java,
net.corda.testMessage.MessageSchemaV1::class.java,
net.test.cordapp.v1.Record::class.java) net.test.cordapp.v1.Record::class.java)
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery"), invokeRpc("vaultTrack"))) val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery"), invokeRpc("vaultTrack")))
} }

View File

@ -42,7 +42,7 @@ class DistributedServiceTests {
invokeRpc(CordaRPCOps::stateMachinesFeed)) invokeRpc(CordaRPCOps::stateMachinesFeed))
) )
driver(DriverParameters( driver(DriverParameters(
extraCordappPackagesToScan = listOf("net.corda.finance.contracts"), extraCordappPackagesToScan = listOf("net.corda.finance.contracts", "net.corda.finance.schemas"),
notarySpecs = listOf( notarySpecs = listOf(
NotarySpec( NotarySpec(
DUMMY_NOTARY_NAME, DUMMY_NOTARY_NAME,

View File

@ -53,7 +53,6 @@ import net.corda.node.services.messaging.DeduplicationHandler
import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.network.* import net.corda.node.services.network.*
import net.corda.node.services.persistence.* import net.corda.node.services.persistence.*
import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.statemachine.* import net.corda.node.services.statemachine.*
import net.corda.node.services.transactions.* import net.corda.node.services.transactions.*
@ -334,7 +333,6 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
contractUpgradeService.start() contractUpgradeService.start()
vaultService.start() vaultService.start()
ScheduledActivityObserver.install(vaultService, schedulerService, flowLogicRefFactory) ScheduledActivityObserver.install(vaultService, schedulerService, flowLogicRefFactory)
HibernateObserver.install(vaultService.rawUpdates, database.hibernateConfig, schemaService)
val frozenTokenizableServices = tokenizableServices!! val frozenTokenizableServices = tokenizableServices!!
tokenizableServices = null tokenizableServices = null
@ -864,7 +862,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
protected open fun makeVaultService(keyManagementService: KeyManagementService, protected open fun makeVaultService(keyManagementService: KeyManagementService,
services: ServicesForResolution, services: ServicesForResolution,
database: CordaPersistence): VaultServiceInternal { database: CordaPersistence): VaultServiceInternal {
return NodeVaultService(platformClock, keyManagementService, services, database) return NodeVaultService(platformClock, keyManagementService, services, database, schemaService)
} }
/** Load configured JVM agents */ /** Load configured JVM agents */

View File

@ -4,16 +4,12 @@ import net.corda.core.contracts.ContractState
import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.VisibleForTesting
import net.corda.core.node.services.Vault
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentStateRef import net.corda.core.schemas.PersistentStateRef
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
import net.corda.node.services.api.SchemaService import net.corda.node.services.api.SchemaService
import net.corda.nodeapi.internal.persistence.HibernateConfiguration import net.corda.nodeapi.internal.persistence.currentDBSession
import net.corda.nodeapi.internal.persistence.contextTransaction
import org.hibernate.FlushMode
import rx.Observable
/** /**
* Small data class bundling together a ContractState and a StateRef (as opposed to a TransactionState and StateRef * Small data class bundling together a ContractState and a StateRef (as opposed to a TransactionState and StateRef
@ -25,17 +21,12 @@ data class ContractStateAndRef(val state: ContractState, val ref: StateRef)
* A vault observer that extracts Object Relational Mappings for contract states that support it, and persists them with Hibernate. * A vault observer that extracts Object Relational Mappings for contract states that support it, and persists them with Hibernate.
*/ */
// TODO: Manage version evolution of the schemas via additional tooling. // TODO: Manage version evolution of the schemas via additional tooling.
class HibernateObserver private constructor(private val config: HibernateConfiguration, private val schemaService: SchemaService) { class PersistentStateService(private val schemaService: SchemaService) {
companion object { companion object {
private val log = contextLogger() private val log = contextLogger()
fun install(vaultUpdates: Observable<Vault.Update<ContractState>>, config: HibernateConfiguration, schemaService: SchemaService): HibernateObserver {
val observer = HibernateObserver(config, schemaService)
vaultUpdates.subscribe { observer.persist(it.produced) }
return observer
}
} }
private fun persist(produced: Set<StateAndRef<ContractState>>) { fun persist(produced: Set<StateAndRef<ContractState>>) {
val stateBySchema: MutableMap<MappedSchema, MutableList<ContractStateAndRef>> = mutableMapOf() val stateBySchema: MutableMap<MappedSchema, MutableList<ContractStateAndRef>> = mutableMapOf()
// map all states by their referenced schemas // map all states by their referenced schemas
produced.forEach { produced.forEach {
@ -51,15 +42,10 @@ class HibernateObserver private constructor(private val config: HibernateConfigu
@VisibleForTesting @VisibleForTesting
internal fun persistStatesWithSchema(statesAndRefs: List<ContractStateAndRef>, schema: MappedSchema) { internal fun persistStatesWithSchema(statesAndRefs: List<ContractStateAndRef>, schema: MappedSchema) {
val sessionFactory = config.sessionFactoryForSchemas(setOf(schema)) statesAndRefs.forEach {
val session = sessionFactory.withOptions().connection(contextTransaction.connection).flushMode(FlushMode.MANUAL).openSession() val mappedObject = schemaService.generateMappedObject(it.state, schema)
session.use { thisSession -> mappedObject.stateRef = PersistentStateRef(it.ref)
statesAndRefs.forEach { currentDBSession().persist(mappedObject)
val mappedObject = schemaService.generateMappedObject(it.state, schema)
mappedObject.stateRef = PersistentStateRef(it.ref)
thisSession.persist(mappedObject)
}
thisSession.flush()
} }
} }
} }

View File

@ -14,12 +14,11 @@ import net.corda.core.schemas.PersistentStateRef
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.* import net.corda.core.transactions.*
import net.corda.core.utilities.* import net.corda.core.utilities.*
import net.corda.node.services.api.SchemaService
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.schema.PersistentStateService
import net.corda.node.services.statemachine.FlowStateMachineImpl import net.corda.node.services.statemachine.FlowStateMachineImpl
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.*
import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
import net.corda.nodeapi.internal.persistence.currentDBSession
import net.corda.nodeapi.internal.persistence.wrapWithDatabaseTransaction
import org.hibernate.Session import org.hibernate.Session
import rx.Observable import rx.Observable
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
@ -51,7 +50,8 @@ class NodeVaultService(
private val clock: Clock, private val clock: Clock,
private val keyManagementService: KeyManagementService, private val keyManagementService: KeyManagementService,
private val servicesForResolution: ServicesForResolution, private val servicesForResolution: ServicesForResolution,
private val database: CordaPersistence private val database: CordaPersistence,
private val schemaService: SchemaService
) : SingletonSerializeAsToken(), VaultServiceInternal { ) : SingletonSerializeAsToken(), VaultServiceInternal {
private companion object { private companion object {
private val log = contextLogger() private val log = contextLogger()
@ -68,6 +68,7 @@ class NodeVaultService(
private val mutex = ThreadBox(InnerState()) private val mutex = ThreadBox(InnerState())
private lateinit var criteriaBuilder: CriteriaBuilder private lateinit var criteriaBuilder: CriteriaBuilder
private val persistentStateService = PersistentStateService(schemaService)
/** /**
* 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
@ -247,6 +248,7 @@ class NodeVaultService(
softLockReserve(uuid, stateRefs) softLockReserve(uuid, stateRefs)
} }
} }
persistentStateService.persist(vaultUpdate.produced)
updatesPublisher.onNext(vaultUpdate) updatesPublisher.onNext(vaultUpdate)
} }
} }

View File

@ -81,7 +81,7 @@ class CordaRPCOpsImplTest {
@Before @Before
fun setup() { fun setup() {
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts.asset")) mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
aliceNode = mockNet.createNode(InternalMockNodeParameters(legalName = ALICE_NAME)) aliceNode = mockNet.createNode(InternalMockNodeParameters(legalName = ALICE_NAME))
rpc = aliceNode.rpcOps rpc = aliceNode.rpcOps
CURRENT_RPC_CONTEXT.set(RpcAuthContext(InvocationContext.rpc(testActor()), buildSubject("TEST_USER", emptySet()))) CURRENT_RPC_CONTEXT.set(RpcAuthContext(InvocationContext.rpc(testActor()), buildSubject("TEST_USER", emptySet())))

View File

@ -74,7 +74,7 @@ import kotlin.test.assertTrue
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class TwoPartyTradeFlowTests(private val anonymous: Boolean) { class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
companion object { companion object {
private val cordappPackages = setOf("net.corda.finance.contracts") private val cordappPackages = listOf("net.corda.finance.contracts", "net.corda.finance.schemas")
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "Anonymous = {0}") @Parameterized.Parameters(name = "Anonymous = {0}")
fun data(): Collection<Boolean> = listOf(true, false) fun data(): Collection<Boolean> = listOf(true, false)

View File

@ -25,7 +25,7 @@ import java.util.concurrent.CountDownLatch
class ServiceHubConcurrentUsageTest { class ServiceHubConcurrentUsageTest {
private val mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(Cash::class.packageName)) private val mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.finance.schemas", "net.corda.node.services.vault.VaultQueryExceptionsTests", Cash::class.packageName))
@After @After
fun stopNodes() { fun stopNodes() {

View File

@ -24,6 +24,7 @@ import net.corda.finance.SWISS_FRANCS
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.DummyFungibleContract import net.corda.finance.contracts.asset.DummyFungibleContract
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV2 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
@ -31,7 +32,7 @@ import net.corda.node.internal.configureDatabase
import net.corda.node.services.api.IdentityServiceInternal import net.corda.node.services.api.IdentityServiceInternal
import net.corda.node.services.api.WritableTransactionStorage import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.schema.ContractStateAndRef import net.corda.node.services.schema.ContractStateAndRef
import net.corda.node.services.schema.HibernateObserver import net.corda.node.services.schema.PersistentStateService
import net.corda.node.services.schema.NodeSchemaService import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.NodeVaultService
import net.corda.node.services.vault.VaultSchemaV1 import net.corda.node.services.vault.VaultSchemaV1
@ -40,6 +41,7 @@ import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.testing.core.* import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.vault.DummyDealStateSchemaV1
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1 import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
import net.corda.testing.internal.vault.DummyLinearStateSchemaV2 import net.corda.testing.internal.vault.DummyLinearStateSchemaV2
import net.corda.testing.internal.vault.VaultFiller import net.corda.testing.internal.vault.VaultFiller
@ -81,7 +83,7 @@ class HibernateConfigurationTest {
// Hibernate configuration objects // Hibernate configuration objects
lateinit var hibernateConfig: HibernateConfiguration lateinit var hibernateConfig: HibernateConfiguration
private lateinit var hibernatePersister: HibernateObserver private lateinit var hibernatePersister: PersistentStateService
private lateinit var sessionFactory: SessionFactory private lateinit var sessionFactory: SessionFactory
private lateinit var entityManager: EntityManager private lateinit var entityManager: EntityManager
private lateinit var criteriaBuilder: CriteriaBuilder private lateinit var criteriaBuilder: CriteriaBuilder
@ -96,10 +98,10 @@ class HibernateConfigurationTest {
@Before @Before
fun setUp() { fun setUp() {
val cordappPackages = listOf("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset") val cordappPackages = listOf("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset", "net.corda.finance.schemas")
bankServices = MockServices(cordappPackages, BOC.name, rigorousMock(), BOC_KEY) bankServices = MockServices(cordappPackages, BOC.name, rigorousMock(), BOC_KEY)
issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock()) issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock<IdentityService>())
notaryServices = MockServices(cordappPackages, dummyNotary, rigorousMock()) notaryServices = MockServices(cordappPackages, dummyNotary, rigorousMock<IdentityService>())
notary = notaryServices.myInfo.singleIdentity() notary = notaryServices.myInfo.singleIdentity()
val dataSourceProps = makeTestDataSourceProperties() val dataSourceProps = makeTestDataSourceProperties()
val identityService = rigorousMock<IdentityService>().also { mock -> val identityService = rigorousMock<IdentityService>().also { mock ->
@ -109,7 +111,7 @@ class HibernateConfigurationTest {
doReturn(it.party).whenever(mock).wellKnownPartyFromX500Name(it.name) doReturn(it.party).whenever(mock).wellKnownPartyFromX500Name(it.name)
} }
} }
val schemaService = NodeSchemaService() val schemaService = NodeSchemaService(extraSchemas = setOf(CashSchemaV1, SampleCashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3, DummyLinearStateSchemaV1, DummyLinearStateSchemaV2, DummyDealStateSchemaV1))
database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService) database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService)
database.transaction { database.transaction {
hibernateConfig = database.hibernateConfig hibernateConfig = database.hibernateConfig
@ -118,7 +120,7 @@ class HibernateConfigurationTest {
services = object : MockServices(cordappPackages, BOB_NAME, rigorousMock<IdentityServiceInternal>().also { services = object : MockServices(cordappPackages, BOB_NAME, rigorousMock<IdentityServiceInternal>().also {
doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == BOB_NAME }) doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == BOB_NAME })
}, generateKeyPair(), dummyNotary.keyPair) { }, generateKeyPair(), dummyNotary.keyPair) {
override val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, servicesForResolution, database).apply { start() } override val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, servicesForResolution, database, schemaService).apply { start() }
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) { override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
for (stx in txs) { for (stx in txs) {
(validatedTransactions as WritableTransactionStorage).addTransaction(stx) (validatedTransactions as WritableTransactionStorage).addTransaction(stx)
@ -130,7 +132,7 @@ class HibernateConfigurationTest {
override fun jdbcSession() = database.createSession() override fun jdbcSession() = database.createSession()
} }
vaultFiller = VaultFiller(services, dummyNotary, notary, ::Random) vaultFiller = VaultFiller(services, dummyNotary, notary, ::Random)
hibernatePersister = HibernateObserver.install(services.vaultService.rawUpdates, hibernateConfig, schemaService) hibernatePersister = PersistentStateService(schemaService)
} }
identity = services.myInfo.singleIdentity() identity = services.myInfo.singleIdentity()

View File

@ -14,25 +14,28 @@ import net.corda.core.schemas.QueryableState
import net.corda.node.services.api.SchemaService import net.corda.node.services.api.SchemaService
import net.corda.node.internal.configureDatabase import net.corda.node.internal.configureDatabase
import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.currentDBSession
import net.corda.testing.internal.LogHelper import net.corda.testing.internal.LogHelper
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Ignore
import org.junit.Test import org.junit.Test
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import kotlin.test.assertEquals import kotlin.test.assertEquals
class HibernateObserverTests { class PersistentStateServiceTests {
@Before @Before
fun setUp() { fun setUp() {
LogHelper.setLevel(HibernateObserver::class) LogHelper.setLevel(PersistentStateService::class)
} }
@After @After
fun cleanUp() { fun cleanUp() {
LogHelper.reset(HibernateObserver::class) LogHelper.reset(PersistentStateService::class)
} }
class TestState : QueryableState { class TestState : QueryableState {
@ -51,9 +54,8 @@ class HibernateObserverTests {
@Test @Test
fun `test child objects are persisted`() { fun `test child objects are persisted`() {
val testSchema = TestSchema val testSchema = TestSchema
val rawUpdatesPublisher = PublishSubject.create<Vault.Update<ContractState>>()
val schemaService = object : SchemaService { val schemaService = object : SchemaService {
override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = emptyMap() override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = mapOf(testSchema to SchemaService.SchemaOptions())
override fun selectSchemas(state: ContractState): Iterable<MappedSchema> = setOf(testSchema) override fun selectSchemas(state: ContractState): Iterable<MappedSchema> = setOf(testSchema)
@ -64,11 +66,12 @@ class HibernateObserverTests {
return parent return parent
} }
} }
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), { null }, { null }, schemaService) val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock(), rigorousMock(), schemaService)
HibernateObserver.install(rawUpdatesPublisher, database.hibernateConfig, schemaService) val persistentStateService = PersistentStateService(schemaService)
database.transaction { database.transaction {
val MEGA_CORP = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")).party val MEGA_CORP = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")).party
rawUpdatesPublisher.onNext(Vault.Update(emptySet(), setOf(StateAndRef(TransactionState(TestState(), DummyContract.PROGRAM_ID, MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0))))) persistentStateService.persist(setOf(StateAndRef(TransactionState(TestState(), DummyContract.PROGRAM_ID, MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0))))
currentDBSession().flush()
val parentRowCountResult = connection.prepareStatement("select count(*) from Parents").executeQuery() val parentRowCountResult = connection.prepareStatement("select count(*) from Parents").executeQuery()
parentRowCountResult.next() parentRowCountResult.next()
val parentRows = parentRowCountResult.getInt(1) val parentRows = parentRowCountResult.getInt(1)

View File

@ -11,10 +11,7 @@ import net.corda.core.identity.*
import net.corda.core.internal.NotaryChangeTransactionBuilder import net.corda.core.internal.NotaryChangeTransactionBuilder
import net.corda.core.internal.packageName import net.corda.core.internal.packageName
import net.corda.core.node.StatesToRecord import net.corda.core.node.StatesToRecord
import net.corda.core.node.services.StatesNotAvailableException import net.corda.core.node.services.*
import net.corda.core.node.services.Vault
import net.corda.core.node.services.VaultService
import net.corda.core.node.services.queryBy
import net.corda.core.node.services.vault.PageSpecification import net.corda.core.node.services.vault.PageSpecification
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.*
@ -97,8 +94,8 @@ class NodeVaultServiceTest {
vaultFiller = VaultFiller(services, dummyNotary) vaultFiller = VaultFiller(services, dummyNotary)
// This is safe because MockServices only ever have a single identity // This is safe because MockServices only ever have a single identity
identity = services.myInfo.singleIdentityAndCert() identity = services.myInfo.singleIdentityAndCert()
issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock()) issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock<IdentityService>())
bocServices = MockServices(cordappPackages, bankOfCorda, rigorousMock()) bocServices = MockServices(cordappPackages, bankOfCorda, rigorousMock<IdentityService>())
services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY) services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY)
services.identityService.verifyAndRegisterIdentity(BOC_IDENTITY) services.identityService.verifyAndRegisterIdentity(BOC_IDENTITY)
} }

View File

@ -23,8 +23,7 @@ class VaultQueryExceptionsTests : VaultQueryParties by rule {
override val cordappPackages = listOf( override val cordappPackages = listOf(
"net.corda.testing.contracts", "net.corda.testing.contracts",
"net.corda.finance.contracts", "net.corda.finance.contracts",
CashSchemaV1::class.packageName, DummyLinearStateSchemaV1::class.packageName)
DummyLinearStateSchemaV1::class.packageName) - SampleCashSchemaV3::class.packageName
} }
} }
@ -43,9 +42,6 @@ class VaultQueryExceptionsTests : VaultQueryParties by rule {
@Test @Test
fun `query attempting to use unregistered schema`() { fun `query attempting to use unregistered schema`() {
database.transaction { database.transaction {
vaultFiller.fillWithSomeTestCash(100.DOLLARS, notaryServices, 1, DUMMY_CASH_ISSUER)
vaultFiller.fillWithSomeTestCash(100.POUNDS, notaryServices, 1, DUMMY_CASH_ISSUER)
vaultFiller.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, 1, DUMMY_CASH_ISSUER)
// CashSchemaV3 NOT registered with NodeSchemaService // CashSchemaV3 NOT registered with NodeSchemaService
val logicalExpression = builder { SampleCashSchemaV3.PersistentCashState::currency.equal(GBP.currencyCode) } val logicalExpression = builder { SampleCashSchemaV3.PersistentCashState::currency.equal(GBP.currencyCode) }
val criteria = VaultCustomQueryCriteria(logicalExpression) val criteria = VaultCustomQueryCriteria(logicalExpression)

View File

@ -24,6 +24,7 @@ import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.services.api.SchemaService
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity

View File

@ -45,7 +45,7 @@ import kotlin.test.fail
class VaultWithCashTest { class VaultWithCashTest {
private companion object { private companion object {
val cordappPackages = listOf("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset", CashSchemaV1::class.packageName) val cordappPackages = listOf("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset", CashSchemaV1::class.packageName, "net.corda.core.contracts")
val BOB = TestIdentity(BOB_NAME, 80).party val BOB = TestIdentity(BOB_NAME, 80).party
val dummyCashIssuer = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10) val dummyCashIssuer = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10)
val DUMMY_CASH_ISSUER = dummyCashIssuer.ref(1) val DUMMY_CASH_ISSUER = dummyCashIssuer.ref(1)
@ -83,7 +83,7 @@ class VaultWithCashTest {
services = databaseAndServices.second services = databaseAndServices.second
vaultFiller = VaultFiller(services, dummyNotary) vaultFiller = VaultFiller(services, dummyNotary)
issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock(), MEGA_CORP_KEY) issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock(), MEGA_CORP_KEY)
notaryServices = MockServices(cordappPackages, dummyNotary, rigorousMock()) notaryServices = MockServices(cordappPackages, dummyNotary, rigorousMock<IdentityService>())
notary = notaryServices.myInfo.legalIdentitiesAndCerts.single().party notary = notaryServices.myInfo.legalIdentitiesAndCerts.single().party
} }

View File

@ -3,6 +3,7 @@ package net.corda.traderdemo
import net.corda.core.contracts.CommandData import net.corda.core.contracts.CommandData
import net.corda.core.crypto.newSecureRandom import net.corda.core.crypto.newSecureRandom
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.IdentityService
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
@ -46,8 +47,8 @@ class TransactionGraphSearchTests {
* @param signer signer for the two transactions and their commands. * @param signer signer for the two transactions and their commands.
*/ */
fun buildTransactions(command: CommandData): GraphTransactionStorage { fun buildTransactions(command: CommandData): GraphTransactionStorage {
val megaCorpServices = MockServices(listOf("net.corda.testing.contracts"), megaCorp, rigorousMock()) val megaCorpServices = MockServices(listOf("net.corda.testing.contracts"), megaCorp, rigorousMock<IdentityService>())
val notaryServices = MockServices(listOf("net.corda.testing.contracts"), dummyNotary, rigorousMock()) val notaryServices = MockServices(listOf("net.corda.testing.contracts"), dummyNotary, rigorousMock<IdentityService>())
val originBuilder = TransactionBuilder(dummyNotary.party) val originBuilder = TransactionBuilder(dummyNotary.party)
.addOutputState(DummyState(random31BitValue()), DummyContract.PROGRAM_ID) .addOutputState(DummyState(random31BitValue()), DummyContract.PROGRAM_ID)
.addCommand(command, megaCorp.publicKey) .addCommand(command, megaCorp.publicKey)

View File

@ -24,7 +24,6 @@ import net.corda.node.internal.configureDatabase
import net.corda.node.internal.cordapp.JarScanningCordappLoader import net.corda.node.internal.cordapp.JarScanningCordappLoader
import net.corda.node.services.api.* import net.corda.node.services.api.*
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.transactions.InMemoryTransactionVerifierService import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.NodeVaultService
@ -115,7 +114,7 @@ open class MockServices private constructor(
val database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService) val database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService)
val mockService = database.transaction { val mockService = database.transaction {
object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) { object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) {
override val vaultService: VaultService = makeVaultService(database.hibernateConfig, schemaService, database) override val vaultService: VaultService = makeVaultService(schemaService, database)
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) { override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
ServiceHubInternal.recordTransactions(statesToRecord, txs, ServiceHubInternal.recordTransactions(statesToRecord, txs,
@ -212,6 +211,12 @@ open class MockServices private constructor(
constructor(firstIdentity: TestIdentity, vararg moreIdentities: TestIdentity) : this( constructor(firstIdentity: TestIdentity, vararg moreIdentities: TestIdentity) : this(
listOf(getCallerPackage(MockServices::class)!!), listOf(getCallerPackage(MockServices::class)!!),
firstIdentity, firstIdentity,
*moreIdentities
)
constructor(cordappPackages: List<String>, firstIdentity: TestIdentity, vararg moreIdentities: TestIdentity) : this(
cordappPackages,
firstIdentity,
makeTestIdentityService(*listOf(firstIdentity, *moreIdentities).map { it.identity }.toTypedArray()), makeTestIdentityService(*listOf(firstIdentity, *moreIdentities).map { it.identity }.toTypedArray()),
firstIdentity.keyPair firstIdentity.keyPair
) )
@ -251,10 +256,8 @@ open class MockServices private constructor(
} }
} }
internal fun makeVaultService(hibernateConfig: HibernateConfiguration, schemaService: SchemaService, database: CordaPersistence): VaultServiceInternal { internal fun makeVaultService(schemaService: SchemaService, database: CordaPersistence): VaultServiceInternal {
val vaultService = NodeVaultService(clock, keyManagementService, servicesForResolution, database).apply { start() } return NodeVaultService(clock, keyManagementService, servicesForResolution, database, schemaService).apply { start() }
HibernateObserver.install(vaultService.rawUpdates, hibernateConfig, schemaService)
return vaultService
} }
// This needs to be internal as MutableClassToInstanceMap is a guava type and shouldn't be part of our public API // This needs to be internal as MutableClassToInstanceMap is a guava type and shouldn't be part of our public API