Moved CordaPersistence and dependent classes into internal package in node-api. This is so that the doorman can make use of them without needing a compile dependency to node.

This commit is contained in:
Shams Asari 2017-11-28 18:12:48 +00:00
parent 2525fb52be
commit b638b30d2a
63 changed files with 331 additions and 297 deletions

View File

@ -15,7 +15,7 @@ import net.corda.core.utilities.unwrap
import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.node.utilities.currentDBSession import net.corda.nodeapi.internal.persistence.currentDBSession
import net.corda.testing.ALICE_NAME import net.corda.testing.ALICE_NAME
import net.corda.testing.BOB_NAME import net.corda.testing.BOB_NAME
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork

View File

@ -3,7 +3,10 @@ package net.corda.finance.contracts.asset
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.generateKeyPair import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.* import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.VaultService import net.corda.core.node.services.VaultService
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
@ -16,7 +19,7 @@ import net.corda.finance.utils.sumCashBy
import net.corda.finance.utils.sumCashOrNull import net.corda.finance.utils.sumCashOrNull
import net.corda.finance.utils.sumCashOrZero import net.corda.finance.utils.sumCashOrZero
import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.NodeVaultService
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.contracts.DummyState import net.corda.testing.contracts.DummyState
import net.corda.testing.contracts.VaultFiller import net.corda.testing.contracts.VaultFiller

View File

