mirror of
https://github.com/corda/corda.git
synced 2025-02-03 09:41:10 +00:00
Szymon db confing (#1141)
database transaction isolation level and database initialisation are configurable
This commit is contained in:
parent
9eb1a0c9d5
commit
7620874e5f
@ -15,6 +15,7 @@ import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
@ -212,7 +213,7 @@ class CommercialPaperTestsGeneric {
|
||||
fun `issue move and then redeem`() {
|
||||
initialiseTestSerialization()
|
||||
val dataSourcePropsAlice = makeTestDataSourceProperties()
|
||||
val databaseAlice = configureDatabase(dataSourcePropsAlice)
|
||||
val databaseAlice = configureDatabase(dataSourcePropsAlice, makeTestDatabaseProperties())
|
||||
databaseAlice.transaction {
|
||||
|
||||
aliceServices = object : MockServices(ALICE_KEY) {
|
||||
@ -231,7 +232,7 @@ class CommercialPaperTestsGeneric {
|
||||
}
|
||||
|
||||
val dataSourcePropsBigCorp = makeTestDataSourceProperties()
|
||||
val databaseBigCorp = configureDatabase(dataSourcePropsBigCorp)
|
||||
val databaseBigCorp = configureDatabase(dataSourcePropsBigCorp, makeTestDatabaseProperties())
|
||||
databaseBigCorp.transaction {
|
||||
|
||||
bigCorpServices = object : MockServices(BIG_CORP_KEY) {
|
||||
|
@ -21,6 +21,7 @@ import net.corda.testing.contracts.fillWithSomeTestCash
|
||||
import net.corda.testing.node.MockKeyManagementService
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.security.KeyPair
|
||||
@ -51,7 +52,7 @@ class CashTests : TestDependencyInjectionBase() {
|
||||
fun setUp() {
|
||||
LogHelper.setLevel(NodeVaultService::class)
|
||||
val dataSourceProps = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProps)
|
||||
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties())
|
||||
database.transaction {
|
||||
miniCorpServices = object : MockServices(MINI_CORP_KEY) {
|
||||
override val keyManagementService: MockKeyManagementService = MockKeyManagementService(identityService, MINI_CORP_KEY, MEGA_CORP_KEY, OUR_KEY)
|
||||
|
@ -13,6 +13,7 @@ import junit.framework.TestSuite
|
||||
import net.corda.testing.TestDependencyInjectionBase
|
||||
import net.corda.testing.initialiseTestSerialization
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import net.corda.testing.resetTestSerialization
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
@ -33,7 +34,7 @@ import java.util.*
|
||||
JDBCHashMapTestSuite.SetConstrained::class)
|
||||
class JDBCHashMapTestSuite {
|
||||
companion object {
|
||||
lateinit var transaction: Transaction
|
||||
lateinit var transaction: DatabaseTransaction
|
||||
lateinit var database: CordaPersistence
|
||||
lateinit var loadOnInitFalseMap: JDBCHashMap<String, String>
|
||||
lateinit var memoryConstrainedMap: JDBCHashMap<String, String>
|
||||
@ -46,7 +47,7 @@ class JDBCHashMapTestSuite {
|
||||
@BeforeClass
|
||||
fun before() {
|
||||
initialiseTestSerialization()
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
setUpDatabaseTx()
|
||||
loadOnInitFalseMap = JDBCHashMap<String, String>("test_map_false", loadOnInit = false)
|
||||
memoryConstrainedMap = JDBCHashMap<String, String>("test_map_constrained", loadOnInit = false, maxBuckets = 1)
|
||||
@ -105,7 +106,7 @@ class JDBCHashMapTestSuite {
|
||||
.createTestSuite()
|
||||
|
||||
private fun setUpDatabaseTx() {
|
||||
transaction = TransactionManager.currentOrNew(Connection.TRANSACTION_REPEATABLE_READ)
|
||||
transaction = DatabaseTransactionManager.currentOrNew()
|
||||
}
|
||||
|
||||
private fun closeDatabaseTx() {
|
||||
@ -232,7 +233,7 @@ class JDBCHashMapTestSuite {
|
||||
|
||||
@Before
|
||||
fun before() {
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -485,7 +485,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
private fun makeVaultObservers() {
|
||||
VaultSoftLockManager(services.vaultService, smm)
|
||||
ScheduledActivityObserver(services)
|
||||
HibernateObserver(services.vaultService.rawUpdates, HibernateConfiguration(services.schemaService))
|
||||
HibernateObserver(services.vaultService.rawUpdates, HibernateConfiguration(services.schemaService, configuration.database ?: Properties()))
|
||||
}
|
||||
|
||||
private fun makeInfo(): NodeInfo {
|
||||
@ -544,7 +544,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)
|
||||
this.database = configureDatabase(props, configuration.database)
|
||||
// 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.")
|
||||
@ -764,7 +764,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
|
||||
private fun createAttachmentStorage(): NodeAttachmentService {
|
||||
val attachmentsDir = (configuration.baseDirectory / "attachments").createDirectories()
|
||||
return NodeAttachmentService(attachmentsDir, configuration.dataSourceProperties, services.monitoringService.metrics)
|
||||
return NodeAttachmentService(attachmentsDir, configuration.dataSourceProperties, services.monitoringService.metrics, configuration.database)
|
||||
}
|
||||
|
||||
private inner class ServiceHubInternalImpl : ServiceHubInternal, SingletonSerializeAsToken() {
|
||||
@ -776,9 +776,9 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
override val validatedTransactions = makeTransactionStorage()
|
||||
override val transactionVerifierService by lazy { makeTransactionVerifierService() }
|
||||
override val networkMapCache by lazy { InMemoryNetworkMapCache(this) }
|
||||
override val vaultService by lazy { NodeVaultService(this, configuration.dataSourceProperties) }
|
||||
override val vaultService by lazy { NodeVaultService(this, configuration.dataSourceProperties, configuration.database) }
|
||||
override val vaultQueryService by lazy {
|
||||
HibernateVaultQueryImpl(HibernateConfiguration(schemaService), vaultService.updatesPublisher)
|
||||
HibernateVaultQueryImpl(HibernateConfiguration(schemaService, configuration.database ?: Properties()), vaultService.updatesPublisher)
|
||||
}
|
||||
// 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
|
||||
|
@ -25,6 +25,7 @@ interface NodeConfiguration : NodeSSLConfiguration {
|
||||
val emailAddress: String
|
||||
val exportJMXto: String
|
||||
val dataSourceProperties: Properties
|
||||
val database: Properties?
|
||||
val rpcUsers: List<User>
|
||||
val devMode: Boolean
|
||||
val certificateSigningService: URL
|
||||
@ -47,6 +48,7 @@ data class FullNodeConfiguration(
|
||||
override val keyStorePassword: String,
|
||||
override val trustStorePassword: String,
|
||||
override val dataSourceProperties: Properties,
|
||||
override val database: Properties?,
|
||||
override val certificateSigningService: URL,
|
||||
override val networkMapService: NetworkMapInfo?,
|
||||
override val minimumPlatformVersion: Int = 1,
|
||||
|
@ -15,10 +15,11 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
|
||||
import org.hibernate.service.UnknownUnwrapTypeException
|
||||
import java.sql.Connection
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class HibernateConfiguration(val schemaService: SchemaService, val useDefaultLogging: Boolean = false) {
|
||||
constructor(schemaService: SchemaService) : this(schemaService, false)
|
||||
class HibernateConfiguration(val schemaService: SchemaService, val useDefaultLogging: Boolean = false, val databaseProperties: Properties) {
|
||||
constructor(schemaService: SchemaService, databaseProperties: Properties) : this(schemaService, false, databaseProperties)
|
||||
|
||||
companion object {
|
||||
val logger = loggerFor<HibernateConfiguration>()
|
||||
@ -57,7 +58,7 @@ class HibernateConfiguration(val schemaService: SchemaService, val useDefaultLog
|
||||
// necessarily remain and would likely be replaced by something like Liquibase. For now it is very convenient though.
|
||||
// TODO: replace auto schema generation as it isn't intended for production use, according to Hibernate docs.
|
||||
val config = Configuration(metadataSources).setProperty("hibernate.connection.provider_class", HibernateConfiguration.NodeDatabaseConnectionProvider::class.java.name)
|
||||
.setProperty("hibernate.hbm2ddl.auto", "update")
|
||||
.setProperty("hibernate.hbm2ddl.auto", if (databaseProperties.getProperty("initDatabase","true") == "true") "update" else "validate")
|
||||
.setProperty("hibernate.show_sql", "$useDefaultLogging")
|
||||
.setProperty("hibernate.format_sql", "$useDefaultLogging")
|
||||
schemas.forEach { schema ->
|
||||
@ -102,7 +103,7 @@ class HibernateConfiguration(val schemaService: SchemaService, val useDefaultLog
|
||||
override fun supportsAggressiveRelease(): Boolean = true
|
||||
|
||||
override fun getConnection(): Connection {
|
||||
return DatabaseTransactionManager.newTransaction(Connection.TRANSACTION_REPEATABLE_READ).connection
|
||||
return DatabaseTransactionManager.newTransaction().connection
|
||||
}
|
||||
|
||||
override fun <T : Any?> unwrap(unwrapType: Class<T>): T {
|
||||
|
@ -3,6 +3,7 @@ package net.corda.node.services.database
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import io.requery.Persistable
|
||||
import io.requery.TransactionIsolation
|
||||
import io.requery.meta.EntityModel
|
||||
import io.requery.sql.KotlinEntityDataStore
|
||||
import io.requery.sql.SchemaModifier
|
||||
@ -13,7 +14,7 @@ import java.sql.Connection
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class RequeryConfiguration(val properties: Properties, val useDefaultLogging: Boolean = false) {
|
||||
class RequeryConfiguration(val properties: Properties, val useDefaultLogging: Boolean = false, val databaseProperties: Properties) {
|
||||
|
||||
companion object {
|
||||
val logger = loggerFor<RequeryConfiguration>()
|
||||
@ -40,11 +41,25 @@ class RequeryConfiguration(val properties: Properties, val useDefaultLogging: Bo
|
||||
fun makeSessionFactoryForModel(model: EntityModel): KotlinEntityDataStore<Persistable> {
|
||||
val configuration = KotlinConfigurationTransactionWrapper(model, dataSource, useDefaultLogging = this.useDefaultLogging)
|
||||
val tables = SchemaModifier(configuration)
|
||||
val mode = TableCreationMode.CREATE_NOT_EXISTS
|
||||
tables.createTables(mode)
|
||||
if (databaseProperties.getProperty("initDatabase","true") == "true" ) {
|
||||
val mode = TableCreationMode.CREATE_NOT_EXISTS
|
||||
tables.createTables(mode)
|
||||
}
|
||||
return KotlinEntityDataStore(configuration)
|
||||
}
|
||||
|
||||
// TODO: remove once Requery supports QUERY WITH COMPOSITE_KEY IN
|
||||
fun jdbcSession(): Connection = DatabaseTransactionManager.current().connection
|
||||
}
|
||||
|
||||
fun parserTransactionIsolationLevel(property: String?) : TransactionIsolation =
|
||||
when (property) {
|
||||
"none" -> TransactionIsolation.NONE
|
||||
"readUncommitted" -> TransactionIsolation.READ_UNCOMMITTED
|
||||
"readCommitted" -> TransactionIsolation.READ_COMMITTED
|
||||
"repeatableRead" -> TransactionIsolation.REPEATABLE_READ
|
||||
"serializable" -> TransactionIsolation.SERIALIZABLE
|
||||
else -> {
|
||||
TransactionIsolation.REPEATABLE_READ
|
||||
}
|
||||
}
|
||||
|
@ -32,13 +32,13 @@ import javax.annotation.concurrent.ThreadSafe
|
||||
* Stores attachments in H2 database.
|
||||
*/
|
||||
@ThreadSafe
|
||||
class NodeAttachmentService(val storePath: Path, dataSourceProperties: Properties, metrics: MetricRegistry)
|
||||
class NodeAttachmentService(val storePath: Path, dataSourceProperties: Properties, metrics: MetricRegistry, databaseProperties: Properties?)
|
||||
: AttachmentStorage, AcceptsFileUpload, SingletonSerializeAsToken() {
|
||||
companion object {
|
||||
private val log = loggerFor<NodeAttachmentService>()
|
||||
}
|
||||
|
||||
val configuration = RequeryConfiguration(dataSourceProperties)
|
||||
val configuration = RequeryConfiguration(dataSourceProperties, databaseProperties = databaseProperties ?: Properties())
|
||||
val session = configuration.sessionForModel(Models.PERSISTENCE)
|
||||
|
||||
@VisibleForTesting
|
||||
|
@ -57,7 +57,7 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
||||
DatabaseTransactionManager.current().close()
|
||||
Strand.sleep(millis)
|
||||
DatabaseTransactionManager.dataSource = db
|
||||
DatabaseTransactionManager.newTransaction(Connection.TRANSACTION_REPEATABLE_READ)
|
||||
DatabaseTransactionManager.newTransaction()
|
||||
} else Strand.sleep(millis)
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import net.corda.core.serialization.serialize
|
||||
import net.corda.core.transactions.*
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.node.services.database.RequeryConfiguration
|
||||
import net.corda.node.services.database.parserTransactionIsolationLevel
|
||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||
import net.corda.node.services.vault.schemas.requery.Models
|
||||
import net.corda.node.services.vault.schemas.requery.VaultSchema
|
||||
@ -60,7 +61,7 @@ import kotlin.concurrent.withLock
|
||||
* TODO: keep an audit trail with time stamps of previously unconsumed states "as of" a particular point in time.
|
||||
* TODO: have transaction storage do some caching.
|
||||
*/
|
||||
class NodeVaultService(private val services: ServiceHub, dataSourceProperties: Properties) : SingletonSerializeAsToken(), VaultService {
|
||||
class NodeVaultService(private val services: ServiceHub, dataSourceProperties: Properties, databaseProperties: Properties?) : SingletonSerializeAsToken(), VaultService {
|
||||
|
||||
private companion object {
|
||||
val log = loggerFor<NodeVaultService>()
|
||||
@ -69,8 +70,9 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
val stateRefCompositeColumn: RowExpression = RowExpression.of(listOf(VaultStatesEntity.TX_ID, VaultStatesEntity.INDEX))
|
||||
}
|
||||
|
||||
val configuration = RequeryConfiguration(dataSourceProperties)
|
||||
val configuration = RequeryConfiguration(dataSourceProperties, databaseProperties = databaseProperties ?: Properties())
|
||||
val session = configuration.sessionForModel(Models.VAULT)
|
||||
private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties?.getProperty("transactionIsolationLevel") ?:"")
|
||||
|
||||
private class InnerState {
|
||||
val _updatesPublisher = PublishSubject.create<Vault.Update<ContractState>>()!!
|
||||
@ -89,7 +91,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
val consumedStateRefs = update.consumed.map { it.ref }
|
||||
log.trace { "Removing $consumedStateRefs consumed contract states and adding $producedStateRefs produced contract states to the database." }
|
||||
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
producedStateRefsMap.forEach { it ->
|
||||
val state = VaultStatesEntity().apply {
|
||||
txId = it.key.txhash.toString()
|
||||
@ -142,7 +144,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
|
||||
override fun <T : ContractState> states(clazzes: Set<Class<T>>, statuses: EnumSet<Vault.StateStatus>, includeSoftLockedStates: Boolean): Iterable<StateAndRef<T>> {
|
||||
val stateAndRefs =
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
val query = select(VaultSchema.VaultStates::class)
|
||||
.where(VaultSchema.VaultStates::stateStatus `in` statuses)
|
||||
// TODO: temporary fix to continue supporting track() function (until becomes Typed)
|
||||
@ -164,7 +166,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
|
||||
override fun statesForRefs(refs: List<StateRef>): Map<StateRef, TransactionState<*>?> {
|
||||
val stateAndRefs =
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
var results: List<StateAndRef<*>> = emptyList()
|
||||
refs.forEach {
|
||||
val result = select(VaultSchema.VaultStates::class)
|
||||
@ -273,7 +275,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
private fun loadStates(refs: Collection<StateRef>): HashSet<StateAndRef<ContractState>> {
|
||||
val states = HashSet<StateAndRef<ContractState>>()
|
||||
if (refs.isNotEmpty()) {
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
val result = select(VaultStatesEntity::class).
|
||||
where(stateRefCompositeColumn.`in`(stateRefArgs(refs))).
|
||||
and(VaultSchema.VaultStates::stateStatus eq Vault.StateStatus.UNCONSUMED)
|
||||
@ -301,7 +303,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
}
|
||||
|
||||
override fun addNoteToTransaction(txnId: SecureHash, noteText: String) {
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
val txnNoteEntity = VaultTxnNoteEntity()
|
||||
txnNoteEntity.txId = txnId.toString()
|
||||
txnNoteEntity.note = noteText
|
||||
@ -310,7 +312,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
}
|
||||
|
||||
override fun getTransactionNotes(txnId: SecureHash): Iterable<String> {
|
||||
return session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
return session.withTransaction(transactionIsolationLevel) {
|
||||
(select(VaultSchema.VaultTxnNote::class) where (VaultSchema.VaultTxnNote::txId eq txnId.toString())).get().asIterable().map { it.note }
|
||||
}
|
||||
}
|
||||
@ -320,7 +322,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
val softLockTimestamp = services.clock.instant()
|
||||
val stateRefArgs = stateRefArgs(stateRefs)
|
||||
try {
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
val updatedRows = update(VaultStatesEntity::class)
|
||||
.set(VaultStatesEntity.LOCK_ID, lockId.toString())
|
||||
.set(VaultStatesEntity.LOCK_UPDATE_TIME, softLockTimestamp)
|
||||
@ -353,7 +355,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
|
||||
override fun softLockRelease(lockId: UUID, stateRefs: NonEmptySet<StateRef>?) {
|
||||
if (stateRefs == null) {
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
val update = update(VaultStatesEntity::class)
|
||||
.set(VaultStatesEntity.LOCK_ID, null)
|
||||
.set(VaultStatesEntity.LOCK_UPDATE_TIME, services.clock.instant())
|
||||
@ -365,7 +367,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
val updatedRows = update(VaultStatesEntity::class)
|
||||
.set(VaultStatesEntity.LOCK_ID, null)
|
||||
.set(VaultStatesEntity.LOCK_UPDATE_TIME, services.clock.instant())
|
||||
@ -482,7 +484,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
|
||||
override fun <T : ContractState> softLockedStates(lockId: UUID?): List<StateAndRef<T>> {
|
||||
val stateAndRefs =
|
||||
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
|
||||
session.withTransaction(transactionIsolationLevel) {
|
||||
val query = select(VaultSchema.VaultStates::class)
|
||||
.where(VaultSchema.VaultStates::stateStatus eq Vault.StateStatus.UNCONSUMED)
|
||||
.and(VaultSchema.VaultStates::contractStateClassName eq Cash.State::class.java.name)
|
||||
|
@ -14,15 +14,16 @@ import java.util.*
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
|
||||
//HikariDataSource implements also Closeable which allows CordaPersistence to be Closeable
|
||||
class CordaPersistence(var dataSource: HikariDataSource): Closeable {
|
||||
//HikariDataSource implements Closeable which allows CordaPersistence to be Closeable
|
||||
class CordaPersistence(var dataSource: HikariDataSource, 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"))
|
||||
|
||||
companion object {
|
||||
fun connect(dataSource: HikariDataSource): CordaPersistence {
|
||||
return CordaPersistence(dataSource).apply {
|
||||
fun connect(dataSource: HikariDataSource, databaseProperties: Properties): CordaPersistence {
|
||||
return CordaPersistence(dataSource, databaseProperties).apply {
|
||||
DatabaseTransactionManager(this)
|
||||
}
|
||||
}
|
||||
@ -31,7 +32,7 @@ class CordaPersistence(var dataSource: HikariDataSource): Closeable {
|
||||
fun createTransaction(): DatabaseTransaction {
|
||||
// We need to set the database for the current [Thread] or [Fiber] here as some tests share threads across databases.
|
||||
DatabaseTransactionManager.dataSource = this
|
||||
return DatabaseTransactionManager.currentOrNew(Connection.TRANSACTION_REPEATABLE_READ)
|
||||
return DatabaseTransactionManager.currentOrNew(transactionIsolationLevel)
|
||||
}
|
||||
|
||||
fun <T> isolatedTransaction(block: DatabaseTransaction.() -> T): T {
|
||||
@ -45,7 +46,7 @@ class CordaPersistence(var dataSource: HikariDataSource): Closeable {
|
||||
|
||||
fun <T> transaction(statement: DatabaseTransaction.() -> T): T {
|
||||
DatabaseTransactionManager.dataSource = this
|
||||
return transaction(Connection.TRANSACTION_REPEATABLE_READ, 3, statement)
|
||||
return transaction(transactionIsolationLevel, 3, statement)
|
||||
}
|
||||
|
||||
private fun <T> transaction(transactionIsolation: Int, repetitionAttempts: Int, statement: DatabaseTransaction.() -> T): T {
|
||||
@ -90,10 +91,10 @@ class CordaPersistence(var dataSource: HikariDataSource): Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
fun configureDatabase(props: Properties): CordaPersistence {
|
||||
val config = HikariConfig(props)
|
||||
fun configureDatabase(dataSourceProperties: Properties, databaseProperties: Properties?): CordaPersistence {
|
||||
val config = HikariConfig(dataSourceProperties)
|
||||
val dataSource = HikariDataSource(config)
|
||||
val persistence = CordaPersistence.connect(dataSource)
|
||||
val persistence = CordaPersistence.connect(dataSource, databaseProperties ?: Properties())
|
||||
|
||||
//org.jetbrains.exposed.sql.Database will be removed once Exposed library is removed
|
||||
val database = Database.connect(dataSource) { _ -> ExposedTransactionManager() }
|
||||
@ -191,3 +192,16 @@ fun <T : Any> rx.Observable<T>.wrapWithDatabaseTransaction(db: CordaPersistence?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun parserTransactionIsolationLevel(property: String?) : Int =
|
||||
when (property) {
|
||||
"none" -> Connection.TRANSACTION_NONE
|
||||
"readUncommitted" -> Connection.TRANSACTION_READ_UNCOMMITTED
|
||||
"readCommitted" -> Connection.TRANSACTION_READ_COMMITTED
|
||||
"repeatableRead" -> Connection.TRANSACTION_REPEATABLE_READ
|
||||
"serializable" -> Connection.TRANSACTION_SERIALIZABLE
|
||||
else -> {
|
||||
Connection.TRANSACTION_REPEATABLE_READ
|
||||
}
|
||||
}
|
||||
|
@ -74,11 +74,11 @@ class DatabaseTransactionManager(initDataSource: CordaPersistence) {
|
||||
|
||||
fun currentOrNull(): DatabaseTransaction? = manager.currentOrNull()
|
||||
|
||||
fun currentOrNew(isolation: Int) = currentOrNull() ?: manager.newTransaction(isolation)
|
||||
fun currentOrNew(isolation: Int = dataSource.transactionIsolationLevel) = currentOrNull() ?: manager.newTransaction(isolation)
|
||||
|
||||
fun current(): DatabaseTransaction = currentOrNull() ?: error("No transaction in context.")
|
||||
|
||||
fun newTransaction(isolation: Int) = manager.newTransaction(isolation)
|
||||
fun newTransaction(isolation: Int = dataSource.transactionIsolationLevel) = manager.newTransaction(isolation)
|
||||
}
|
||||
|
||||
data class Boundary(val txId: UUID)
|
||||
|
@ -9,6 +9,10 @@ dataSourceProperties = {
|
||||
"dataSource.user" = sa
|
||||
"dataSource.password" = ""
|
||||
}
|
||||
database = {
|
||||
transactionIsolationLevel = "repeatableRead"
|
||||
initDatabase = true
|
||||
}
|
||||
devMode = true
|
||||
certificateSigningService = "https://cordaci-netperm.corda.r3cev.com"
|
||||
useHTTPS = false
|
||||
|
@ -52,6 +52,7 @@ import static net.corda.core.utilities.ByteArrays.toHexString;
|
||||
import static net.corda.node.utilities.CordaPersistenceKt.configureDatabase;
|
||||
import static net.corda.testing.CoreTestUtils.*;
|
||||
import static net.corda.testing.node.MockServicesKt.makeTestDataSourceProperties;
|
||||
import static net.corda.testing.node.MockServicesKt.makeTestDatabaseProperties;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class VaultQueryJavaTests extends TestDependencyInjectionBase {
|
||||
@ -64,10 +65,10 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
|
||||
@Before
|
||||
public void setUp() {
|
||||
Properties dataSourceProps = makeTestDataSourceProperties(SecureHash.randomSHA256().toString());
|
||||
database = configureDatabase(dataSourceProps);
|
||||
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties());
|
||||
|
||||
Set<MappedSchema> customSchemas = new HashSet<>(Collections.singletonList(DummyLinearStateSchemaV1.INSTANCE));
|
||||
HibernateConfiguration hibernateConfig = new HibernateConfiguration(new NodeSchemaService(customSchemas));
|
||||
HibernateConfiguration hibernateConfig = new HibernateConfiguration(new NodeSchemaService(customSchemas), makeTestDatabaseProperties());
|
||||
database.transaction(
|
||||
statement -> { services = new MockServices(getMEGA_CORP_KEY()) {
|
||||
@NotNull
|
||||
|
@ -15,6 +15,7 @@ import net.corda.node.services.persistence.schemas.requery.AttachmentEntity
|
||||
import net.corda.node.services.transactions.SimpleNotaryService
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -35,7 +36,7 @@ class AttachmentTests {
|
||||
fun setUp() {
|
||||
mockNet = MockNetwork()
|
||||
val dataSourceProperties = makeTestDataSourceProperties()
|
||||
configuration = RequeryConfiguration(dataSourceProperties)
|
||||
configuration = RequeryConfiguration(dataSourceProperties, databaseProperties = makeTestDatabaseProperties())
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -5,6 +5,7 @@ import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.nodeapi.User
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.Test
|
||||
import java.net.URL
|
||||
@ -21,6 +22,7 @@ class FullNodeConfigurationTest {
|
||||
keyStorePassword = "cordacadevpass",
|
||||
trustStorePassword = "trustpass",
|
||||
dataSourceProperties = makeTestDataSourceProperties(ALICE.name.commonName),
|
||||
database = makeTestDatabaseProperties(),
|
||||
certificateSigningService = URL("http://localhost"),
|
||||
rpcUsers = emptyList(),
|
||||
verifierType = VerifierType.InMemory,
|
||||
|
@ -27,6 +27,7 @@ import net.corda.testing.contracts.fillWithSomeTestDeals
|
||||
import net.corda.testing.contracts.fillWithSomeTestLinearStates
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import net.corda.testing.schemas.DummyLinearStateSchemaV1
|
||||
import net.corda.testing.schemas.DummyLinearStateSchemaV2
|
||||
import org.assertj.core.api.Assertions
|
||||
@ -60,16 +61,17 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
val dataSourceProps = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProps)
|
||||
val defaultDatabaseProperties = makeTestDatabaseProperties()
|
||||
database = configureDatabase(dataSourceProps, defaultDatabaseProperties)
|
||||
val customSchemas = setOf(VaultSchemaV1, CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3)
|
||||
|
||||
database.transaction {
|
||||
|
||||
hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas))
|
||||
hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), makeTestDatabaseProperties())
|
||||
|
||||
services = object : MockServices(BOB_KEY) {
|
||||
override val vaultService: VaultService get() {
|
||||
val vaultService = NodeVaultService(this, dataSourceProps)
|
||||
val vaultService = NodeVaultService(this, dataSourceProps, makeTestDatabaseProperties())
|
||||
hibernatePersister = HibernateObserver(vaultService.rawUpdates, hibernateConfig)
|
||||
return vaultService
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import net.corda.testing.DUMMY_PUBKEY_1
|
||||
import net.corda.testing.TestDependencyInjectionBase
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -43,7 +44,7 @@ class RequeryConfigurationTest : TestDependencyInjectionBase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
val dataSourceProperties = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProperties)
|
||||
database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties())
|
||||
newTransactionStorage()
|
||||
newRequeryStorage(dataSourceProperties)
|
||||
}
|
||||
@ -157,7 +158,7 @@ class RequeryConfigurationTest : TestDependencyInjectionBase() {
|
||||
val nativeQuery = "SELECT v.transaction_id, v.output_index FROM vault_states v WHERE v.state_status = 0"
|
||||
|
||||
database.transaction {
|
||||
val configuration = RequeryConfiguration(dataSourceProperties, true)
|
||||
val configuration = RequeryConfiguration(dataSourceProperties, true, makeTestDatabaseProperties())
|
||||
val jdbcSession = configuration.jdbcSession()
|
||||
val prepStatement = jdbcSession.prepareStatement(nativeQuery)
|
||||
val rs = prepStatement.executeQuery()
|
||||
@ -197,7 +198,7 @@ class RequeryConfigurationTest : TestDependencyInjectionBase() {
|
||||
|
||||
private fun newRequeryStorage(dataSourceProperties: Properties) {
|
||||
database.transaction {
|
||||
val configuration = RequeryConfiguration(dataSourceProperties, true)
|
||||
val configuration = RequeryConfiguration(dataSourceProperties, true, makeTestDatabaseProperties())
|
||||
requerySession = configuration.sessionForModel(Models.VAULT)
|
||||
}
|
||||
}
|
||||
|
@ -21,12 +21,10 @@ import net.corda.node.services.statemachine.StateMachineManager
|
||||
import net.corda.node.services.vault.NodeVaultService
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.testing.getTestX509Name
|
||||
import net.corda.testing.node.InMemoryMessagingNetwork
|
||||
import net.corda.testing.node.MockKeyManagementService
|
||||
import net.corda.testing.node.TestClock
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.testNodeConfiguration
|
||||
import net.corda.testing.initialiseTestSerialization
|
||||
import net.corda.testing.node.*
|
||||
import net.corda.testing.node.TestClock
|
||||
import net.corda.testing.resetTestSerialization
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
@ -37,6 +35,7 @@ import java.nio.file.Paths
|
||||
import java.security.PublicKey
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -75,7 +74,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
smmHasRemovedAllFlows = CountDownLatch(1)
|
||||
calls = 0
|
||||
val dataSourceProps = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProps)
|
||||
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties())
|
||||
val identityService = InMemoryIdentityService(trustRoot = DUMMY_CA.certificate)
|
||||
val kms = MockKeyManagementService(identityService, ALICE_KEY)
|
||||
|
||||
@ -92,7 +91,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
overrideClock = testClock,
|
||||
keyManagement = kms,
|
||||
network = mockMessagingService), TestReference {
|
||||
override val vaultService: VaultService = NodeVaultService(this, dataSourceProps)
|
||||
override val vaultService: VaultService = NodeVaultService(this, dataSourceProps, makeTestDatabaseProperties())
|
||||
override val testReference = this@NodeSchedulerServiceTest
|
||||
}
|
||||
scheduler = NodeSchedulerService(services, schedulerGatedExecutor)
|
||||
|
@ -22,6 +22,7 @@ import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MOCK_VERSION_INFO
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.After
|
||||
@ -30,6 +31,7 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.net.ServerSocket
|
||||
import java.util.*
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||
import kotlin.concurrent.thread
|
||||
@ -68,7 +70,7 @@ class ArtemisMessagingTests : TestDependencyInjectionBase() {
|
||||
baseDirectory = baseDirectory,
|
||||
myLegalName = ALICE.name)
|
||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
networkMapRegistrationFuture = Futures.immediateFuture(Unit)
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.LogHelper
|
||||
import net.corda.testing.TestDependencyInjectionBase
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.junit.After
|
||||
@ -32,7 +33,7 @@ class DBCheckpointStorageTests : TestDependencyInjectionBase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
newCheckpointStorage()
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.LogHelper
|
||||
import net.corda.testing.TestDependencyInjectionBase
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -28,7 +29,7 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
newTransactionStorage()
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import net.corda.node.services.transactions.PersistentUniquenessProvider
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -42,9 +43,9 @@ class NodeAttachmentStorageTest {
|
||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||
|
||||
dataSourceProperties = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProperties)
|
||||
database = configureDatabase(dataSourceProperties, makeTestDatabaseProperties())
|
||||
|
||||
configuration = RequeryConfiguration(dataSourceProperties)
|
||||
configuration = RequeryConfiguration(dataSourceProperties, databaseProperties = makeTestDatabaseProperties())
|
||||
fs = Jimfs.newFileSystem(Configuration.unix())
|
||||
}
|
||||
|
||||
@ -59,7 +60,7 @@ class NodeAttachmentStorageTest {
|
||||
val expectedHash = testJar.readAll().sha256()
|
||||
|
||||
database.transaction {
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry())
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties())
|
||||
val id = testJar.read { storage.importAttachment(it) }
|
||||
assertEquals(expectedHash, id)
|
||||
|
||||
@ -85,7 +86,7 @@ class NodeAttachmentStorageTest {
|
||||
fun `duplicates not allowed`() {
|
||||
val testJar = makeTestJar()
|
||||
database.transaction {
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry())
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties())
|
||||
testJar.read {
|
||||
storage.importAttachment(it)
|
||||
}
|
||||
@ -101,7 +102,7 @@ class NodeAttachmentStorageTest {
|
||||
fun `corrupt entry throws exception`() {
|
||||
val testJar = makeTestJar()
|
||||
database.transaction {
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry())
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties())
|
||||
val id = testJar.read { storage.importAttachment(it) }
|
||||
|
||||
// Corrupt the file in the store.
|
||||
@ -129,7 +130,7 @@ class NodeAttachmentStorageTest {
|
||||
@Test
|
||||
fun `non jar rejected`() {
|
||||
database.transaction {
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry())
|
||||
val storage = NodeAttachmentService(fs.getPath("/"), dataSourceProperties, MetricRegistry(), makeTestDatabaseProperties())
|
||||
val path = fs.getPath("notajar")
|
||||
path.writeLines(listOf("Hey", "there!"))
|
||||
path.read {
|
||||
|
@ -14,6 +14,7 @@ import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.MEGA_CORP
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.hibernate.annotations.Cascade
|
||||
import org.hibernate.annotations.CascadeType
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
@ -31,7 +32,7 @@ class HibernateObserverTests {
|
||||
@Before
|
||||
fun setUp() {
|
||||
LogHelper.setLevel(HibernateObserver::class)
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
}
|
||||
|
||||
@After
|
||||
@ -101,7 +102,7 @@ class HibernateObserverTests {
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val observer = HibernateObserver(rawUpdatesPublisher, HibernateConfiguration(schemaService))
|
||||
val observer = HibernateObserver(rawUpdatesPublisher, HibernateConfiguration(schemaService, makeTestDatabaseProperties()))
|
||||
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()
|
||||
|
@ -15,6 +15,7 @@ import net.corda.testing.LogHelper
|
||||
import net.corda.testing.TestDependencyInjectionBase
|
||||
import net.corda.testing.freeLocalHostAndPort
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -34,7 +35,7 @@ class DistributedImmutableMapTests : TestDependencyInjectionBase() {
|
||||
fun setup() {
|
||||
LogHelper.setLevel("-org.apache.activemq")
|
||||
LogHelper.setLevel(NetworkMapService::class)
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
cluster = setUpCluster()
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import net.corda.testing.MEGA_CORP
|
||||
import net.corda.testing.TestDependencyInjectionBase
|
||||
import net.corda.testing.generateStateRef
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -24,7 +25,7 @@ class PersistentUniquenessProviderTests : TestDependencyInjectionBase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -23,6 +23,7 @@ import net.corda.testing.*
|
||||
import net.corda.testing.contracts.fillWithSomeTestCash
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import net.corda.testing.schemas.DummyLinearStateSchemaV1
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
@ -46,10 +47,10 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
fun setUp() {
|
||||
LogHelper.setLevel(NodeVaultService::class)
|
||||
val dataSourceProps = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProps)
|
||||
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties())
|
||||
database.transaction {
|
||||
val customSchemas = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1)
|
||||
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas))
|
||||
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), makeTestDatabaseProperties())
|
||||
services = object : MockServices() {
|
||||
override val vaultService: VaultService = makeVaultService(dataSourceProps, hibernateConfig)
|
||||
|
||||
|
@ -30,6 +30,7 @@ import net.corda.testing.*
|
||||
import net.corda.testing.contracts.*
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import net.corda.testing.schemas.DummyLinearStateSchemaV1
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@ -56,10 +57,10 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
val dataSourceProps = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProps)
|
||||
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties())
|
||||
database.transaction {
|
||||
val customSchemas = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1)
|
||||
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas))
|
||||
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), makeTestDatabaseProperties())
|
||||
services = object : MockServices(MEGA_CORP_KEY) {
|
||||
override val vaultService: VaultService = makeVaultService(dataSourceProps, hibernateConfig)
|
||||
|
||||
@ -86,7 +87,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
||||
@Ignore
|
||||
@Test
|
||||
fun createPersistentTestDb() {
|
||||
val database = configureDatabase(makePersistentDataSourceProperties())
|
||||
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties())
|
||||
|
||||
setUpDb(database, 5000)
|
||||
|
||||
|
@ -20,6 +20,7 @@ import net.corda.testing.*
|
||||
import net.corda.testing.contracts.*
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import net.corda.testing.schemas.DummyLinearStateSchemaV1
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
@ -43,10 +44,10 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
fun setUp() {
|
||||
LogHelper.setLevel(VaultWithCashTest::class)
|
||||
val dataSourceProps = makeTestDataSourceProperties()
|
||||
database = configureDatabase(dataSourceProps)
|
||||
database = configureDatabase(dataSourceProps, makeTestDatabaseProperties())
|
||||
database.transaction {
|
||||
val customSchemas = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1)
|
||||
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas))
|
||||
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), makeTestDatabaseProperties())
|
||||
services = object : MockServices() {
|
||||
override val vaultService: VaultService = makeVaultService(dataSourceProps, hibernateConfig)
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.google.common.util.concurrent.SettableFuture
|
||||
import net.corda.core.internal.bufferUntilSubscribed
|
||||
import net.corda.core.internal.tee
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
@ -19,7 +20,7 @@ class ObservablesTests {
|
||||
val toBeClosed = mutableListOf<Closeable>()
|
||||
|
||||
fun createDatabase(): CordaPersistence {
|
||||
val database = configureDatabase(makeTestDataSourceProperties())
|
||||
val database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
toBeClosed += database
|
||||
return database
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import net.corda.testing.*
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.After
|
||||
import org.junit.Assert
|
||||
@ -59,7 +60,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
database = configureDatabase(makeTestDataSourceProperties())
|
||||
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties())
|
||||
database.transaction {
|
||||
oracle = NodeInterestRates.Oracle(
|
||||
MEGA_CORP,
|
||||
|
@ -21,6 +21,7 @@ import net.corda.node.services.identity.InMemoryIdentityService
|
||||
import net.corda.nodeapi.config.SSLConfiguration
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.makeTestDatabaseProperties
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x500.X500NameBuilder
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
||||
@ -163,6 +164,7 @@ fun testNodeConfiguration(
|
||||
whenever(nc.trustStorePassword).thenReturn("trustpass")
|
||||
whenever(nc.rpcUsers).thenReturn(emptyList())
|
||||
whenever(nc.dataSourceProperties).thenReturn(makeTestDataSourceProperties(myLegalName.commonName))
|
||||
whenever(nc.database).thenReturn(makeTestDatabaseProperties())
|
||||
whenever(nc.emailAddress).thenReturn("")
|
||||
whenever(nc.exportJMXto).thenReturn("")
|
||||
whenever(nc.devMode).thenReturn(true)
|
||||
|
@ -80,8 +80,8 @@ open class MockServices(vararg val keys: KeyPair) : ServiceHub {
|
||||
}
|
||||
override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2)
|
||||
|
||||
fun makeVaultService(dataSourceProps: Properties, hibernateConfig: HibernateConfiguration = HibernateConfiguration(NodeSchemaService())): VaultService {
|
||||
val vaultService = NodeVaultService(this, dataSourceProps)
|
||||
fun makeVaultService(dataSourceProps: Properties, hibernateConfig: HibernateConfiguration = HibernateConfiguration(NodeSchemaService(), makeTestDatabaseProperties())): VaultService {
|
||||
val vaultService = NodeVaultService(this, dataSourceProps, makeTestDatabaseProperties())
|
||||
HibernateObserver(vaultService.rawUpdates, hibernateConfig)
|
||||
return vaultService
|
||||
}
|
||||
@ -196,4 +196,10 @@ fun makeTestDataSourceProperties(nodeName: String = SecureHash.randomSHA256().to
|
||||
return props
|
||||
}
|
||||
|
||||
fun makeTestDatabaseProperties(): Properties {
|
||||
val props = Properties()
|
||||
props.setProperty("transactionIsolationLevel", "repeatableRead") //for other possible values see net.corda.node.utilities.CordaPeristence.parserTransactionIsolationLevel(String)
|
||||
return props
|
||||
}
|
||||
|
||||
val MOCK_VERSION_INFO = VersionInfo(1, "Mock release", "Mock revision", "Mock Vendor")
|
||||
|
@ -32,7 +32,7 @@ class SimpleNode(val config: NodeConfiguration, val address: NetworkHostAndPort
|
||||
rpcAddress: NetworkHostAndPort = freeLocalHostAndPort(),
|
||||
trustRoot: X509Certificate) : AutoCloseable {
|
||||
|
||||
val database: CordaPersistence = configureDatabase(config.dataSourceProperties)
|
||||
val database: CordaPersistence = configureDatabase(config.dataSourceProperties, config.database)
|
||||
val userService = RPCUserServiceImpl(config.rpcUsers)
|
||||
val monitoringService = MonitoringService(MetricRegistry())
|
||||
val identity: KeyPair = generateKeyPair()
|
||||
|
Loading…
x
Reference in New Issue
Block a user