mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
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
This commit is contained in:
parent
a4052f9126
commit
09adba8275
@ -42,7 +42,7 @@ class JDBCHashMapTestSuite {
|
|||||||
@BeforeClass
|
@BeforeClass
|
||||||
fun before() {
|
fun before() {
|
||||||
initialiseTestSerialization()
|
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()
|
setUpDatabaseTx()
|
||||||
loadOnInitFalseMap = JDBCHashMap<String, String>("test_map_false", loadOnInit = false)
|
loadOnInitFalseMap = JDBCHashMap<String, String>("test_map_false", loadOnInit = false)
|
||||||
memoryConstrainedMap = JDBCHashMap<String, String>("test_map_constrained", loadOnInit = false, maxBuckets = 1)
|
memoryConstrainedMap = JDBCHashMap<String, String>("test_map_constrained", loadOnInit = false, maxBuckets = 1)
|
||||||
@ -228,7 +228,7 @@ class JDBCHashMapTestSuite {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun 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
|
@After
|
||||||
|
@ -480,7 +480,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
|||||||
private fun makeVaultObservers() {
|
private fun makeVaultObservers() {
|
||||||
VaultSoftLockManager(services.vaultService, smm)
|
VaultSoftLockManager(services.vaultService, smm)
|
||||||
ScheduledActivityObserver(services)
|
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 {
|
private fun makeInfo(legalIdentity: PartyAndCertificate): NodeInfo {
|
||||||
@ -538,7 +538,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
|||||||
protected open fun initialiseDatabasePersistence(insideTransaction: () -> Unit) {
|
protected open fun initialiseDatabasePersistence(insideTransaction: () -> Unit) {
|
||||||
val props = configuration.dataSourceProperties
|
val props = configuration.dataSourceProperties
|
||||||
if (props.isNotEmpty()) {
|
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.
|
// 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.database.vendor} database.")
|
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 inner class ServiceHubInternalImpl : ServiceHubInternal, SingletonSerializeAsToken() {
|
||||||
|
|
||||||
private val hibernateConfig by lazy { HibernateConfiguration(schemaService, configuration.database ?: Properties(), { identityService }) }
|
|
||||||
|
|
||||||
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()
|
||||||
@ -761,7 +759,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
|||||||
override val networkMapCache by lazy { InMemoryNetworkMapCache(this) }
|
override val networkMapCache by lazy { InMemoryNetworkMapCache(this) }
|
||||||
override val vaultService by lazy { NodeVaultService(this) }
|
override val vaultService by lazy { NodeVaultService(this) }
|
||||||
override val vaultQueryService by lazy {
|
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
|
// 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
|
// the KMS is meant for derived temporary keys used in transactions, and we're not supposed to sign things with
|
||||||
|
@ -21,39 +21,37 @@ import java.sql.Connection
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
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 {
|
companion object {
|
||||||
val logger = loggerFor<HibernateConfiguration>()
|
val logger = loggerFor<HibernateConfiguration>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make this a guava cache or similar to limit ability for this to grow forever.
|
// TODO: make this a guava cache or similar to limit ability for this to grow forever.
|
||||||
val sessionFactories = ConcurrentHashMap<MappedSchema, SessionFactory>()
|
private val sessionFactories = ConcurrentHashMap<Set<MappedSchema>, SessionFactory>()
|
||||||
|
|
||||||
private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel") ?:"")
|
private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel") ?:"")
|
||||||
|
var schemaService = createSchemaService()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
schemaService.schemaOptions.map { it.key }.forEach { mappedSchema ->
|
logger.info("Init HibernateConfiguration for schemas: ${schemaService.schemaOptions.keys}")
|
||||||
sessionFactories.computeIfAbsent(mappedSchema, { makeSessionFactoryForSchema(mappedSchema) })
|
sessionFactoryForRegisteredSchemas()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sessionFactoryForRegisteredSchemas(): SessionFactory {
|
fun sessionFactoryForRegisteredSchemas(): SessionFactory {
|
||||||
return sessionFactoryForSchemas(*schemaService.schemaOptions.map { it.key }.toTypedArray())
|
return sessionFactoryForSchemas(*schemaService.schemaOptions.keys.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sessionFactoryForSchema(schema: MappedSchema): SessionFactory {
|
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 {
|
fun sessionFactoryForSchemas(vararg schemas: MappedSchema): SessionFactory {
|
||||||
return makeSessionFactoryForSchemas(schemas.iterator())
|
val schemaSet: Set<MappedSchema> = schemas.toSet()
|
||||||
|
return sessionFactories.computeIfAbsent(schemaSet, { makeSessionFactoryForSchemas(schemaSet) })
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeSessionFactoryForSchema(schema: MappedSchema): SessionFactory {
|
private fun makeSessionFactoryForSchemas(schemas: Set<MappedSchema>): SessionFactory {
|
||||||
return makeSessionFactoryForSchemas(setOf(schema).iterator())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun makeSessionFactoryForSchemas(schemas: Iterator<MappedSchema>): SessionFactory {
|
|
||||||
logger.info("Creating session factory for schemas: $schemas")
|
logger.info("Creating session factory for schemas: $schemas")
|
||||||
val serviceRegistry = BootstrapServiceRegistryBuilder().build()
|
val serviceRegistry = BootstrapServiceRegistryBuilder().build()
|
||||||
val metadataSources = MetadataSources(serviceRegistry)
|
val metadataSources = MetadataSources(serviceRegistry)
|
||||||
@ -84,7 +82,7 @@ class HibernateConfiguration(val schemaService: SchemaService, val databasePrope
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
// register custom converters
|
// register custom converters
|
||||||
applyAttributeConverter(AbstractPartyToX500NameAsStringConverter(identitySvc))
|
applyAttributeConverter(AbstractPartyToX500NameAsStringConverter(createIdentityScervice))
|
||||||
|
|
||||||
build()
|
build()
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package net.corda.node.utilities
|
|||||||
import com.zaxxer.hikari.HikariConfig
|
import com.zaxxer.hikari.HikariConfig
|
||||||
import com.zaxxer.hikari.HikariDataSource
|
import com.zaxxer.hikari.HikariDataSource
|
||||||
import net.corda.core.node.services.IdentityService
|
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.database.HibernateConfiguration
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import org.hibernate.SessionFactory
|
import org.hibernate.SessionFactory
|
||||||
@ -20,21 +20,28 @@ import java.util.concurrent.CopyOnWriteArrayList
|
|||||||
|
|
||||||
|
|
||||||
//HikariDataSource implements Closeable which allows CordaPersistence to be Closeable
|
//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 */
|
/** Holds Exposed database, the field will be removed once Exposed library is removed */
|
||||||
lateinit var database: Database
|
lateinit var database: Database
|
||||||
var transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel"))
|
var transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel"))
|
||||||
|
|
||||||
val entityManagerFactory: SessionFactory by lazy(LazyThreadSafetyMode.NONE) {
|
val hibernateConfig: HibernateConfiguration by lazy {
|
||||||
transaction {
|
transaction {
|
||||||
HibernateConfiguration(nodeSchemaService, databaseProperties, identitySvc).sessionFactoryForRegisteredSchemas()
|
HibernateConfiguration(createSchemaService, databaseProperties, createIdentityService)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val entityManagerFactory: SessionFactory by lazy {
|
||||||
|
transaction {
|
||||||
|
hibernateConfig.sessionFactoryForRegisteredSchemas()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun connect(dataSource: HikariDataSource, nodeSchemaService: NodeSchemaService, identitySvc: () -> IdentityService, databaseProperties: Properties): CordaPersistence {
|
fun connect(dataSource: HikariDataSource, createSchemaService: () -> SchemaService, createIdentityService: () -> IdentityService, databaseProperties: Properties): CordaPersistence {
|
||||||
return CordaPersistence(dataSource, nodeSchemaService, identitySvc, databaseProperties).apply {
|
return CordaPersistence(dataSource, createSchemaService, createIdentityService, databaseProperties).apply {
|
||||||
DatabaseTransactionManager(this)
|
DatabaseTransactionManager(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,10 +107,10 @@ class CordaPersistence(var dataSource: HikariDataSource, var nodeSchemaService:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun configureDatabase(dataSourceProperties: Properties, databaseProperties: Properties?, entitySchemas: Set<MappedSchema> = emptySet<MappedSchema>(), identitySvc: ()-> IdentityService): CordaPersistence {
|
fun configureDatabase(dataSourceProperties: Properties, databaseProperties: Properties?, createSchemaService: () -> SchemaService = { NodeSchemaService() }, createIdentityService: () -> IdentityService): CordaPersistence {
|
||||||
val config = HikariConfig(dataSourceProperties)
|
val config = HikariConfig(dataSourceProperties)
|
||||||
val dataSource = HikariDataSource(config)
|
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
|
//org.jetbrains.exposed.sql.Database will be removed once Exposed library is removed
|
||||||
val database = Database.connect(dataSource) { _ -> ExposedTransactionManager() }
|
val database = Database.connect(dataSource) { _ -> ExposedTransactionManager() }
|
||||||
@ -197,7 +204,7 @@ fun <T : Any> rx.Observable<T>.wrapWithDatabaseTransaction(db: CordaPersistence?
|
|||||||
wrappingSubscriber.cleanUp()
|
wrappingSubscriber.cleanUp()
|
||||||
// If cleanup removed the last subscriber reset the system, as future subscribers might need the stream again
|
// If cleanup removed the last subscriber reset the system, as future subscribers might need the stream again
|
||||||
if (wrappingSubscriber.delegates.isEmpty()) {
|
if (wrappingSubscriber.delegates.isEmpty()) {
|
||||||
wrappingSubscriber = DatabaseTransactionWrappingSubscriber<T>(db)
|
wrappingSubscriber = DatabaseTransactionWrappingSubscriber(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class DatabaseTransaction(isolation: Int, val threadLocal: ThreadLocal<DatabaseT
|
|||||||
val session: Session by sessionDelegate
|
val session: Session by sessionDelegate
|
||||||
private lateinit var hibernateTransaction : Transaction
|
private lateinit var hibernateTransaction : Transaction
|
||||||
|
|
||||||
val outerTransaction: DatabaseTransaction? = threadLocal.get()
|
private val outerTransaction: DatabaseTransaction? = threadLocal.get()
|
||||||
|
|
||||||
fun commit() {
|
fun commit() {
|
||||||
if (sessionDelegate.isInitialized()) {
|
if (sessionDelegate.isInitialized()) {
|
||||||
@ -51,6 +51,9 @@ class DatabaseTransaction(isolation: Int, val threadLocal: ThreadLocal<DatabaseT
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun close() {
|
fun close() {
|
||||||
|
if (sessionDelegate.isInitialized() && session.isOpen) {
|
||||||
|
session.close()
|
||||||
|
}
|
||||||
connection.close()
|
connection.close()
|
||||||
threadLocal.set(outerTransaction)
|
threadLocal.set(outerTransaction)
|
||||||
if (outerTransaction == null) {
|
if (outerTransaction == null) {
|
||||||
|
@ -69,12 +69,13 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
|||||||
issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, BOB_KEY, BOC_KEY)
|
issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, BOB_KEY, BOC_KEY)
|
||||||
val dataSourceProps = makeTestDataSourceProperties()
|
val dataSourceProps = makeTestDataSourceProperties()
|
||||||
val defaultDatabaseProperties = makeTestDatabaseProperties()
|
val defaultDatabaseProperties = makeTestDatabaseProperties()
|
||||||
database = configureDatabase(dataSourceProps, defaultDatabaseProperties, identitySvc = ::makeTestIdentityService)
|
|
||||||
val customSchemas = setOf(VaultSchemaV1, CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3)
|
val customSchemas = setOf(VaultSchemaV1, CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3)
|
||||||
|
val createSchemaService = { NodeSchemaService(customSchemas) }
|
||||||
|
database = configureDatabase(dataSourceProps, defaultDatabaseProperties, createSchemaService, ::makeTestIdentityService)
|
||||||
database.transaction {
|
database.transaction {
|
||||||
hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), makeTestDatabaseProperties(), ::makeTestIdentityService)
|
hibernateConfig = database.hibernateConfig
|
||||||
services = object : MockServices(BOB_KEY, BOC_KEY, DUMMY_NOTARY_KEY) {
|
services = object : MockServices(BOB_KEY, BOC_KEY, DUMMY_NOTARY_KEY) {
|
||||||
override val vaultService: VaultService = makeVaultService(hibernateConfig)
|
override val vaultService: VaultService = makeVaultService(database.hibernateConfig)
|
||||||
|
|
||||||
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
||||||
for (stx in txs) {
|
for (stx in txs) {
|
||||||
|
@ -74,7 +74,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
|||||||
calls = 0
|
calls = 0
|
||||||
val dataSourceProps = makeTestDataSourceProperties()
|
val dataSourceProps = makeTestDataSourceProperties()
|
||||||
val databaseProperties = makeTestDatabaseProperties()
|
val databaseProperties = makeTestDatabaseProperties()
|
||||||
database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = ::makeTestIdentityService)
|
database = configureDatabase(dataSourceProps, databaseProperties, createIdentityService = ::makeTestIdentityService)
|
||||||
val identityService = InMemoryIdentityService(trustRoot = DUMMY_CA.certificate)
|
val identityService = InMemoryIdentityService(trustRoot = DUMMY_CA.certificate)
|
||||||
val kms = MockKeyManagementService(identityService, ALICE_KEY)
|
val kms = MockKeyManagementService(identityService, ALICE_KEY)
|
||||||
|
|
||||||
|
@ -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(), identitySvc = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
||||||
networkMapRegistrationFuture = doneFuture(Unit)
|
networkMapRegistrationFuture = doneFuture(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(), identitySvc = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
||||||
newCheckpointStorage()
|
newCheckpointStorage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,6 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() {
|
|||||||
lateinit var transactionStorage: DBTransactionStorage
|
lateinit var transactionStorage: DBTransactionStorage
|
||||||
lateinit var services: MockServices
|
lateinit var services: MockServices
|
||||||
val vault: VaultService get() = services.vaultService
|
val vault: VaultService get() = services.vaultService
|
||||||
// Hibernate configuration objects
|
|
||||||
lateinit var hibernateConfig: HibernateConfiguration
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
@ -49,18 +47,16 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() {
|
|||||||
val transactionSchema = MappedSchema(schemaFamily = javaClass, version = 1,
|
val transactionSchema = MappedSchema(schemaFamily = javaClass, version = 1,
|
||||||
mappedTypes = listOf(DBTransactionStorage.DBTransaction::class.java))
|
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 {
|
database.transaction {
|
||||||
|
|
||||||
hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService)
|
|
||||||
|
|
||||||
services = object : MockServices(BOB_KEY) {
|
services = object : MockServices(BOB_KEY) {
|
||||||
override val vaultService: VaultService get() {
|
override val vaultService: VaultService get() {
|
||||||
val vaultService = NodeVaultService(this)
|
val vaultService = NodeVaultService(this)
|
||||||
hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig)
|
hibernatePersister = HibernateObserver(vaultService.rawUpdates, database.hibernateConfig)
|
||||||
return vaultService
|
return vaultService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class NodeAttachmentStorageTest {
|
|||||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||||
|
|
||||||
val dataSourceProperties = makeTestDataSourceProperties()
|
val dataSourceProperties = makeTestDataSourceProperties()
|
||||||
database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService)
|
database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
||||||
fs = Jimfs.newFileSystem(Configuration.unix())
|
fs = Jimfs.newFileSystem(Configuration.unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,8 @@ import net.corda.core.schemas.PersistentState
|
|||||||
import net.corda.core.schemas.QueryableState
|
import net.corda.core.schemas.QueryableState
|
||||||
import net.corda.testing.LogHelper
|
import net.corda.testing.LogHelper
|
||||||
import net.corda.node.services.api.SchemaService
|
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.node.utilities.configureDatabase
|
||||||
import net.corda.testing.DUMMY_CA
|
|
||||||
import net.corda.testing.MEGA_CORP
|
import net.corda.testing.MEGA_CORP
|
||||||
import net.corda.testing.MOCK_IDENTITIES
|
|
||||||
import net.corda.testing.node.makeTestDataSourceProperties
|
import net.corda.testing.node.makeTestDataSourceProperties
|
||||||
import net.corda.testing.node.makeTestDatabaseProperties
|
import net.corda.testing.node.makeTestDatabaseProperties
|
||||||
import net.corda.testing.node.makeTestIdentityService
|
import net.corda.testing.node.makeTestIdentityService
|
||||||
@ -31,17 +26,14 @@ import kotlin.test.assertEquals
|
|||||||
|
|
||||||
|
|
||||||
class HibernateObserverTests {
|
class HibernateObserverTests {
|
||||||
lateinit var database: CordaPersistence
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
LogHelper.setLevel(HibernateObserver::class)
|
LogHelper.setLevel(HibernateObserver::class)
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
database.close()
|
|
||||||
LogHelper.reset(HibernateObserver::class)
|
LogHelper.reset(HibernateObserver::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,9 +96,10 @@ class HibernateObserverTests {
|
|||||||
return parent
|
return parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { schemaService }, createIdentityService = ::makeTestIdentityService)
|
||||||
|
|
||||||
@Suppress("UNUSED_VARIABLE")
|
@Suppress("UNUSED_VARIABLE")
|
||||||
val observer = HibernateObserver(rawUpdatesPublisher, HibernateConfiguration(schemaService, makeTestDatabaseProperties(), ::makeTestIdentityService))
|
val observer = HibernateObserver(rawUpdatesPublisher, database.hibernateConfig)
|
||||||
database.transaction {
|
database.transaction {
|
||||||
rawUpdatesPublisher.onNext(Vault.Update(emptySet(), setOf(StateAndRef(TransactionState(TestState(), MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0)))))
|
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()
|
val parentRowCountResult = TransactionManager.current().connection.prepareStatement("select count(*) from Parents").executeQuery()
|
||||||
@ -120,5 +113,7 @@ class HibernateObserverTests {
|
|||||||
assertEquals(1, parentRows, "Expected one parent")
|
assertEquals(1, parentRows, "Expected one parent")
|
||||||
assertEquals(2, childrenRows, "Expected two children")
|
assertEquals(2, childrenRows, "Expected two children")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
database.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -34,7 +34,7 @@ class DistributedImmutableMapTests : TestDependencyInjectionBase() {
|
|||||||
fun setup() {
|
fun setup() {
|
||||||
LogHelper.setLevel("-org.apache.activemq")
|
LogHelper.setLevel("-org.apache.activemq")
|
||||||
LogHelper.setLevel(NetworkMapService::class)
|
LogHelper.setLevel(NetworkMapService::class)
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
||||||
cluster = setUpCluster()
|
cluster = setUpCluster()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(), identitySvc = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -17,6 +17,7 @@ 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.utilities.*
|
import net.corda.core.utilities.*
|
||||||
import net.corda.finance.*
|
import net.corda.finance.*
|
||||||
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import net.corda.node.utilities.CordaPersistence
|
import net.corda.node.utilities.CordaPersistence
|
||||||
import net.corda.node.utilities.configureDatabase
|
import net.corda.node.utilities.configureDatabase
|
||||||
import net.corda.schemas.CashSchemaV1
|
import net.corda.schemas.CashSchemaV1
|
||||||
@ -64,7 +65,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
|||||||
// register additional identities
|
// register additional identities
|
||||||
identitySvc.verifyAndRegisterIdentity(CASH_NOTARY_IDENTITY)
|
identitySvc.verifyAndRegisterIdentity(CASH_NOTARY_IDENTITY)
|
||||||
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
|
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
|
||||||
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY), identitySvc = { identitySvc })
|
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY), createIdentityService = { identitySvc })
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY)
|
notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY)
|
||||||
@ -81,7 +82,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
|||||||
@Ignore
|
@Ignore
|
||||||
@Test
|
@Test
|
||||||
fun createPersistentTestDb() {
|
fun createPersistentTestDb() {
|
||||||
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = { identitySvc })
|
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = { identitySvc })
|
||||||
|
|
||||||
setUpDb(database, 5000)
|
setUpDb(database, 5000)
|
||||||
|
|
||||||
|
@ -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(), identitySvc = ::makeTestIdentityService)
|
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
||||||
toBeClosed += database
|
toBeClosed += database
|
||||||
return database
|
return database
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService)
|
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
|
||||||
database.transaction {
|
database.transaction {
|
||||||
oracle = NodeInterestRates.Oracle(
|
oracle = NodeInterestRates.Oracle(
|
||||||
MEGA_CORP,
|
MEGA_CORP,
|
||||||
|
@ -87,7 +87,7 @@ open class MockServices(vararg val keys: KeyPair) : ServiceHub {
|
|||||||
|
|
||||||
lateinit var hibernatePersister: HibernateObserver
|
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)
|
val vaultService = NodeVaultService(this)
|
||||||
hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig)
|
hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig)
|
||||||
return vaultService
|
return vaultService
|
||||||
@ -219,15 +219,14 @@ fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRo
|
|||||||
|
|
||||||
fun makeTestDatabaseAndMockServices(customSchemas: Set<MappedSchema> = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1, CashSchemaV1),
|
fun makeTestDatabaseAndMockServices(customSchemas: Set<MappedSchema> = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1, CashSchemaV1),
|
||||||
keys: List<KeyPair> = listOf(MEGA_CORP_KEY),
|
keys: List<KeyPair> = listOf(MEGA_CORP_KEY),
|
||||||
identitySvc: ()-> IdentityService = { makeTestIdentityService() }): Pair<CordaPersistence, MockServices> {
|
createIdentityService: () -> IdentityService = { makeTestIdentityService() }): Pair<CordaPersistence, MockServices> {
|
||||||
val dataSourceProps = makeTestDataSourceProperties()
|
val dataSourceProps = makeTestDataSourceProperties()
|
||||||
val databaseProperties = makeTestDatabaseProperties()
|
val databaseProperties = makeTestDatabaseProperties()
|
||||||
|
val createSchemaService = { NodeSchemaService(customSchemas) }
|
||||||
val database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = identitySvc)
|
val database = configureDatabase(dataSourceProps, databaseProperties, createSchemaService, createIdentityService)
|
||||||
val mockService = database.transaction {
|
val mockService = database.transaction {
|
||||||
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), databaseProperties, identitySvc = identitySvc)
|
|
||||||
object : MockServices(*(keys.toTypedArray())) {
|
object : MockServices(*(keys.toTypedArray())) {
|
||||||
override val vaultService: VaultService = makeVaultService(hibernateConfig)
|
override val vaultService: VaultService = makeVaultService(database.hibernateConfig)
|
||||||
|
|
||||||
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
||||||
for (stx in txs) {
|
for (stx in txs) {
|
||||||
@ -237,7 +236,7 @@ fun makeTestDatabaseAndMockServices(customSchemas: Set<MappedSchema> = setOf(Com
|
|||||||
vaultService.notifyAll(txs.map { it.tx })
|
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()
|
override fun jdbcSession(): Connection = database.createSession()
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import net.corda.node.services.keys.E2ETestKeyManagementService
|
|||||||
import net.corda.node.services.messaging.ArtemisMessagingServer
|
import net.corda.node.services.messaging.ArtemisMessagingServer
|
||||||
import net.corda.node.services.messaging.NodeMessagingClient
|
import net.corda.node.services.messaging.NodeMessagingClient
|
||||||
import net.corda.node.services.network.InMemoryNetworkMapCache
|
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.AffinityExecutor.ServiceAffinityExecutor
|
||||||
import net.corda.node.utilities.CordaPersistence
|
import net.corda.node.utilities.CordaPersistence
|
||||||
import net.corda.node.utilities.configureDatabase
|
import net.corda.node.utilities.configureDatabase
|
||||||
@ -36,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, identitySvc = {InMemoryIdentityService(trustRoot = trustRoot)})
|
val database: CordaPersistence = configureDatabase(config.dataSourceProperties, config.database, { NodeSchemaService() }, { InMemoryIdentityService(trustRoot = trustRoot) })
|
||||||
val keyService: KeyManagementService = E2ETestKeyManagementService(identityService, setOf(identity))
|
val keyService: KeyManagementService = E2ETestKeyManagementService(identityService, setOf(identity))
|
||||||
val executor = ServiceAffinityExecutor(config.myLegalName.commonName, 1)
|
val executor = ServiceAffinityExecutor(config.myLegalName.commonName, 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
|
||||||
|
Loading…
Reference in New Issue
Block a user