From 09adba8275c81f8c35407e883524111e8ccc32dc Mon Sep 17 00:00:00 2001 From: szymonsztuka Date: Tue, 22 Aug 2017 13:08:36 +0100 Subject: [PATCH] Hibernate session leak fix * Hibernate session was not closed when JDBC connection was closed * combined few instances of HibernateSession objects into one field inside CordaPersistence * HibernateConfiguration improved caching of schema factories --- .../node/utilities/JDBCHashMapTestSuite.kt | 4 +-- .../net/corda/node/internal/AbstractNode.kt | 8 +++--- .../database/HibernateConfiguration.kt | 26 +++++++++---------- .../corda/node/utilities/CordaPersistence.kt | 25 +++++++++++------- .../utilities/DatabaseTransactionManager.kt | 5 +++- .../database/HibernateConfigurationTest.kt | 7 ++--- .../events/NodeSchedulerServiceTest.kt | 2 +- .../messaging/ArtemisMessagingTests.kt | 2 +- .../persistence/DBCheckpointStorageTests.kt | 2 +- .../persistence/DBTransactionStorageTests.kt | 10 +++---- .../persistence/NodeAttachmentStorageTest.kt | 2 +- .../services/schema/HibernateObserverTests.kt | 13 +++------- .../DistributedImmutableMapTests.kt | 2 +- .../PersistentUniquenessProviderTests.kt | 2 +- .../node/services/vault/VaultQueryTests.kt | 5 ++-- .../corda/node/utilities/ObservablesTests.kt | 2 +- .../corda/irs/api/NodeInterestRatesTest.kt | 2 +- .../net/corda/testing/node/MockServices.kt | 13 +++++----- .../net/corda/testing/node/SimpleNode.kt | 3 ++- 19 files changed, 67 insertions(+), 68 deletions(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/utilities/JDBCHashMapTestSuite.kt b/node/src/integration-test/kotlin/net/corda/node/utilities/JDBCHashMapTestSuite.kt index 0057ba0470..479c400068 100644 --- a/node/src/integration-test/kotlin/net/corda/node/utilities/JDBCHashMapTestSuite.kt +++ b/node/src/integration-test/kotlin/net/corda/node/utilities/JDBCHashMapTestSuite.kt @@ -42,7 +42,7 @@ class JDBCHashMapTestSuite { @BeforeClass fun before() { initialiseTestSerialization() - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = { throw UnsupportedOperationException("Identity Service should not be in use") }) + database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = { throw UnsupportedOperationException("Identity Service should not be in use") }) setUpDatabaseTx() loadOnInitFalseMap = JDBCHashMap("test_map_false", loadOnInit = false) memoryConstrainedMap = JDBCHashMap("test_map_constrained", loadOnInit = false, maxBuckets = 1) @@ -228,7 +228,7 @@ class JDBCHashMapTestSuite { @Before fun before() { - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = { throw UnsupportedOperationException("Identity Service should not be in use") }) + database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = { throw UnsupportedOperationException("Identity Service should not be in use") }) } @After diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 10708956d9..434ddba409 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -480,7 +480,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, private fun makeVaultObservers() { VaultSoftLockManager(services.vaultService, smm) ScheduledActivityObserver(services) - HibernateObserver(services.vaultService.rawUpdates, HibernateConfiguration(services.schemaService, configuration.database ?: Properties(), {services.identityService})) + HibernateObserver(services.vaultService.rawUpdates, services.database.hibernateConfig) } private fun makeInfo(legalIdentity: PartyAndCertificate): NodeInfo { @@ -538,7 +538,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, protected open fun initialiseDatabasePersistence(insideTransaction: () -> Unit) { val props = configuration.dataSourceProperties if (props.isNotEmpty()) { - this.database = configureDatabase(props, configuration.database, identitySvc = { _services.identityService }) + this.database = configureDatabase(props, configuration.database, { _services.schemaService }, createIdentityService = { _services.identityService }) // Now log the vendor string as this will also cause a connection to be tested eagerly. database.transaction { log.info("Connected to ${database.database.vendor} database.") @@ -750,8 +750,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, private inner class ServiceHubInternalImpl : ServiceHubInternal, SingletonSerializeAsToken() { - private val hibernateConfig by lazy { HibernateConfiguration(schemaService, configuration.database ?: Properties(), { identityService }) } - override val rpcFlows = ArrayList>>() override val stateMachineRecordedTransactionMapping = DBTransactionMappingStorage() override val auditService = DummyAuditService() @@ -761,7 +759,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, override val networkMapCache by lazy { InMemoryNetworkMapCache(this) } override val vaultService by lazy { NodeVaultService(this) } override val vaultQueryService by lazy { - HibernateVaultQueryImpl(hibernateConfig, vaultService) + HibernateVaultQueryImpl(database.hibernateConfig, vaultService) } // Place the long term identity key in the KMS. Eventually, this is likely going to be separated again because // the KMS is meant for derived temporary keys used in transactions, and we're not supposed to sign things with diff --git a/node/src/main/kotlin/net/corda/node/services/database/HibernateConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/database/HibernateConfiguration.kt index 88d9065681..0bd0610a3a 100644 --- a/node/src/main/kotlin/net/corda/node/services/database/HibernateConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/database/HibernateConfiguration.kt @@ -21,39 +21,37 @@ import java.sql.Connection import java.util.* import java.util.concurrent.ConcurrentHashMap -class HibernateConfiguration(val schemaService: SchemaService, val databaseProperties: Properties, private val identitySvc: () -> IdentityService) { +class HibernateConfiguration(createSchemaService: () -> SchemaService, private val databaseProperties: Properties, private val createIdentityScervice: () -> IdentityService) { companion object { val logger = loggerFor() } // TODO: make this a guava cache or similar to limit ability for this to grow forever. - val sessionFactories = ConcurrentHashMap() + private val sessionFactories = ConcurrentHashMap, SessionFactory>() private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel") ?:"") + var schemaService = createSchemaService() init { - schemaService.schemaOptions.map { it.key }.forEach { mappedSchema -> - sessionFactories.computeIfAbsent(mappedSchema, { makeSessionFactoryForSchema(mappedSchema) }) - } + logger.info("Init HibernateConfiguration for schemas: ${schemaService.schemaOptions.keys}") + sessionFactoryForRegisteredSchemas() } fun sessionFactoryForRegisteredSchemas(): SessionFactory { - return sessionFactoryForSchemas(*schemaService.schemaOptions.map { it.key }.toTypedArray()) + return sessionFactoryForSchemas(*schemaService.schemaOptions.keys.toTypedArray()) } fun sessionFactoryForSchema(schema: MappedSchema): SessionFactory { - return sessionFactories.computeIfAbsent(schema, { sessionFactoryForSchemas(schema) }) + return sessionFactoryForSchemas(schema) } + //vararg to set conversions left to preserve method signature for now fun sessionFactoryForSchemas(vararg schemas: MappedSchema): SessionFactory { - return makeSessionFactoryForSchemas(schemas.iterator()) + val schemaSet: Set = schemas.toSet() + return sessionFactories.computeIfAbsent(schemaSet, { makeSessionFactoryForSchemas(schemaSet) }) } - private fun makeSessionFactoryForSchema(schema: MappedSchema): SessionFactory { - return makeSessionFactoryForSchemas(setOf(schema).iterator()) - } - - private fun makeSessionFactoryForSchemas(schemas: Iterator): SessionFactory { + private fun makeSessionFactoryForSchemas(schemas: Set): SessionFactory { logger.info("Creating session factory for schemas: $schemas") val serviceRegistry = BootstrapServiceRegistryBuilder().build() val metadataSources = MetadataSources(serviceRegistry) @@ -84,7 +82,7 @@ class HibernateConfiguration(val schemaService: SchemaService, val databasePrope } }) // register custom converters - applyAttributeConverter(AbstractPartyToX500NameAsStringConverter(identitySvc)) + applyAttributeConverter(AbstractPartyToX500NameAsStringConverter(createIdentityScervice)) build() } diff --git a/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt b/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt index a29fee242e..e4563ebaa0 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt @@ -3,7 +3,7 @@ package net.corda.node.utilities import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource import net.corda.core.node.services.IdentityService -import net.corda.core.schemas.MappedSchema +import net.corda.node.services.api.SchemaService import net.corda.node.services.database.HibernateConfiguration import net.corda.node.services.schema.NodeSchemaService import org.hibernate.SessionFactory @@ -20,21 +20,28 @@ import java.util.concurrent.CopyOnWriteArrayList //HikariDataSource implements Closeable which allows CordaPersistence to be Closeable -class CordaPersistence(var dataSource: HikariDataSource, var nodeSchemaService: NodeSchemaService, val identitySvc: ()-> IdentityService, databaseProperties: Properties): Closeable { +class CordaPersistence(var dataSource: HikariDataSource, private var createSchemaService: () -> SchemaService, + private val createIdentityService: ()-> IdentityService, databaseProperties: Properties): Closeable { /** Holds Exposed database, the field will be removed once Exposed library is removed */ lateinit var database: Database var transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel")) - val entityManagerFactory: SessionFactory by lazy(LazyThreadSafetyMode.NONE) { + val hibernateConfig: HibernateConfiguration by lazy { transaction { - HibernateConfiguration(nodeSchemaService, databaseProperties, identitySvc).sessionFactoryForRegisteredSchemas() + HibernateConfiguration(createSchemaService, databaseProperties, createIdentityService) + } + } + + val entityManagerFactory: SessionFactory by lazy { + transaction { + hibernateConfig.sessionFactoryForRegisteredSchemas() } } companion object { - fun connect(dataSource: HikariDataSource, nodeSchemaService: NodeSchemaService, identitySvc: () -> IdentityService, databaseProperties: Properties): CordaPersistence { - return CordaPersistence(dataSource, nodeSchemaService, identitySvc, databaseProperties).apply { + fun connect(dataSource: HikariDataSource, createSchemaService: () -> SchemaService, createIdentityService: () -> IdentityService, databaseProperties: Properties): CordaPersistence { + return CordaPersistence(dataSource, createSchemaService, createIdentityService, databaseProperties).apply { DatabaseTransactionManager(this) } } @@ -100,10 +107,10 @@ class CordaPersistence(var dataSource: HikariDataSource, var nodeSchemaService: } } -fun configureDatabase(dataSourceProperties: Properties, databaseProperties: Properties?, entitySchemas: Set = emptySet(), identitySvc: ()-> IdentityService): CordaPersistence { +fun configureDatabase(dataSourceProperties: Properties, databaseProperties: Properties?, createSchemaService: () -> SchemaService = { NodeSchemaService() }, createIdentityService: () -> IdentityService): CordaPersistence { val config = HikariConfig(dataSourceProperties) val dataSource = HikariDataSource(config) - val persistence = CordaPersistence.connect(dataSource, NodeSchemaService(entitySchemas), identitySvc, databaseProperties ?: Properties()) + val persistence = CordaPersistence.connect(dataSource, createSchemaService, createIdentityService, databaseProperties ?: Properties()) //org.jetbrains.exposed.sql.Database will be removed once Exposed library is removed val database = Database.connect(dataSource) { _ -> ExposedTransactionManager() } @@ -197,7 +204,7 @@ fun rx.Observable.wrapWithDatabaseTransaction(db: CordaPersistence? wrappingSubscriber.cleanUp() // If cleanup removed the last subscriber reset the system, as future subscribers might need the stream again if (wrappingSubscriber.delegates.isEmpty()) { - wrappingSubscriber = DatabaseTransactionWrappingSubscriber(db) + wrappingSubscriber = DatabaseTransactionWrappingSubscriber(db) } } } diff --git a/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt b/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt index da64097850..f847080433 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt @@ -32,7 +32,7 @@ class DatabaseTransaction(isolation: Int, val threadLocal: ThreadLocal) { for (stx in txs) { diff --git a/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt index e22dd01731..df17f414c2 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt @@ -74,7 +74,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() { calls = 0 val dataSourceProps = makeTestDataSourceProperties() val databaseProperties = makeTestDatabaseProperties() - database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = ::makeTestIdentityService) + database = configureDatabase(dataSourceProps, databaseProperties, createIdentityService = ::makeTestIdentityService) val identityService = InMemoryIdentityService(trustRoot = DUMMY_CA.certificate) val kms = MockKeyManagementService(identityService, ALICE_KEY) diff --git a/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt b/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt index 0d19c27a65..84c20bc453 100644 --- a/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt @@ -71,7 +71,7 @@ class ArtemisMessagingTests : TestDependencyInjectionBase() { baseDirectory = baseDirectory, myLegalName = ALICE.name) LogHelper.setLevel(PersistentUniquenessProvider::class) - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) + database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) networkMapRegistrationFuture = doneFuture(Unit) } diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/DBCheckpointStorageTests.kt b/node/src/test/kotlin/net/corda/node/services/persistence/DBCheckpointStorageTests.kt index e060680d41..88b0012435 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/DBCheckpointStorageTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/DBCheckpointStorageTests.kt @@ -33,7 +33,7 @@ class DBCheckpointStorageTests : TestDependencyInjectionBase() { @Before fun setUp() { LogHelper.setLevel(PersistentUniquenessProvider::class) - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) + database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) newCheckpointStorage() } diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt b/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt index 183044d1ad..56845229a9 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt @@ -38,8 +38,6 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() { lateinit var transactionStorage: DBTransactionStorage lateinit var services: MockServices val vault: VaultService get() = services.vaultService - // Hibernate configuration objects - lateinit var hibernateConfig: HibernateConfiguration @Before fun setUp() { @@ -49,18 +47,16 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() { val transactionSchema = MappedSchema(schemaFamily = javaClass, version = 1, mappedTypes = listOf(DBTransactionStorage.DBTransaction::class.java)) - val customSchemas = setOf(VaultSchemaV1, CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3, transactionSchema) + val createSchemaService = { NodeSchemaService(setOf(VaultSchemaV1, CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3, transactionSchema)) } - database = configureDatabase(dataSourceProps, makeTestDatabaseProperties(), customSchemas, identitySvc = ::makeTestIdentityService) + database = configureDatabase(dataSourceProps, makeTestDatabaseProperties(), createSchemaService, ::makeTestIdentityService) database.transaction { - hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) - services = object : MockServices(BOB_KEY) { override val vaultService: VaultService get() { val vaultService = NodeVaultService(this) - hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig) + hibernatePersister = HibernateObserver(vaultService.rawUpdates, database.hibernateConfig) return vaultService } diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt index a32f4166b0..f1c55ca1a7 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt @@ -40,7 +40,7 @@ class NodeAttachmentStorageTest { LogHelper.setLevel(PersistentUniquenessProvider::class) val dataSourceProperties = makeTestDataSourceProperties() - database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) + database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) fs = Jimfs.newFileSystem(Configuration.unix()) } diff --git a/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt b/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt index f81aac2b48..f061b1c4bf 100644 --- a/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/schema/HibernateObserverTests.kt @@ -9,13 +9,8 @@ import net.corda.core.schemas.PersistentState import net.corda.core.schemas.QueryableState import net.corda.testing.LogHelper import net.corda.node.services.api.SchemaService -import net.corda.node.services.database.HibernateConfiguration -import net.corda.node.services.identity.InMemoryIdentityService -import net.corda.node.utilities.CordaPersistence import net.corda.node.utilities.configureDatabase -import net.corda.testing.DUMMY_CA import net.corda.testing.MEGA_CORP -import net.corda.testing.MOCK_IDENTITIES import net.corda.testing.node.makeTestDataSourceProperties import net.corda.testing.node.makeTestDatabaseProperties import net.corda.testing.node.makeTestIdentityService @@ -31,17 +26,14 @@ import kotlin.test.assertEquals class HibernateObserverTests { - lateinit var database: CordaPersistence @Before fun setUp() { LogHelper.setLevel(HibernateObserver::class) - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) } @After fun cleanUp() { - database.close() LogHelper.reset(HibernateObserver::class) } @@ -104,9 +96,10 @@ class HibernateObserverTests { return parent } } + val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { schemaService }, createIdentityService = ::makeTestIdentityService) @Suppress("UNUSED_VARIABLE") - val observer = HibernateObserver(rawUpdatesPublisher, HibernateConfiguration(schemaService, makeTestDatabaseProperties(), ::makeTestIdentityService)) + val observer = HibernateObserver(rawUpdatesPublisher, database.hibernateConfig) database.transaction { rawUpdatesPublisher.onNext(Vault.Update(emptySet(), setOf(StateAndRef(TransactionState(TestState(), MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0))))) val parentRowCountResult = TransactionManager.current().connection.prepareStatement("select count(*) from Parents").executeQuery() @@ -120,5 +113,7 @@ class HibernateObserverTests { assertEquals(1, parentRows, "Expected one parent") assertEquals(2, childrenRows, "Expected two children") } + + database.close() } } \ No newline at end of file diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/DistributedImmutableMapTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/DistributedImmutableMapTests.kt index 95082a625b..06585baf20 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/DistributedImmutableMapTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/DistributedImmutableMapTests.kt @@ -34,7 +34,7 @@ class DistributedImmutableMapTests : TestDependencyInjectionBase() { fun setup() { LogHelper.setLevel("-org.apache.activemq") LogHelper.setLevel(NetworkMapService::class) - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) + database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) cluster = setUpCluster() } diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt index 57eefb0f22..289bc695ac 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt @@ -23,7 +23,7 @@ class PersistentUniquenessProviderTests : TestDependencyInjectionBase() { @Before fun setUp() { LogHelper.setLevel(PersistentUniquenessProvider::class) - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) + database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) } @After diff --git a/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt b/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt index fd51cbb62b..16f6cc14e9 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt @@ -17,6 +17,7 @@ import net.corda.core.node.services.vault.* import net.corda.core.node.services.vault.QueryCriteria.* import net.corda.core.utilities.* import net.corda.finance.* +import net.corda.node.services.schema.NodeSchemaService import net.corda.node.utilities.CordaPersistence import net.corda.node.utilities.configureDatabase import net.corda.schemas.CashSchemaV1 @@ -64,7 +65,7 @@ class VaultQueryTests : TestDependencyInjectionBase() { // register additional identities identitySvc.verifyAndRegisterIdentity(CASH_NOTARY_IDENTITY) identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY) - val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY), identitySvc = { identitySvc }) + val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY), createIdentityService = { identitySvc }) database = databaseAndServices.first services = databaseAndServices.second notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY) @@ -81,7 +82,7 @@ class VaultQueryTests : TestDependencyInjectionBase() { @Ignore @Test fun createPersistentTestDb() { - val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = { identitySvc }) + val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = { identitySvc }) setUpDb(database, 5000) diff --git a/node/src/test/kotlin/net/corda/node/utilities/ObservablesTests.kt b/node/src/test/kotlin/net/corda/node/utilities/ObservablesTests.kt index 0d99e3f3b8..900c00e482 100644 --- a/node/src/test/kotlin/net/corda/node/utilities/ObservablesTests.kt +++ b/node/src/test/kotlin/net/corda/node/utilities/ObservablesTests.kt @@ -21,7 +21,7 @@ class ObservablesTests { val toBeClosed = mutableListOf() fun createDatabase(): CordaPersistence { - val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) + val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) toBeClosed += database return database } diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt index ef25bf74c2..bdf12363f0 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt @@ -58,7 +58,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() { @Before fun setUp() { - database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) + database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) database.transaction { oracle = NodeInterestRates.Oracle( MEGA_CORP, diff --git a/test-utils/src/main/kotlin/net/corda/testing/node/MockServices.kt b/test-utils/src/main/kotlin/net/corda/testing/node/MockServices.kt index 37841f8857..367b16da73 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/node/MockServices.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/node/MockServices.kt @@ -87,7 +87,7 @@ open class MockServices(vararg val keys: KeyPair) : ServiceHub { lateinit var hibernatePersister: HibernateObserver - fun makeVaultService(hibernateConfig: HibernateConfiguration = HibernateConfiguration(NodeSchemaService(), makeTestDatabaseProperties(), { identityService })): VaultService { + fun makeVaultService(hibernateConfig: HibernateConfiguration = HibernateConfiguration( { NodeSchemaService() }, makeTestDatabaseProperties(), { identityService })): VaultService { val vaultService = NodeVaultService(this) hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig) return vaultService @@ -219,15 +219,14 @@ fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRo fun makeTestDatabaseAndMockServices(customSchemas: Set = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1, CashSchemaV1), keys: List = listOf(MEGA_CORP_KEY), - identitySvc: ()-> IdentityService = { makeTestIdentityService() }): Pair { + createIdentityService: () -> IdentityService = { makeTestIdentityService() }): Pair { val dataSourceProps = makeTestDataSourceProperties() val databaseProperties = makeTestDatabaseProperties() - - val database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = identitySvc) + val createSchemaService = { NodeSchemaService(customSchemas) } + val database = configureDatabase(dataSourceProps, databaseProperties, createSchemaService, createIdentityService) val mockService = database.transaction { - val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), databaseProperties, identitySvc = identitySvc) object : MockServices(*(keys.toTypedArray())) { - override val vaultService: VaultService = makeVaultService(hibernateConfig) + override val vaultService: VaultService = makeVaultService(database.hibernateConfig) override fun recordTransactions(notifyVault: Boolean, txs: Iterable) { for (stx in txs) { @@ -237,7 +236,7 @@ fun makeTestDatabaseAndMockServices(customSchemas: Set = setOf(Com vaultService.notifyAll(txs.map { it.tx }) } - override val vaultQueryService: VaultQueryService = HibernateVaultQueryImpl(hibernateConfig, vaultService) + override val vaultQueryService: VaultQueryService = HibernateVaultQueryImpl(database.hibernateConfig, vaultService) override fun jdbcSession(): Connection = database.createSession() } diff --git a/test-utils/src/main/kotlin/net/corda/testing/node/SimpleNode.kt b/test-utils/src/main/kotlin/net/corda/testing/node/SimpleNode.kt index 0f55f1bdb3..4e45f47417 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/node/SimpleNode.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/node/SimpleNode.kt @@ -16,6 +16,7 @@ import net.corda.node.services.keys.E2ETestKeyManagementService import net.corda.node.services.messaging.ArtemisMessagingServer import net.corda.node.services.messaging.NodeMessagingClient import net.corda.node.services.network.InMemoryNetworkMapCache +import net.corda.node.services.schema.NodeSchemaService import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor import net.corda.node.utilities.CordaPersistence import net.corda.node.utilities.configureDatabase @@ -36,7 +37,7 @@ class SimpleNode(val config: NodeConfiguration, val address: NetworkHostAndPort val monitoringService = MonitoringService(MetricRegistry()) val identity: KeyPair = generateKeyPair() val identityService: IdentityService = InMemoryIdentityService(trustRoot = trustRoot) - val database: CordaPersistence = configureDatabase(config.dataSourceProperties, config.database, identitySvc = {InMemoryIdentityService(trustRoot = trustRoot)}) + val database: CordaPersistence = configureDatabase(config.dataSourceProperties, config.database, { NodeSchemaService() }, { InMemoryIdentityService(trustRoot = trustRoot) }) val keyService: KeyManagementService = E2ETestKeyManagementService(identityService, setOf(identity)) val executor = ServiceAffinityExecutor(config.myLegalName.commonName, 1) // TODO: We should have a dummy service hub rather than change behaviour in tests