@ -3,7 +3,7 @@ apply plugin: 'net.corda.plugins.quasar-utils'
apply plugin: 'net.corda.plugins.publish-utils' apply plugin: 'net.corda.plugins.publish-utils'
apply plugin: 'com.jfrog.artifactory' apply plugin: 'com.jfrog.artifactory'
description 'Corda node Artemis API' description 'Corda node API'
dependencies { dependencies {
compile project(":core") compile project(":core")

View File

@ -1,63 +1,79 @@
package net.corda.node.utilities package net.corda.nodeapi.internal.persistence
import com.zaxxer.hikari.HikariConfig import net.corda.core.schemas.MappedSchema
import com.zaxxer.hikari.HikariDataSource
import net.corda.core.node.services.IdentityService
import net.corda.node.services.api.SchemaService
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.persistence.HibernateConfiguration
import net.corda.node.services.schema.NodeSchemaService
import rx.Observable import rx.Observable
import rx.Subscriber import rx.Subscriber
import rx.subjects.UnicastSubject import rx.subjects.UnicastSubject
import java.io.Closeable import java.io.Closeable
import java.sql.Connection import java.sql.Connection
import java.sql.SQLException import java.sql.SQLException
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
import javax.persistence.AttributeConverter
import javax.sql.DataSource
/** /**
* Table prefix for all tables owned by the node module. * Table prefix for all tables owned by the node module.
*/ */
const val NODE_DATABASE_PREFIX = "node_" const val NODE_DATABASE_PREFIX = "node_"
//HikariDataSource implements Closeable which allows CordaPersistence to be Closeable // This class forms part of the node config and so any changes to it must be handled with care
data class DatabaseConfig(
val initialiseSchema: Boolean = true,
val serverNameTablePrefix: String = "",
val transactionIsolationLevel: TransactionIsolationLevel = TransactionIsolationLevel.REPEATABLE_READ
)
// This class forms part of the node config and so any changes to it must be handled with care
enum class TransactionIsolationLevel {
NONE,
READ_UNCOMMITTED,
READ_COMMITTED,
REPEATABLE_READ,
SERIALIZABLE;
/**
* The JDBC constant value of the same name but prefixed with TRANSACTION_ defined in [java.sql.Connection].
*/
val jdbcValue: Int = java.sql.Connection::class.java.getField("TRANSACTION_$name").get(null) as Int
}
class CordaPersistence( class CordaPersistence(
val dataSource: HikariDataSource, val dataSource: DataSource,
private val schemaService: SchemaService, databaseConfig: DatabaseConfig,
private val identityService: IdentityService, schemas: Set<MappedSchema>,
databaseConfig: DatabaseConfig attributeConverters: Collection<AttributeConverter<*, *>> = emptySet()
) : Closeable { ) : Closeable {
val transactionIsolationLevel = databaseConfig.transactionIsolationLevel.jdbcValue val defaultIsolationLevel = databaseConfig.transactionIsolationLevel
val hibernateConfig: HibernateConfiguration by lazy { val hibernateConfig: HibernateConfiguration by lazy {
transaction { transaction {
HibernateConfiguration(schemaService, databaseConfig, identityService) HibernateConfiguration(schemas, databaseConfig, attributeConverters)
} }
} }
val entityManagerFactory get() = hibernateConfig.sessionFactoryForRegisteredSchemas val entityManagerFactory get() = hibernateConfig.sessionFactoryForRegisteredSchemas
companion object { init {
fun connect(dataSource: HikariDataSource, schemaService: SchemaService, identityService: IdentityService, databaseConfig: DatabaseConfig): CordaPersistence { DatabaseTransactionManager(this)
return CordaPersistence(dataSource, schemaService, identityService, databaseConfig).apply { // Check not in read-only mode.
DatabaseTransactionManager(this) transaction {
dataSource.connection.use {
check(!it.metaData.isReadOnly) { "Database should not be readonly." }
} }
} }
} }
/** /**
* Creates an instance of [DatabaseTransaction], with the given isolation level. * Creates an instance of [DatabaseTransaction], with the given transaction isolation level.
* @param isolationLevel isolation level for the transaction. If not specified the default (i.e. provided at the creation time) is used.
*/ */
fun createTransaction(isolationLevel: Int): DatabaseTransaction { fun createTransaction(isolationLevel: TransactionIsolationLevel): DatabaseTransaction {
// We need to set the database for the current [Thread] or [Fiber] here as some tests share threads across databases. // We need to set the database for the current [Thread] or [Fiber] here as some tests share threads across databases.
DatabaseTransactionManager.dataSource = this DatabaseTransactionManager.dataSource = this
return DatabaseTransactionManager.currentOrNew(isolationLevel) return DatabaseTransactionManager.currentOrNew(isolationLevel)
} }
/** /**
* Creates an instance of [DatabaseTransaction], with the transaction isolation level specified at the creation time. * Creates an instance of [DatabaseTransaction], with the default transaction isolation level.
*/ */
fun createTransaction(): DatabaseTransaction = createTransaction(transactionIsolationLevel) fun createTransaction(): DatabaseTransaction = createTransaction(defaultIsolationLevel)
fun createSession(): Connection { fun createSession(): Connection {
// We need to set the database for the current [Thread] or [Fiber] here as some tests share threads across databases. // We need to set the database for the current [Thread] or [Fiber] here as some tests share threads across databases.
@ -71,7 +87,7 @@ class CordaPersistence(
* @param isolationLevel isolation level for the transaction. * @param isolationLevel isolation level for the transaction.
* @param statement to be executed in the scope of this transaction. * @param statement to be executed in the scope of this transaction.
*/ */
fun <T> transaction(isolationLevel: Int, statement: DatabaseTransaction.() -> T): T { fun <T> transaction(isolationLevel: TransactionIsolationLevel, statement: DatabaseTransaction.() -> T): T {
DatabaseTransactionManager.dataSource = this DatabaseTransactionManager.dataSource = this
return transaction(isolationLevel, 3, statement) return transaction(isolationLevel, 3, statement)
} }
@ -80,22 +96,21 @@ class CordaPersistence(
* Executes given statement in the scope of transaction with the transaction level specified at the creation time. * Executes given statement in the scope of transaction with the transaction level specified at the creation time.
* @param statement to be executed in the scope of this transaction. * @param statement to be executed in the scope of this transaction.
*/ */
fun <T> transaction(statement: DatabaseTransaction.() -> T): T = transaction(transactionIsolationLevel, statement) fun <T> transaction(statement: DatabaseTransaction.() -> T): T = transaction(defaultIsolationLevel, statement)
private fun <T> transaction(transactionIsolation: Int, repetitionAttempts: Int, statement: DatabaseTransaction.() -> T): T { private fun <T> transaction(isolationLevel: TransactionIsolationLevel, repetitionAttempts: Int, statement: DatabaseTransaction.() -> T): T {
val outer = DatabaseTransactionManager.currentOrNull() val outer = DatabaseTransactionManager.currentOrNull()
return if (outer != null) { return if (outer != null) {
outer.statement() outer.statement()
} else { } else {
inTopLevelTransaction(transactionIsolation, repetitionAttempts, statement) inTopLevelTransaction(isolationLevel, repetitionAttempts, statement)
} }
} }
private fun <T> inTopLevelTransaction(transactionIsolation: Int, repetitionAttempts: Int, statement: DatabaseTransaction.() -> T): T { private fun <T> inTopLevelTransaction(isolationLevel: TransactionIsolationLevel, repetitionAttempts: Int, statement: DatabaseTransaction.() -> T): T {
var repetitions = 0 var repetitions = 0
while (true) { while (true) {
val transaction = DatabaseTransactionManager.currentOrNew(transactionIsolation) val transaction = DatabaseTransactionManager.currentOrNew(isolationLevel)
try { try {
val answer = transaction.statement() val answer = transaction.statement()
transaction.commit() transaction.commit()
@ -116,23 +131,11 @@ class CordaPersistence(
} }
override fun close() { override fun close() {
dataSource.close() // DataSource doesn't implement AutoCloseable so we just have to hope that the implementation does so that we can close it
(dataSource as? AutoCloseable)?.close()
} }
} }
fun configureDatabase(dataSourceProperties: Properties, databaseConfig: DatabaseConfig, identityService: IdentityService, schemaService: SchemaService = NodeSchemaService(null)): CordaPersistence {
val config = HikariConfig(dataSourceProperties)
val dataSource = HikariDataSource(config)
val persistence = CordaPersistence.connect(dataSource, schemaService, identityService, databaseConfig)
// Check not in read-only mode.
persistence.transaction {
persistence.dataSource.connection.use {
check(!it.metaData.isReadOnly) { "Database should not be readonly." }
}
}
return persistence
}
/** /**
* Buffer observations until after the current database transaction has been closed. Observations are never * Buffer observations until after the current database transaction has been closed. Observations are never
* dropped, simply delayed. * dropped, simply delayed.
@ -144,7 +147,7 @@ fun configureDatabase(dataSourceProperties: Properties, databaseConfig: Database
*/ */
fun <T : Any> rx.Observer<T>.bufferUntilDatabaseCommit(): rx.Observer<T> { fun <T : Any> rx.Observer<T>.bufferUntilDatabaseCommit(): rx.Observer<T> {
val currentTxId = DatabaseTransactionManager.transactionId val currentTxId = DatabaseTransactionManager.transactionId
val databaseTxBoundary: Observable<DatabaseTransactionManager.Boundary> = DatabaseTransactionManager.transactionBoundaries.filter { it.txId == currentTxId }.first() val databaseTxBoundary: Observable<DatabaseTransactionManager.Boundary> = DatabaseTransactionManager.transactionBoundaries.first { it.txId == currentTxId }
val subject = UnicastSubject.create<T>() val subject = UnicastSubject.create<T>()
subject.delaySubscription(databaseTxBoundary).subscribe(this) subject.delaySubscription(databaseTxBoundary).subscribe(this)
databaseTxBoundary.doOnCompleted { subject.onCompleted() } databaseTxBoundary.doOnCompleted { subject.onCompleted() }
@ -183,14 +186,9 @@ private class DatabaseTransactionWrappingSubscriber<U>(val db: CordaPersistence?
// A subscriber that wraps another but does not pass on observations to it. // A subscriber that wraps another but does not pass on observations to it.
private class NoOpSubscriber<U>(t: Subscriber<in U>) : Subscriber<U>(t) { private class NoOpSubscriber<U>(t: Subscriber<in U>) : Subscriber<U>(t) {
override fun onCompleted() { override fun onCompleted() {}
} override fun onError(e: Throwable?) {}
override fun onNext(s: U) {}
override fun onError(e: Throwable?) {
}
override fun onNext(s: U) {
}
} }
/** /**

View File

@ -0,0 +1,61 @@
package net.corda.nodeapi.internal.persistence
import org.hibernate.Session
import org.hibernate.Transaction
import rx.subjects.Subject
import java.sql.Connection
import java.util.*
class DatabaseTransaction(
isolation: Int,
private val threadLocal: ThreadLocal<DatabaseTransaction>,
private val transactionBoundaries: Subject<DatabaseTransactionManager.Boundary, DatabaseTransactionManager.Boundary>,
val cordaPersistence: CordaPersistence
) {
val id: UUID = UUID.randomUUID()
val connection: Connection by lazy(LazyThreadSafetyMode.NONE) {
cordaPersistence.dataSource.connection.apply {
autoCommit = false
transactionIsolation = isolation
}
}
private val sessionDelegate = lazy {
val session = cordaPersistence.entityManagerFactory.withOptions().connection(connection).openSession()
hibernateTransaction = session.beginTransaction()
session
}
val session: Session by sessionDelegate
private lateinit var hibernateTransaction: Transaction
private val outerTransaction: DatabaseTransaction? = threadLocal.get()
fun commit() {
if (sessionDelegate.isInitialized()) {
hibernateTransaction.commit()
}
connection.commit()
}
fun rollback() {
if (sessionDelegate.isInitialized() && session.isOpen) {
session.clear()
}
if (!connection.isClosed) {
connection.rollback()
}
}
fun close() {
if (sessionDelegate.isInitialized() && session.isOpen) {
session.close()
}
connection.close()
threadLocal.set(outerTransaction)
if (outerTransaction == null) {
transactionBoundaries.onNext(DatabaseTransactionManager.Boundary(id))
}
}
}

View File

@ -1,68 +1,14 @@
package net.corda.node.utilities package net.corda.nodeapi.internal.persistence
import co.paralleluniverse.strands.Strand import co.paralleluniverse.strands.Strand
import org.hibernate.Session import org.hibernate.Session
import org.hibernate.Transaction
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import rx.subjects.Subject import rx.subjects.Subject
import java.sql.Connection
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
class DatabaseTransaction(isolation: Int, val threadLocal: ThreadLocal<DatabaseTransaction>, fun currentDBSession(): Session = DatabaseTransactionManager.current().session
val transactionBoundaries: Subject<DatabaseTransactionManager.Boundary, DatabaseTransactionManager.Boundary>,
val cordaPersistence: CordaPersistence) {
val id: UUID = UUID.randomUUID()
val connection: Connection by lazy(LazyThreadSafetyMode.NONE) {
cordaPersistence.dataSource.connection
.apply {
autoCommit = false
transactionIsolation = isolation
}
}
private val sessionDelegate = lazy {
val session = cordaPersistence.entityManagerFactory.withOptions().connection(connection).openSession()
hibernateTransaction = session.beginTransaction()
session
}
val session: Session by sessionDelegate
private lateinit var hibernateTransaction: Transaction
private val outerTransaction: DatabaseTransaction? = threadLocal.get()
fun commit() {
if (sessionDelegate.isInitialized()) {
hibernateTransaction.commit()
}
connection.commit()
}
fun rollback() {
if (sessionDelegate.isInitialized() && session.isOpen) {
session.clear()
}
if (!connection.isClosed) {
connection.rollback()
}
}
fun close() {
if (sessionDelegate.isInitialized() && session.isOpen) {
session.close()
}
connection.close()
threadLocal.set(outerTransaction)
if (outerTransaction == null) {
transactionBoundaries.onNext(DatabaseTransactionManager.Boundary(id))
}
}
}
fun currentDBSession() = DatabaseTransactionManager.current().session
class DatabaseTransactionManager(initDataSource: CordaPersistence) { class DatabaseTransactionManager(initDataSource: CordaPersistence) {
companion object { companion object {
private val threadLocalDb = ThreadLocal<CordaPersistence>() private val threadLocalDb = ThreadLocal<CordaPersistence>()
@ -95,11 +41,15 @@ class DatabaseTransactionManager(initDataSource: CordaPersistence) {
fun currentOrNull(): DatabaseTransaction? = manager.currentOrNull() fun currentOrNull(): DatabaseTransaction? = manager.currentOrNull()
fun currentOrNew(isolation: Int = dataSource.transactionIsolationLevel) = currentOrNull() ?: manager.newTransaction(isolation) fun currentOrNew(isolation: TransactionIsolationLevel = dataSource.defaultIsolationLevel): DatabaseTransaction {
return currentOrNull() ?: manager.newTransaction(isolation.jdbcValue)
}
fun current(): DatabaseTransaction = currentOrNull() ?: error("No transaction in context.") fun current(): DatabaseTransaction = currentOrNull() ?: error("No transaction in context.")
fun newTransaction(isolation: Int = dataSource.transactionIsolationLevel) = manager.newTransaction(isolation) fun newTransaction(isolation: TransactionIsolationLevel = dataSource.defaultIsolationLevel): DatabaseTransaction {
return manager.newTransaction(isolation.jdbcValue)
}
} }
data class Boundary(val txId: UUID) data class Boundary(val txId: UUID)

View File

@ -1,13 +1,9 @@
package net.corda.node.services.persistence package net.corda.nodeapi.internal.persistence
import net.corda.core.internal.castIfPossible import net.corda.core.internal.castIfPossible
import net.corda.core.node.services.IdentityService
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.toHexString import net.corda.core.utilities.toHexString
import net.corda.node.services.api.SchemaService
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.utilities.DatabaseTransactionManager
import org.hibernate.SessionFactory import org.hibernate.SessionFactory
import org.hibernate.boot.MetadataSources import org.hibernate.boot.MetadataSources
import org.hibernate.boot.model.naming.Identifier import org.hibernate.boot.model.naming.Identifier
@ -18,14 +14,18 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
import org.hibernate.service.UnknownUnwrapTypeException import org.hibernate.service.UnknownUnwrapTypeException
import org.hibernate.type.AbstractSingleColumnStandardBasicType import org.hibernate.type.AbstractSingleColumnStandardBasicType
import org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor
import org.hibernate.type.descriptor.sql.BlobTypeDescriptor import org.hibernate.type.descriptor.sql.BlobTypeDescriptor
import org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor import org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor
import java.sql.Connection import java.sql.Connection
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import javax.persistence.AttributeConverter
class HibernateConfiguration(val schemaService: SchemaService, private val databaseConfig: DatabaseConfig, private val identityService: IdentityService) { class HibernateConfiguration(
schemas: Set<MappedSchema>,
private val databaseConfig: DatabaseConfig,
private val attributeConverters: Collection<AttributeConverter<*, *>>
) {
companion object { companion object {
private val logger = contextLogger() private val logger = contextLogger()
} }
@ -33,13 +33,8 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab
// 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.
private val sessionFactories = ConcurrentHashMap<Set<MappedSchema>, SessionFactory>() private val sessionFactories = ConcurrentHashMap<Set<MappedSchema>, SessionFactory>()
val sessionFactoryForRegisteredSchemas = schemaService.schemaOptions.keys.let { val sessionFactoryForRegisteredSchemas = schemas.let {
logger.info("Init HibernateConfiguration for schemas: $it") logger.info("Init HibernateConfiguration for schemas: $it")
// Register the AbstractPartyDescriptor so Hibernate doesn't warn when encountering AbstractParty. Unfortunately
// Hibernate warns about not being able to find a descriptor if we don't provide one, but won't use it by default
// so we end up providing both descriptor and converter. We should re-examine this in later versions to see if
// either Hibernate can be convinced to stop warning, use the descriptor by default, or something else.
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(identityService))
sessionFactoryForSchemas(it) sessionFactoryForSchemas(it)
} }
@ -78,7 +73,7 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab
} }
}) })
// register custom converters // register custom converters
applyAttributeConverter(AbstractPartyToX500NameAsStringConverter(identityService)) attributeConverters.forEach { applyAttributeConverter(it) }
// Register a tweaked version of `org.hibernate.type.MaterializedBlobType` that truncates logged messages. // Register a tweaked version of `org.hibernate.type.MaterializedBlobType` that truncates logged messages.
// to avoid OOM when large blobs might get logged. // to avoid OOM when large blobs might get logged.
applyBasicType(CordaMaterializedBlobType, CordaMaterializedBlobType.name) applyBasicType(CordaMaterializedBlobType, CordaMaterializedBlobType.name)

View File

@ -1,4 +1,4 @@
package net.corda.node.utilities package net.corda.nodeapi.internal.crypto
import net.corda.core.crypto.Crypto import net.corda.core.crypto.Crypto
import net.corda.core.crypto.Crypto.EDDSA_ED25519_SHA512 import net.corda.core.crypto.Crypto.EDDSA_ED25519_SHA512
@ -13,7 +13,6 @@ import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.node.serialization.KryoServerSerializationScheme import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.node.services.config.createKeystoreForCordaNode import net.corda.node.services.config.createKeystoreForCordaNode
import net.corda.nodeapi.internal.crypto.*
import net.corda.nodeapi.internal.serialization.AllWhitelist import net.corda.nodeapi.internal.serialization.AllWhitelist
import net.corda.nodeapi.internal.serialization.SerializationContextImpl import net.corda.nodeapi.internal.serialization.SerializationContextImpl
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl

View File

@ -3,6 +3,8 @@ package net.corda.node.internal
import com.codahale.metrics.MetricRegistry import com.codahale.metrics.MetricRegistry
import com.google.common.collect.MutableClassToInstanceMap import com.google.common.collect.MutableClassToInstanceMap
import com.google.common.util.concurrent.MoreExecutors import com.google.common.util.concurrent.MoreExecutors
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesFlow
import net.corda.confidential.SwapIdentitiesHandler import net.corda.confidential.SwapIdentitiesHandler
import net.corda.core.CordaException import net.corda.core.CordaException
@ -58,10 +60,12 @@ import net.corda.node.services.vault.NodeVaultService
import net.corda.node.services.vault.VaultSoftLockManager import net.corda.node.services.vault.VaultSoftLockManager
import net.corda.node.shell.InteractiveShell import net.corda.node.shell.InteractiveShell
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.configureDatabase
import net.corda.nodeapi.internal.crypto.* import net.corda.nodeapi.internal.crypto.*
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.activemq.artemis.utils.ReusableLatch
import org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry
import org.slf4j.Logger import org.slf4j.Logger
import rx.Observable import rx.Observable
import java.io.IOException import java.io.IOException
@ -181,7 +185,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
log.info("Node starting up ...") log.info("Node starting up ...")
initCertificate() initCertificate()
val (keyPairs, info) = initNodeInfo() val (keyPairs, info) = initNodeInfo()
val schemaService = NodeSchemaService(cordappLoader) val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
val identityService = makeIdentityService(info) val identityService = makeIdentityService(info)
// Do all of this in a database transaction so anything that might need a connection has one. // Do all of this in a database transaction so anything that might need a connection has one.
val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService, identityService) { database -> val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService, identityService) { database ->
@ -207,7 +211,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
MoreExecutors.shutdownAndAwaitTermination(serverThread as ExecutorService, 50, SECONDS) MoreExecutors.shutdownAndAwaitTermination(serverThread as ExecutorService, 50, SECONDS)
} }
} }
makeVaultObservers(schedulerService, database.hibernateConfig, smm) makeVaultObservers(schedulerService, database.hibernateConfig, smm, schemaService)
val rpcOps = makeRPCOps(flowStarter, database, smm) val rpcOps = makeRPCOps(flowStarter, database, smm)
startMessagingService(rpcOps) startMessagingService(rpcOps)
installCoreFlows() installCoreFlows()
@ -513,10 +517,11 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
} }
protected open fun makeTransactionStorage(database: CordaPersistence): WritableTransactionStorage = DBTransactionStorage() protected open fun makeTransactionStorage(database: CordaPersistence): WritableTransactionStorage = DBTransactionStorage()
private fun makeVaultObservers(schedulerService: SchedulerService, hibernateConfig: HibernateConfiguration, smm: StateMachineManager) {
private fun makeVaultObservers(schedulerService: SchedulerService, hibernateConfig: HibernateConfiguration, smm: StateMachineManager, schemaService: SchemaService) {
VaultSoftLockManager.install(services.vaultService, smm) VaultSoftLockManager.install(services.vaultService, smm)
ScheduledActivityObserver.install(services.vaultService, schedulerService) ScheduledActivityObserver.install(services.vaultService, schedulerService)
HibernateObserver.install(services.vaultService.rawUpdates, hibernateConfig) HibernateObserver.install(services.vaultService.rawUpdates, hibernateConfig, schemaService)
} }
@VisibleForTesting @VisibleForTesting
@ -753,7 +758,23 @@ internal class FlowStarterImpl(private val serverThread: AffinityExecutor, priva
} }
class ConfigurationException(message: String) : CordaException(message) class ConfigurationException(message: String) : CordaException(message)
/** /**
* Thrown when a node is about to start and its network map cache doesn't contain any node. * Thrown when a node is about to start and its network map cache doesn't contain any node.
*/ */
internal class NetworkMapCacheEmptyException : Exception() internal class NetworkMapCacheEmptyException : Exception()
fun configureDatabase(dataSourceProperties: Properties,
databaseConfig: DatabaseConfig,
identityService: IdentityService,
schemaService: SchemaService = NodeSchemaService()): CordaPersistence {
// Register the AbstractPartyDescriptor so Hibernate doesn't warn when encountering AbstractParty. Unfortunately
// Hibernate warns about not being able to find a descriptor if we don't provide one, but won't use it by default
// so we end up providing both descriptor and converter. We should re-examine this in later versions to see if
// either Hibernate can be convinced to stop warning, use the descriptor by default, or something else.
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(identityService))
val config = HikariConfig(dataSourceProperties)
val dataSource = HikariDataSource(config)
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(identityService))
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, attributeConverters)
}

View File

@ -26,7 +26,7 @@ import net.corda.node.services.api.FlowStarter
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.messaging.context import net.corda.node.services.messaging.context
import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import rx.Observable import rx.Observable
import java.io.InputStream import java.io.InputStream
import java.security.PublicKey import java.security.PublicKey

View File

@ -10,9 +10,9 @@ import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.TransactionVerifierService import net.corda.core.node.services.TransactionVerifierService
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.serialization.internal.SerializationEnvironmentImpl import net.corda.core.serialization.internal.SerializationEnvironmentImpl
import net.corda.core.serialization.internal.nodeSerializationEnv import net.corda.core.serialization.internal.nodeSerializationEnv
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.node.VersionInfo import net.corda.node.VersionInfo
import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappLoader
@ -25,10 +25,10 @@ import net.corda.node.services.messaging.*
import net.corda.node.services.transactions.InMemoryTransactionVerifierService import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.utilities.AddressUtils import net.corda.node.utilities.AddressUtils
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.DemoClock import net.corda.node.utilities.DemoClock
import net.corda.nodeapi.internal.ShutdownHook import net.corda.nodeapi.internal.ShutdownHook
import net.corda.nodeapi.internal.addShutdownHook import net.corda.nodeapi.internal.addShutdownHook
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.serialization.* import net.corda.nodeapi.internal.serialization.*
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
import org.slf4j.Logger import org.slf4j.Logger

View File

@ -5,7 +5,7 @@ import net.corda.node.services.api.FlowStarter
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.messaging.rpcContext import net.corda.node.services.messaging.rpcContext
import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
/** /**
* Implementation of [CordaRPCOps] that checks authorisation. * Implementation of [CordaRPCOps] that checks authorisation.

View File

@ -14,7 +14,7 @@ import net.corda.node.services.api.StartedNodeServices
import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import rx.Observable import rx.Observable
interface StartedNode<out N : AbstractNode> { interface StartedNode<out N : AbstractNode> {

View File

@ -52,12 +52,14 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
} }
} }
val cordappSchemas: Set<MappedSchema> get() = cordapps.flatMap { it.customSchemas }.toSet()
companion object { companion object {
private val logger = contextLogger() private val logger = contextLogger()
/** /**
* Default cordapp dir name * Default cordapp dir name
*/ */
val CORDAPPS_DIR_NAME = "cordapps" private const val CORDAPPS_DIR_NAME = "cordapps"
/** /**
* Creates a default CordappLoader intended to be used in non-dev or non-test environments. * Creates a default CordappLoader intended to be used in non-dev or non-test environments.
@ -94,8 +96,9 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
* CorDapps. * CorDapps.
*/ */
@VisibleForTesting @VisibleForTesting
fun createWithTestPackages(testPackages: List<String>) fun createWithTestPackages(testPackages: List<String>): CordappLoader {
= cordappLoadersCache.computeIfAbsent(testPackages, { CordappLoader(testPackages.flatMap(this::createScanPackage)) }) return cordappLoadersCache.computeIfAbsent(testPackages, { CordappLoader(testPackages.flatMap(this::createScanPackage)) })
}
/** /**
* Creates a dev mode CordappLoader intended only to be used in test environments * Creates a dev mode CordappLoader intended only to be used in test environments

View File

@ -1,11 +1,11 @@
package net.corda.node.services.api package net.corda.node.services.api
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.InvocationContext
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.FlowStateMachine
import net.corda.core.context.InvocationContext
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.messaging.StateMachineTransactionMapping import net.corda.core.messaging.StateMachineTransactionMapping
@ -23,7 +23,7 @@ import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
import net.corda.node.services.statemachine.FlowStateMachineImpl import net.corda.node.services.statemachine.FlowStateMachineImpl
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
interface NetworkMapCacheInternal : NetworkMapCache, NetworkMapCacheBaseInternal interface NetworkMapCacheInternal : NetworkMapCache, NetworkMapCacheBaseInternal
interface NetworkMapCacheBaseInternal : NetworkMapCacheBase { interface NetworkMapCacheBaseInternal : NetworkMapCacheBase {

View File

@ -5,6 +5,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.services.messaging.CertificateChainCheckPolicy import net.corda.node.services.messaging.CertificateChainCheckPolicy
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.nodeapi.config.NodeSSLConfiguration import net.corda.nodeapi.config.NodeSSLConfiguration
import net.corda.nodeapi.config.parseAs import net.corda.nodeapi.config.parseAs
@ -43,25 +44,6 @@ interface NodeConfiguration : NodeSSLConfiguration {
data class DevModeOptions(val disableCheckpointChecker: Boolean = false) data class DevModeOptions(val disableCheckpointChecker: Boolean = false)
data class DatabaseConfig(
val initialiseSchema: Boolean = true,
val serverNameTablePrefix: String = "",
val transactionIsolationLevel: TransactionIsolationLevel = TransactionIsolationLevel.REPEATABLE_READ
)
enum class TransactionIsolationLevel {
NONE,
READ_UNCOMMITTED,
READ_COMMITTED,
REPEATABLE_READ,
SERIALIZABLE;
/**
* The JDBC constant value of the same name but with prefixed with TRANSACTION_ defined in [java.sql.Connection].
*/
val jdbcValue: Int = java.sql.Connection::class.java.getField("TRANSACTION_$name").get(null) as Int
}
fun NodeConfiguration.shouldCheckCheckpoints(): Boolean { fun NodeConfiguration.shouldCheckCheckpoints(): Boolean {
return this.devMode && this.devModeOptions?.disableCheckpointChecker != true return this.devMode && this.devModeOptions?.disableCheckpointChecker != true
} }

View File

@ -3,6 +3,7 @@ package net.corda.node.services.events
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
import net.corda.core.context.InvocationContext import net.corda.core.context.InvocationContext
import net.corda.core.context.Origin
import net.corda.core.contracts.SchedulableState import net.corda.core.contracts.SchedulableState
import net.corda.core.contracts.ScheduledActivity import net.corda.core.contracts.ScheduledActivity
import net.corda.core.contracts.ScheduledStateRef import net.corda.core.contracts.ScheduledStateRef
@ -12,7 +13,6 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.concurrent.flatMap import net.corda.core.internal.concurrent.flatMap
import net.corda.core.context.Origin
import net.corda.core.internal.until import net.corda.core.internal.until
import net.corda.core.node.StateLoader import net.corda.core.node.StateLoader
import net.corda.core.schemas.PersistentStateRef import net.corda.core.schemas.PersistentStateRef
@ -24,9 +24,9 @@ import net.corda.node.services.api.FlowStarter
import net.corda.node.services.api.SchedulerService import net.corda.node.services.api.SchedulerService
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.NODE_DATABASE_PREFIX
import net.corda.node.utilities.PersistentMap import net.corda.node.utilities.PersistentMap
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.activemq.artemis.utils.ReusableLatch
import java.time.Clock import java.time.Clock
import java.time.Instant import java.time.Instant

View File

@ -13,7 +13,7 @@ import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import net.corda.nodeapi.internal.crypto.X509CertificateFactory import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.cert.X509CertificateHolder
import java.security.InvalidAlgorithmParameterException import java.security.InvalidAlgorithmParameterException

View File

@ -7,7 +7,7 @@ import net.corda.core.node.services.KeyManagementService
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.MAX_HASH_HEX_SIZE import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import org.bouncycastle.operator.ContentSigner import org.bouncycastle.operator.ContentSigner
import java.security.KeyPair import java.security.KeyPair
import java.security.PrivateKey import java.security.PrivateKey

View File

@ -17,10 +17,13 @@ import net.corda.core.utilities.trace
import net.corda.node.VersionInfo import net.corda.node.VersionInfo
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.statemachine.StateMachineManagerImpl import net.corda.node.services.statemachine.StateMachineManagerImpl
import net.corda.node.utilities.* import net.corda.node.utilities.AffinityExecutor
import net.corda.nodeapi.internal.ArtemisMessagingComponent import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.PersistentMap
import net.corda.nodeapi.internal.ArtemisMessagingComponent.* import net.corda.nodeapi.internal.ArtemisMessagingComponent.*
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.P2P_QUEUE import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.P2P_QUEUE
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import org.apache.activemq.artemis.api.core.ActiveMQObjectClosedException import org.apache.activemq.artemis.api.core.ActiveMQObjectClosedException
import org.apache.activemq.artemis.api.core.Message.* import org.apache.activemq.artemis.api.core.Message.*
import org.apache.activemq.artemis.api.core.RoutingType import org.apache.activemq.artemis.api.core.RoutingType

View File

@ -22,9 +22,9 @@ import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.node.services.api.NetworkMapCacheBaseInternal import net.corda.node.services.api.NetworkMapCacheBaseInternal
import net.corda.node.services.api.NetworkMapCacheInternal import net.corda.node.services.api.NetworkMapCacheInternal
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.node.utilities.bufferUntilDatabaseCommit import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
import net.corda.node.utilities.wrapWithDatabaseTransaction import net.corda.nodeapi.internal.persistence.wrapWithDatabaseTransaction
import org.hibernate.Session import org.hibernate.Session
import rx.Observable import rx.Observable
import rx.subjects.PublishSubject import rx.subjects.PublishSubject

View File

@ -3,8 +3,8 @@ package net.corda.node.services.persistence
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.node.services.api.Checkpoint import net.corda.node.services.api.Checkpoint
import net.corda.node.services.api.CheckpointStorage import net.corda.node.services.api.CheckpointStorage
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import net.corda.node.utilities.currentDBSession import net.corda.nodeapi.internal.persistence.currentDBSession
import javax.persistence.Column import javax.persistence.Column
import javax.persistence.Entity import javax.persistence.Entity
import javax.persistence.Id import javax.persistence.Id

View File

@ -7,6 +7,9 @@ import net.corda.core.messaging.DataFeed
import net.corda.core.messaging.StateMachineTransactionMapping import net.corda.core.messaging.StateMachineTransactionMapping
import net.corda.node.services.api.StateMachineRecordedTransactionMappingStorage import net.corda.node.services.api.StateMachineRecordedTransactionMappingStorage
import net.corda.node.utilities.* import net.corda.node.utilities.*
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
import net.corda.nodeapi.internal.persistence.wrapWithDatabaseTransaction
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import java.util.* import java.util.*
import javax.annotation.concurrent.ThreadSafe import javax.annotation.concurrent.ThreadSafe

View File

@ -8,6 +8,9 @@ import net.corda.core.serialization.*
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.node.services.api.WritableTransactionStorage import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.utilities.* import net.corda.node.utilities.*
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
import net.corda.nodeapi.internal.persistence.wrapWithDatabaseTransaction
import rx.Observable import rx.Observable
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import javax.persistence.* import javax.persistence.*

View File

@ -17,9 +17,9 @@ import net.corda.core.node.services.vault.AttachmentSort
import net.corda.core.serialization.* import net.corda.core.serialization.*
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.node.services.vault.HibernateAttachmentQueryCriteriaParser import net.corda.node.services.vault.HibernateAttachmentQueryCriteriaParser
import net.corda.node.utilities.DatabaseTransactionManager import net.corda.nodeapi.internal.persistence.DatabaseTransactionManager
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import net.corda.node.utilities.currentDBSession import net.corda.nodeapi.internal.persistence.currentDBSession
import java.io.* import java.io.*
import java.nio.file.Paths import java.nio.file.Paths
import java.time.Instant import java.time.Instant

View File

@ -9,8 +9,9 @@ import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentStateRef import net.corda.core.schemas.PersistentStateRef
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
import net.corda.node.services.persistence.HibernateConfiguration import net.corda.node.services.api.SchemaService
import net.corda.node.utilities.DatabaseTransactionManager import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.nodeapi.internal.persistence.DatabaseTransactionManager
import org.hibernate.FlushMode import org.hibernate.FlushMode
import rx.Observable import rx.Observable
@ -18,12 +19,11 @@ import rx.Observable
* A vault observer that extracts Object Relational Mappings for contract states that support it, and persists them with Hibernate. * A vault observer that extracts Object Relational Mappings for contract states that support it, and persists them with Hibernate.
*/ */
// TODO: Manage version evolution of the schemas via additional tooling. // TODO: Manage version evolution of the schemas via additional tooling.
class HibernateObserver private constructor(private val config: HibernateConfiguration) { class HibernateObserver private constructor(private val config: HibernateConfiguration, private val schemaService: SchemaService) {
companion object { companion object {
private val log = contextLogger() private val log = contextLogger()
@JvmStatic fun install(vaultUpdates: Observable<Vault.Update<ContractState>>, config: HibernateConfiguration, schemaService: SchemaService): HibernateObserver {
fun install(vaultUpdates: Observable<Vault.Update<ContractState>>, config: HibernateConfiguration): HibernateObserver { val observer = HibernateObserver(config, schemaService)
val observer = HibernateObserver(config)
vaultUpdates.subscribe { observer.persist(it.produced) } vaultUpdates.subscribe { observer.persist(it.produced) }
return observer return observer
} }
@ -36,7 +36,7 @@ class HibernateObserver private constructor(private val config: HibernateConfigu
private fun persistState(stateAndRef: StateAndRef<ContractState>) { private fun persistState(stateAndRef: StateAndRef<ContractState>) {
val state = stateAndRef.state.data val state = stateAndRef.state.data
log.debug { "Asked to persist state ${stateAndRef.ref}" } log.debug { "Asked to persist state ${stateAndRef.ref}" }
config.schemaService.selectSchemas(state).forEach { persistStateWithSchema(state, stateAndRef.ref, it) } schemaService.selectSchemas(state).forEach { persistStateWithSchema(state, stateAndRef.ref, it) }
} }
@VisibleForTesting @VisibleForTesting
@ -47,7 +47,7 @@ class HibernateObserver private constructor(private val config: HibernateConfigu
flushMode(FlushMode.MANUAL). flushMode(FlushMode.MANUAL).
openSession() openSession()
session.use { session.use {
val mappedObject = config.schemaService.generateMappedObject(state, schema) val mappedObject = schemaService.generateMappedObject(state, schema)
mappedObject.stateRef = PersistentStateRef(stateRef) mappedObject.stateRef = PersistentStateRef(stateRef)
it.persist(mappedObject) it.persist(mappedObject)
it.flush() it.flush()

View File

@ -9,8 +9,8 @@ import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState import net.corda.core.schemas.QueryableState
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.services.api.SchemaService import net.corda.node.services.api.SchemaService
import net.corda.node.services.api.SchemaService.SchemaOptions
import net.corda.node.services.events.NodeSchedulerService import net.corda.node.services.events.NodeSchedulerService
import net.corda.node.services.identity.PersistentIdentityService import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.services.keys.PersistentKeyManagementService import net.corda.node.services.keys.PersistentKeyManagementService
@ -27,14 +27,12 @@ import net.corda.node.services.vault.VaultSchemaV1
/** /**
* Most basic implementation of [SchemaService]. * Most basic implementation of [SchemaService].
* @param cordappLoader if not null, custom schemas will be extracted from its cordapps.
* TODO: support loading schema options from node configuration. * TODO: support loading schema options from node configuration.
* TODO: support configuring what schemas are to be selected for persistence. * TODO: support configuring what schemas are to be selected for persistence.
* TODO: support plugins for schema version upgrading or custom mapping not supported by original [QueryableState]. * TODO: support plugins for schema version upgrading or custom mapping not supported by original [QueryableState].
* TODO: create whitelisted tables when a CorDapp is first installed * TODO: create whitelisted tables when a CorDapp is first installed
*/ */
class NodeSchemaService(cordappLoader: CordappLoader?) : SchemaService, SingletonSerializeAsToken() { class NodeSchemaService(extraSchemas: Set<MappedSchema> = emptySet()) : SchemaService, SingletonSerializeAsToken() {
// Entities for compulsory services // Entities for compulsory services
object NodeServices object NodeServices
@ -60,17 +58,12 @@ class NodeSchemaService(cordappLoader: CordappLoader?) : SchemaService, Singleto
// Required schemas are those used by internal Corda services // Required schemas are those used by internal Corda services
// For example, cash is used by the vault for coin selection (but will be extracted as a standalone CorDapp in future) // For example, cash is used by the vault for coin selection (but will be extracted as a standalone CorDapp in future)
private val requiredSchemas: Map<MappedSchema, SchemaService.SchemaOptions> = private val requiredSchemas: Map<MappedSchema, SchemaService.SchemaOptions> =
mapOf(Pair(CommonSchemaV1, SchemaService.SchemaOptions()), mapOf(Pair(CommonSchemaV1, SchemaOptions()),
Pair(VaultSchemaV1, SchemaService.SchemaOptions()), Pair(VaultSchemaV1, SchemaOptions()),
Pair(NodeInfoSchemaV1, SchemaService.SchemaOptions()), Pair(NodeInfoSchemaV1, SchemaOptions()),
Pair(NodeServicesV1, SchemaService.SchemaOptions())) Pair(NodeServicesV1, SchemaOptions()))
override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = if (cordappLoader == null) { override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = requiredSchemas + extraSchemas.associateBy({ it }, { SchemaOptions() })
requiredSchemas
} else {
val customSchemas = cordappLoader.cordapps.flatMap { it.customSchemas }.toSet()
requiredSchemas.plus(customSchemas.map { mappedSchema -> Pair(mappedSchema, SchemaService.SchemaOptions()) })
}
// Currently returns all schemas supported by the state, with no filtering or enrichment. // Currently returns all schemas supported by the state, with no filtering or enrichment.
override fun selectSchemas(state: ContractState): Iterable<MappedSchema> { override fun selectSchemas(state: ContractState): Iterable<MappedSchema> {

View File

@ -7,6 +7,7 @@ import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.strands.Strand import co.paralleluniverse.strands.Strand
import com.google.common.primitives.Primitives import com.google.common.primitives.Primitives
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.InvocationContext
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.random63BitValue import net.corda.core.crypto.random63BitValue
import net.corda.core.flows.* import net.corda.core.flows.*
@ -15,7 +16,6 @@ import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.internal.concurrent.OpenFuture import net.corda.core.internal.concurrent.OpenFuture
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.context.InvocationContext
import net.corda.core.serialization.SerializationDefaults import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
@ -25,9 +25,9 @@ import net.corda.node.services.api.FlowPermissionAuditEvent
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.logging.pushToLoggingContext import net.corda.node.services.logging.pushToLoggingContext
import net.corda.node.services.statemachine.FlowSessionState.Initiating import net.corda.node.services.statemachine.FlowSessionState.Initiating
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.node.utilities.DatabaseTransaction import net.corda.nodeapi.internal.persistence.DatabaseTransaction
import net.corda.node.utilities.DatabaseTransactionManager import net.corda.nodeapi.internal.persistence.DatabaseTransactionManager
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.nio.file.Paths import java.nio.file.Paths

View File

@ -27,7 +27,10 @@ import net.corda.core.serialization.SerializationDefaults.SERIALIZATION_FACTORY
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.* import net.corda.core.utilities.Try
import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.debug
import net.corda.core.utilities.trace
import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.services.api.Checkpoint import net.corda.node.services.api.Checkpoint
import net.corda.node.services.api.CheckpointStorage import net.corda.node.services.api.CheckpointStorage
@ -35,7 +38,11 @@ import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.config.shouldCheckCheckpoints import net.corda.node.services.config.shouldCheckCheckpoints
import net.corda.node.services.messaging.ReceivedMessage import net.corda.node.services.messaging.ReceivedMessage
import net.corda.node.services.messaging.TopicSession import net.corda.node.services.messaging.TopicSession
import net.corda.node.utilities.* import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.newNamedSingleThreadExecutor
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
import net.corda.nodeapi.internal.persistence.wrapWithDatabaseTransaction
import net.corda.nodeapi.internal.serialization.SerializeAsTokenContextImpl import net.corda.nodeapi.internal.serialization.SerializeAsTokenContextImpl
import net.corda.nodeapi.internal.serialization.withTokenContext import net.corda.nodeapi.internal.serialization.withTokenContext
import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.activemq.artemis.utils.ReusableLatch

View File

@ -23,7 +23,7 @@ import net.corda.core.utilities.*
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.config.BFTSMaRtConfiguration import net.corda.node.services.config.BFTSMaRtConfiguration
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import java.security.PublicKey import java.security.PublicKey
import javax.persistence.Entity import javax.persistence.Entity
import javax.persistence.Table import javax.persistence.Table

View File

@ -5,8 +5,9 @@ import io.atomix.copycat.Query
import io.atomix.copycat.server.Commit import io.atomix.copycat.server.Commit
import io.atomix.copycat.server.StateMachine import io.atomix.copycat.server.StateMachine
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.node.utilities.* import net.corda.node.utilities.AppendOnlyPersistentMap
import java.util.LinkedHashMap import net.corda.nodeapi.internal.persistence.CordaPersistence
import java.util.*
/** /**
* A distributed map state machine that doesn't allow overriding values. The state machine is replicated * A distributed map state machine that doesn't allow overriding values. The state machine is replicated

View File

@ -12,7 +12,7 @@ import net.corda.core.schemas.PersistentStateRef
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import java.io.Serializable import java.io.Serializable
import java.util.* import java.util.*
import javax.annotation.concurrent.ThreadSafe import javax.annotation.concurrent.ThreadSafe

View File

@ -29,10 +29,10 @@ import net.corda.core.serialization.serialize
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.node.services.config.RaftConfig import net.corda.node.services.config.RaftConfig
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.NODE_DATABASE_PREFIX
import net.corda.nodeapi.config.NodeSSLConfiguration import net.corda.nodeapi.config.NodeSSLConfiguration
import net.corda.nodeapi.config.SSLConfiguration import net.corda.nodeapi.config.SSLConfiguration
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import java.nio.file.Path import java.nio.file.Path
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import javax.annotation.concurrent.ThreadSafe import javax.annotation.concurrent.ThreadSafe

View File

@ -4,7 +4,7 @@ import net.corda.core.contracts.StateRef
import net.corda.core.contracts.UpgradedContract import net.corda.core.contracts.UpgradedContract
import net.corda.core.node.services.ContractUpgradeService import net.corda.core.node.services.ContractUpgradeService
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import net.corda.node.utilities.PersistentMap import net.corda.node.utilities.PersistentMap
import javax.persistence.Column import javax.persistence.Column
import javax.persistence.Entity import javax.persistence.Entity

View File

@ -17,12 +17,12 @@ import net.corda.core.transactions.NotaryChangeWireTransaction
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.core.utilities.* import net.corda.core.utilities.*
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.persistence.HibernateConfiguration import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.node.services.statemachine.FlowStateMachineImpl import net.corda.node.services.statemachine.FlowStateMachineImpl
import net.corda.node.utilities.DatabaseTransactionManager import net.corda.nodeapi.internal.persistence.DatabaseTransactionManager
import net.corda.node.utilities.bufferUntilDatabaseCommit import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
import net.corda.node.utilities.currentDBSession import net.corda.nodeapi.internal.persistence.currentDBSession
import net.corda.node.utilities.wrapWithDatabaseTransaction import net.corda.nodeapi.internal.persistence.wrapWithDatabaseTransaction
import org.hibernate.Session import org.hibernate.Session
import rx.Observable import rx.Observable
import rx.subjects.PublishSubject import rx.subjects.PublishSubject

View File

@ -22,9 +22,7 @@ import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.messaging.FlowProgressHandle import net.corda.core.messaging.FlowProgressHandle
import net.corda.core.messaging.StateMachineUpdate import net.corda.core.messaging.StateMachineUpdate
import net.corda.core.utilities.getOrThrow
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.loggerFor
import net.corda.node.internal.Node import net.corda.node.internal.Node
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.RPCUserService import net.corda.node.services.RPCUserService
@ -33,8 +31,8 @@ import net.corda.node.services.messaging.CURRENT_RPC_CONTEXT
import net.corda.node.services.messaging.RpcAuthContext import net.corda.node.services.messaging.RpcAuthContext
import net.corda.node.services.messaging.RpcPermissions import net.corda.node.services.messaging.RpcPermissions
import net.corda.node.utilities.ANSIProgressRenderer import net.corda.node.utilities.ANSIProgressRenderer
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.StdoutANSIProgressRenderer import net.corda.node.utilities.StdoutANSIProgressRenderer
import net.corda.nodeapi.internal.persistence.CordaPersistence
import org.crsh.command.InvocationContext import org.crsh.command.InvocationContext
import org.crsh.console.jline.JLineProcessor import org.crsh.console.jline.JLineProcessor
import org.crsh.console.jline.TerminalFactory import org.crsh.console.jline.TerminalFactory
@ -94,7 +92,7 @@ object InteractiveShell {
* Starts an interactive shell connected to the local terminal. This shell gives administrator access to the node * Starts an interactive shell connected to the local terminal. This shell gives administrator access to the node
* internals. * internals.
*/ */
fun startShell(configuration:NodeConfiguration, cordaRPCOps: CordaRPCOps, userService: RPCUserService, identityService: IdentityService, database:CordaPersistence) { fun startShell(configuration:NodeConfiguration, cordaRPCOps: CordaRPCOps, userService: RPCUserService, identityService: IdentityService, database: CordaPersistence) {
this.rpcOps = cordaRPCOps this.rpcOps = cordaRPCOps
this.userService = userService this.userService = userService
this.identityService = identityService this.identityService = identityService

View File

@ -1,6 +1,7 @@
package net.corda.node.utilities package net.corda.node.utilities
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.nodeapi.internal.persistence.currentDBSession
import java.util.* import java.util.*

View File

@ -1,13 +1,12 @@
package net.corda.node.utilities package net.corda.node.utilities
import com.google.common.cache.RemovalCause import com.google.common.cache.RemovalCause
import com.google.common.cache.RemovalListener import com.google.common.cache.RemovalListener
import com.google.common.cache.RemovalNotification import com.google.common.cache.RemovalNotification
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.nodeapi.internal.persistence.currentDBSession
import java.util.* import java.util.*
/** /**
* Implements an unbound caching layer on top of a table accessed via Hibernate mapping. * Implements an unbound caching layer on top of a table accessed via Hibernate mapping.
*/ */

View File

@ -20,8 +20,8 @@ import net.corda.finance.contracts.DealState;
import net.corda.finance.contracts.asset.Cash; import net.corda.finance.contracts.asset.Cash;
import net.corda.finance.schemas.CashSchemaV1; import net.corda.finance.schemas.CashSchemaV1;
import net.corda.node.services.identity.InMemoryIdentityService; import net.corda.node.services.identity.InMemoryIdentityService;
import net.corda.node.utilities.CordaPersistence; import net.corda.nodeapi.internal.persistence.CordaPersistence;
import net.corda.node.utilities.DatabaseTransaction; import net.corda.nodeapi.internal.persistence.DatabaseTransaction;
import net.corda.testing.SerializationEnvironmentRule; import net.corda.testing.SerializationEnvironmentRule;
import net.corda.testing.contracts.DummyLinearContract; import net.corda.testing.contracts.DummyLinearContract;
import net.corda.testing.contracts.VaultFiller; import net.corda.testing.contracts.VaultFiller;

View File

@ -10,10 +10,10 @@ import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.messaging.FlowProgressHandleImpl import net.corda.core.messaging.FlowProgressHandleImpl
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.node.services.config.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.shell.InteractiveShell import net.corda.node.shell.InteractiveShell
import net.corda.node.utilities.configureDatabase import net.corda.node.internal.configureDatabase
import net.corda.testing.DEV_TRUST_ROOT import net.corda.testing.DEV_TRUST_ROOT
import net.corda.testing.MEGA_CORP import net.corda.testing.MEGA_CORP
import net.corda.testing.MEGA_CORP_IDENTITY import net.corda.testing.MEGA_CORP_IDENTITY

View File

@ -36,7 +36,7 @@ import net.corda.node.internal.StartedNode
import net.corda.node.services.api.WritableTransactionStorage import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.persistence.DBTransactionStorage import net.corda.node.services.persistence.DBTransactionStorage
import net.corda.node.services.persistence.checkpoints import net.corda.node.services.persistence.checkpoints
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.contracts.VaultFiller import net.corda.testing.contracts.VaultFiller
import net.corda.testing.node.* import net.corda.testing.node.*

View File

@ -1,6 +1,7 @@
package net.corda.node.services.config package net.corda.node.services.config
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.ALICE import net.corda.testing.ALICE
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy

View File

@ -23,7 +23,6 @@ import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.internal.cordapp.CordappProviderImpl import net.corda.node.internal.cordapp.CordappProviderImpl
import net.corda.node.services.api.MonitoringService import net.corda.node.services.api.MonitoringService
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.network.NetworkMapCacheImpl import net.corda.node.services.network.NetworkMapCacheImpl
import net.corda.node.services.persistence.DBCheckpointStorage import net.corda.node.services.persistence.DBCheckpointStorage
@ -32,8 +31,9 @@ import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.services.statemachine.StateMachineManagerImpl import net.corda.node.services.statemachine.StateMachineManagerImpl
import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.NodeVaultService
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.node.* import net.corda.testing.node.*

View File

@ -10,11 +10,11 @@ import net.corda.core.internal.cert
import net.corda.core.internal.toX509CertHolder import net.corda.core.internal.toX509CertHolder
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.UnknownAnonymousPartyException import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.node.utilities.CordaPersistence
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509CertificateFactory import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.junit.After import org.junit.After

View File

@ -4,15 +4,15 @@ import net.corda.core.crypto.generateKeyPair
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.services.RPCUserService import net.corda.node.services.RPCUserService
import net.corda.node.services.RPCUserServiceImpl import net.corda.node.services.RPCUserServiceImpl
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.configureWithDevSSLCertificate import net.corda.node.services.config.configureWithDevSSLCertificate
import net.corda.node.services.network.NetworkMapCacheImpl import net.corda.node.services.network.NetworkMapCacheImpl
import net.corda.node.services.network.PersistentNetworkMapCache import net.corda.node.services.network.PersistentNetworkMapCache
import net.corda.node.services.transactions.PersistentUniquenessProvider import net.corda.node.services.transactions.PersistentUniquenessProvider
import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor
import net.corda.node.utilities.CordaPersistence import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties

View File

@ -4,10 +4,10 @@ import com.google.common.primitives.Ints
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.node.services.api.Checkpoint import net.corda.node.services.api.Checkpoint
import net.corda.node.services.api.CheckpointStorage import net.corda.node.services.api.CheckpointStorage
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.transactions.PersistentUniquenessProvider import net.corda.node.services.transactions.PersistentUniquenessProvider
import net.corda.node.utilities.CordaPersistence import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.LogHelper import net.corda.testing.LogHelper
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.SerializationEnvironmentRule
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties

View File

@ -10,12 +10,13 @@ import net.corda.core.toFuture
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.schema.HibernateObserver import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.transactions.PersistentUniquenessProvider import net.corda.node.services.transactions.PersistentUniquenessProvider
import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.NodeVaultService
import net.corda.node.utilities.CordaPersistence import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
@ -40,13 +41,14 @@ class DBTransactionStorageTests {
fun setUp() { fun setUp() {
LogHelper.setLevel(PersistentUniquenessProvider::class) LogHelper.setLevel(PersistentUniquenessProvider::class)
val dataSourceProps = makeTestDataSourceProperties() val dataSourceProps = makeTestDataSourceProperties()
database = configureDatabase(dataSourceProps, DatabaseConfig(), rigorousMock()) val schemaService = NodeSchemaService()
database = configureDatabase(dataSourceProps, DatabaseConfig(), rigorousMock(), schemaService)
database.transaction { database.transaction {
services = object : MockServices(BOB_KEY) { services = object : MockServices(BOB_KEY) {
override val vaultService: VaultServiceInternal override val vaultService: VaultServiceInternal
get() { get() {
val vaultService = NodeVaultService(clock, keyManagementService, stateLoader, database.hibernateConfig) val vaultService = NodeVaultService(clock, keyManagementService, stateLoader, database.hibernateConfig)
hibernatePersister = HibernateObserver.install(vaultService.rawUpdates, database.hibernateConfig) hibernatePersister = HibernateObserver.install(vaultService.rawUpdates, database.hibernateConfig, schemaService)
return vaultService return vaultService
} }

View File

@ -23,16 +23,21 @@ import net.corda.core.utilities.toBase58String
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.POUNDS import net.corda.finance.POUNDS
import net.corda.finance.SWISS_FRANCS import net.corda.finance.SWISS_FRANCS
import net.corda.finance.contracts.asset.* import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_KEY
import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_NAME
import net.corda.finance.contracts.asset.DummyFungibleContract
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV2 import net.corda.finance.schemas.SampleCashSchemaV2
import net.corda.finance.schemas.SampleCashSchemaV3 import net.corda.finance.schemas.SampleCashSchemaV3
import net.corda.finance.utils.sumCash import net.corda.finance.utils.sumCash
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.schema.HibernateObserver import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.vault.VaultSchemaV1 import net.corda.node.services.vault.VaultSchemaV1
import net.corda.node.utilities.CordaPersistence import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.contracts.* import net.corda.testing.contracts.*
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
@ -92,12 +97,13 @@ class HibernateConfigurationTest {
doReturn(it).whenever(mock).wellKnownPartyFromX500Name(it.name) doReturn(it).whenever(mock).wellKnownPartyFromX500Name(it.name)
} }
} }
database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService) val schemaService = NodeSchemaService()
database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, schemaService)
database.transaction { database.transaction {
hibernateConfig = database.hibernateConfig hibernateConfig = database.hibernateConfig
// `consumeCash` expects we can self-notarise transactions // `consumeCash` expects we can self-notarise transactions
services = object : MockServices(cordappPackages, BOB_NAME, generateKeyPair(), DUMMY_NOTARY_KEY) { services = object : MockServices(cordappPackages, BOB_NAME, generateKeyPair(), DUMMY_NOTARY_KEY) {
override val vaultService = makeVaultService(database.hibernateConfig) override val vaultService = makeVaultService(database.hibernateConfig, schemaService)
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) { override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
for (stx in txs) { for (stx in txs) {
validatedTransactions.addTransaction(stx) validatedTransactions.addTransaction(stx)

View File

@ -13,10 +13,10 @@ import net.corda.core.node.services.vault.AttachmentQueryCriteria
import net.corda.core.node.services.vault.AttachmentSort import net.corda.core.node.services.vault.AttachmentSort
import net.corda.core.node.services.vault.Builder import net.corda.core.node.services.vault.Builder
import net.corda.core.node.services.vault.Sort import net.corda.core.node.services.vault.Sort
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.transactions.PersistentUniquenessProvider import net.corda.node.services.transactions.PersistentUniquenessProvider
import net.corda.node.utilities.CordaPersistence import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.LogHelper import net.corda.testing.LogHelper
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.rigorousMock import net.corda.testing.rigorousMock

View File

@ -11,9 +11,9 @@ import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState import net.corda.core.schemas.QueryableState
import net.corda.node.services.api.SchemaService import net.corda.node.services.api.SchemaService
import net.corda.node.services.config.DatabaseConfig import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.DatabaseTransactionManager import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.DatabaseTransactionManager
import net.corda.testing.LogHelper import net.corda.testing.LogHelper
import net.corda.testing.MEGA_CORP import net.corda.testing.MEGA_CORP
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
@ -66,7 +66,7 @@ class HibernateObserverTests {
} }
} }
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock(), schemaService) val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock(), schemaService)
HibernateObserver.install(rawUpdatesPublisher, database.hibernateConfig) HibernateObserver.install(rawUpdatesPublisher, database.hibernateConfig, schemaService)
database.transaction { database.transaction {
rawUpdatesPublisher.onNext(Vault.Update(emptySet(), setOf(StateAndRef(TransactionState(TestState(), DummyContract.PROGRAM_ID, MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0))))) rawUpdatesPublisher.onNext(Vault.Update(emptySet(), setOf(StateAndRef(TransactionState(TestState(), DummyContract.PROGRAM_ID, MEGA_CORP), StateRef(SecureHash.sha256("dummy"), 0)))))
val parentRowCountResult = DatabaseTransactionManager.current().connection.prepareStatement("select count(*) from Parents").executeQuery() val parentRowCountResult = DatabaseTransactionManager.current().connection.prepareStatement("select count(*) from Parents").executeQuery()

View File

@ -10,9 +10,9 @@ import net.corda.core.internal.concurrent.asCordaFuture
import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.concurrent.transpose
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.services.config.DatabaseConfig import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.LogHelper import net.corda.testing.LogHelper
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.SerializationEnvironmentRule
import net.corda.testing.freeLocalHostAndPort import net.corda.testing.freeLocalHostAndPort

View File

@ -2,9 +2,9 @@ package net.corda.node.services.transactions
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.node.services.UniquenessException import net.corda.core.node.services.UniquenessException
import net.corda.node.services.config.DatabaseConfig import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import org.junit.After import org.junit.After

View File

@ -34,7 +34,7 @@ import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_NAME
import net.corda.finance.contracts.getCashBalance import net.corda.finance.contracts.getCashBalance
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.utils.sumCash import net.corda.finance.utils.sumCash
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.contracts.VaultFiller import net.corda.testing.contracts.VaultFiller
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices

View File

@ -28,9 +28,9 @@ import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.CashSchemaV1.PersistentCashState import net.corda.finance.schemas.CashSchemaV1.PersistentCashState
import net.corda.finance.schemas.CommercialPaperSchemaV1 import net.corda.finance.schemas.CommercialPaperSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV3 import net.corda.finance.schemas.SampleCashSchemaV3
import net.corda.node.services.config.DatabaseConfig import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.contracts.* import net.corda.testing.contracts.*
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices

View File

@ -25,7 +25,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.persistence.HibernateConfiguration import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.rigorousMock import net.corda.testing.rigorousMock

View File

@ -24,7 +24,7 @@ import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_KEY
import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_NAME import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_NAME
import net.corda.finance.contracts.getCashBalance import net.corda.finance.contracts.getCashBalance
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.contracts.* import net.corda.testing.contracts.*
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices

View File

@ -3,7 +3,8 @@ package net.corda.node.utilities
import com.google.common.util.concurrent.SettableFuture import com.google.common.util.concurrent.SettableFuture
import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.internal.tee import net.corda.core.internal.tee
import net.corda.node.services.config.DatabaseConfig import net.corda.node.internal.configureDatabase
import net.corda.nodeapi.internal.persistence.*
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.rigorousMock import net.corda.testing.rigorousMock
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat

View File

@ -15,9 +15,9 @@ import net.corda.finance.contracts.FixOf
import net.corda.finance.contracts.asset.CASH import net.corda.finance.contracts.asset.CASH
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.irs.flows.RatesFixFlow import net.corda.irs.flows.RatesFixFlow
import net.corda.node.services.config.DatabaseConfig import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.MockNodeParameters

View File

@ -18,7 +18,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.api.StartedNodeServices
import net.corda.node.services.config.CertChainPolicyConfig import net.corda.node.services.config.CertChainPolicyConfig
import net.corda.node.services.config.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.VerifierType import net.corda.node.services.config.VerifierType
import net.corda.nodeapi.User import net.corda.nodeapi.User

View File

@ -2,14 +2,14 @@ package net.corda.testing.node
import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.CompositeKey
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.messaging.AllPossibleRecipients import net.corda.core.messaging.AllPossibleRecipients
import net.corda.core.messaging.MessageRecipientGroup import net.corda.core.messaging.MessageRecipientGroup
import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.node.services.PartyInfo import net.corda.core.node.services.PartyInfo
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
@ -17,7 +17,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.trace import net.corda.core.utilities.trace
import net.corda.node.services.messaging.* import net.corda.node.services.messaging.*
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.node.InMemoryMessagingNetwork.InMemoryMessaging import net.corda.testing.node.InMemoryMessagingNetwork.InMemoryMessaging
import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.activemq.artemis.utils.ReusableLatch
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory

View File

@ -8,7 +8,7 @@ import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.services.network.PersistentNetworkMapCache import net.corda.node.services.network.PersistentNetworkMapCache
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.getTestPartyAndCertificate import net.corda.testing.getTestPartyAndCertificate
import rx.Observable import rx.Observable
import rx.subjects.PublishSubject import rx.subjects.PublishSubject

View File

@ -36,7 +36,7 @@ import net.corda.node.services.transactions.BFTSMaRt
import net.corda.node.services.transactions.InMemoryTransactionVerifierService import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor
import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties

View File

@ -18,21 +18,22 @@ import net.corda.core.transactions.SignedTransaction
import net.corda.node.VersionInfo import net.corda.node.VersionInfo
import net.corda.node.internal.StateLoaderImpl import net.corda.node.internal.StateLoaderImpl
import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.services.api.SchemaService
import net.corda.node.services.api.StateMachineRecordedTransactionMappingStorage import net.corda.node.services.api.StateMachineRecordedTransactionMappingStorage
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.api.WritableTransactionStorage import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.config.DatabaseConfig
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.keys.freshCertificate import net.corda.node.services.keys.freshCertificate
import net.corda.node.services.keys.getSigner import net.corda.node.services.keys.getSigner
import net.corda.node.services.persistence.HibernateConfiguration
import net.corda.node.services.persistence.InMemoryStateMachineRecordedTransactionMappingStorage import net.corda.node.services.persistence.InMemoryStateMachineRecordedTransactionMappingStorage
import net.corda.node.services.schema.HibernateObserver import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.transactions.InMemoryTransactionVerifierService import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.NodeVaultService
import net.corda.node.utilities.CordaPersistence import net.corda.node.internal.configureDatabase
import net.corda.node.utilities.configureDatabase import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.testing.* import net.corda.testing.*
import org.bouncycastle.operator.ContentSigner import org.bouncycastle.operator.ContentSigner
import rx.Observable import rx.Observable
@ -78,6 +79,7 @@ open class MockServices(
} }
private fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRoot = DEV_TRUST_ROOT) private fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRoot = DEV_TRUST_ROOT)
/** /**
* Makes database and mock services appropriate for unit tests. * Makes database and mock services appropriate for unit tests.
* @param keys a list of [KeyPair] instances to be used by [MockServices]. Defaults to [MEGA_CORP_KEY] * @param keys a list of [KeyPair] instances to be used by [MockServices]. Defaults to [MEGA_CORP_KEY]
@ -88,8 +90,9 @@ open class MockServices(
@JvmStatic @JvmStatic
fun makeTestDatabaseAndMockServices(keys: List<KeyPair> = listOf(MEGA_CORP_KEY), fun makeTestDatabaseAndMockServices(keys: List<KeyPair> = listOf(MEGA_CORP_KEY),
identityService: IdentityService = makeTestIdentityService(), identityService: IdentityService = makeTestIdentityService(),
cordappPackages: List<String> = emptyList()): Pair<CordaPersistence, MockServices> cordappPackages: List<String> = emptyList()): Pair<CordaPersistence, MockServices> {
= makeTestDatabaseAndMockServices(keys, identityService, cordappPackages, MEGA_CORP.name) return makeTestDatabaseAndMockServices(keys, identityService, cordappPackages, MEGA_CORP.name)
}
/** /**
* Makes database and mock services appropriate for unit tests. * Makes database and mock services appropriate for unit tests.
@ -105,11 +108,12 @@ open class MockServices(
initialIdentityName: CordaX500Name): Pair<CordaPersistence, MockServices> { initialIdentityName: CordaX500Name): Pair<CordaPersistence, MockServices> {
val cordappLoader = CordappLoader.createWithTestPackages(cordappPackages) val cordappLoader = CordappLoader.createWithTestPackages(cordappPackages)
val dataSourceProps = makeTestDataSourceProperties() val dataSourceProps = makeTestDataSourceProperties()
val database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, NodeSchemaService(cordappLoader)) val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
val database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, schemaService)
val mockService = database.transaction { val mockService = database.transaction {
object : MockServices(cordappLoader, initialIdentityName = initialIdentityName, keys = *(keys.toTypedArray())) { object : MockServices(cordappLoader, initialIdentityName = initialIdentityName, keys = *(keys.toTypedArray())) {
override val identityService get() = identityService override val identityService get() = identityService
override val vaultService: VaultServiceInternal = makeVaultService(database.hibernateConfig) override val vaultService: VaultServiceInternal = makeVaultService(database.hibernateConfig, schemaService)
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) { override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
for (stx in txs) { for (stx in txs) {
@ -161,13 +165,13 @@ open class MockServices(
override val cordappProvider: CordappProvider get() = mockCordappProvider override val cordappProvider: CordappProvider get() = mockCordappProvider
lateinit var hibernatePersister: HibernateObserver lateinit var hibernatePersister: HibernateObserver
fun makeVaultService(hibernateConfig: HibernateConfiguration): VaultServiceInternal { fun makeVaultService(hibernateConfig: HibernateConfiguration, schemaService: SchemaService): VaultServiceInternal {
val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, stateLoader, hibernateConfig) val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, stateLoader, hibernateConfig)
hibernatePersister = HibernateObserver.install(vaultService.rawUpdates, hibernateConfig) hibernatePersister = HibernateObserver.install(vaultService.rawUpdates, hibernateConfig, schemaService)
return vaultService return vaultService
} }
val cordappServices = MutableClassToInstanceMap.create<SerializeAsToken>() val cordappServices: MutableClassToInstanceMap<SerializeAsToken> = MutableClassToInstanceMap.create<SerializeAsToken>()
override fun <T : SerializeAsToken> cordaService(type: Class<T>): T { override fun <T : SerializeAsToken> cordaService(type: Class<T>): T {
require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" } require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" }
return cordappServices.getInstance(type) ?: throw IllegalArgumentException("Corda service ${type.name} does not exist") return cordappServices.getInstance(type) ?: throw IllegalArgumentException("Corda service ${type.name} does not exist")