mirror of
https://github.com/corda/corda.git
synced 2025-06-16 14:18:20 +00:00
ENT-2431 Tidy up buildNamed and CacheFactory
This commit is contained in:
@ -7,7 +7,6 @@ import javafx.collections.FXCollections
|
|||||||
import javafx.collections.ObservableList
|
import javafx.collections.ObservableList
|
||||||
import net.corda.client.jfx.utils.*
|
import net.corda.client.jfx.utils.*
|
||||||
import net.corda.core.identity.AnonymousParty
|
import net.corda.core.identity.AnonymousParty
|
||||||
import net.corda.core.internal.buildNamed
|
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.node.services.NetworkMapCache.MapChange
|
import net.corda.core.node.services.NetworkMapCache.MapChange
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
@ -32,7 +31,7 @@ class NetworkIdentityModel {
|
|||||||
private val rpcProxy by observableValue(NodeMonitorModel::proxyObservable)
|
private val rpcProxy by observableValue(NodeMonitorModel::proxyObservable)
|
||||||
|
|
||||||
private val identityCache = Caffeine.newBuilder()
|
private val identityCache = Caffeine.newBuilder()
|
||||||
.buildNamed<PublicKey, ObservableValue<NodeInfo?>>("NetworkIdentityModel_identity", CacheLoader { publicKey: PublicKey ->
|
.build<PublicKey, ObservableValue<NodeInfo?>>(CacheLoader { publicKey: PublicKey ->
|
||||||
publicKey.let { rpcProxy.map { it?.cordaRPCOps?.nodeInfoFromParty(AnonymousParty(publicKey)) } }
|
publicKey.let { rpcProxy.map { it?.cordaRPCOps?.nodeInfoFromParty(AnonymousParty(publicKey)) } }
|
||||||
})
|
})
|
||||||
val notaries = ChosenList(rpcProxy.map { FXCollections.observableList(it?.cordaRPCOps?.notaryIdentities() ?: emptyList()) }, "notaries")
|
val notaries = ChosenList(rpcProxy.map { FXCollections.observableList(it?.cordaRPCOps?.notaryIdentities() ?: emptyList()) }, "notaries")
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package net.corda.client.rpc.internal
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Cache
|
||||||
|
import com.github.benmanes.caffeine.cache.CacheLoader
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
|
|
||||||
|
class ClientCacheFactory : NamedCacheFactory {
|
||||||
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V> {
|
||||||
|
checkCacheName(name)
|
||||||
|
return caffeine.build<K, V>()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V> {
|
||||||
|
checkCacheName(name)
|
||||||
|
return caffeine.build<K, V>(loader)
|
||||||
|
}
|
||||||
|
}
|
@ -83,7 +83,8 @@ class RPCClientProxyHandler(
|
|||||||
private val sessionId: Trace.SessionId,
|
private val sessionId: Trace.SessionId,
|
||||||
private val externalTrace: Trace?,
|
private val externalTrace: Trace?,
|
||||||
private val impersonatedActor: Actor?,
|
private val impersonatedActor: Actor?,
|
||||||
private val targetLegalIdentity: CordaX500Name?
|
private val targetLegalIdentity: CordaX500Name?,
|
||||||
|
private val cacheFactory: NamedCacheFactory = ClientCacheFactory()
|
||||||
) : InvocationHandler {
|
) : InvocationHandler {
|
||||||
|
|
||||||
private enum class State {
|
private enum class State {
|
||||||
@ -169,8 +170,7 @@ class RPCClientProxyHandler(
|
|||||||
}
|
}
|
||||||
observablesToReap.locked { observables.add(observableId) }
|
observablesToReap.locked { observables.add(observableId) }
|
||||||
}
|
}
|
||||||
return Caffeine.newBuilder().
|
return cacheFactory.buildNamed(Caffeine.newBuilder().weakValues().removalListener(onObservableRemove).executor(SameThreadExecutor.getExecutor()), "RpcClientProxyHandler_rpcObservable")
|
||||||
weakValues().removalListener(onObservableRemove).executor(SameThreadExecutor.getExecutor()).buildNamed("RpcClientProxyHandler_rpcObservable")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var sessionFactory: ClientSessionFactory? = null
|
private var sessionFactory: ClientSessionFactory? = null
|
||||||
@ -179,7 +179,7 @@ class RPCClientProxyHandler(
|
|||||||
private var rpcProducer: ClientProducer? = null
|
private var rpcProducer: ClientProducer? = null
|
||||||
private var rpcConsumer: ClientConsumer? = null
|
private var rpcConsumer: ClientConsumer? = null
|
||||||
|
|
||||||
private val deduplicationChecker = DeduplicationChecker(rpcConfiguration.deduplicationCacheExpiry)
|
private val deduplicationChecker = DeduplicationChecker(rpcConfiguration.deduplicationCacheExpiry, cacheFactory = cacheFactory)
|
||||||
private val deduplicationSequenceNumber = AtomicLong(0)
|
private val deduplicationSequenceNumber = AtomicLong(0)
|
||||||
|
|
||||||
private val sendingEnabled = AtomicBoolean(true)
|
private val sendingEnabled = AtomicBoolean(true)
|
||||||
|
@ -6,30 +6,21 @@ import com.github.benmanes.caffeine.cache.Caffeine
|
|||||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Allow extra functionality to be injected to our caches.
|
||||||
|
*/
|
||||||
|
interface NamedCacheFactory {
|
||||||
|
/**
|
||||||
* Restrict the allowed characters of a cache name - this ensures that each cache has a name, and that
|
* Restrict the allowed characters of a cache name - this ensures that each cache has a name, and that
|
||||||
* the name can be used to create a file name or a metric name.
|
* the name can be used to create a file name or a metric name.
|
||||||
*/
|
*/
|
||||||
internal fun checkCacheName(name: String) {
|
fun checkCacheName(name: String) {
|
||||||
require(!name.isBlank())
|
require(!name.isBlank())
|
||||||
require(allowedChars.matches(name))
|
require(allowedChars.matches(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V>
|
||||||
|
|
||||||
|
fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V>
|
||||||
}
|
}
|
||||||
|
|
||||||
private val allowedChars = Regex("^[0-9A-Za-z_.]*\$")
|
private val allowedChars = Regex("^[0-9A-Za-z_.]*\$")
|
||||||
|
|
||||||
/* buildNamed is the central helper method to build caffeine caches in Corda.
|
|
||||||
* This allows to easily add tweaks to all caches built in Corda, and also forces
|
|
||||||
* cache users to give their cache a (meaningful) name that can be used e.g. for
|
|
||||||
* capturing cache traces etc.
|
|
||||||
*
|
|
||||||
* Currently it is not used in this version of CORDA, but there are plans to do so.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fun <K, V> Caffeine<in K, in V>.buildNamed(name: String): Cache<K, V> {
|
|
||||||
checkCacheName(name)
|
|
||||||
return this.build<K, V>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <K, V> Caffeine<in K, in V>.buildNamed(name: String, loader: CacheLoader<K, V>): LoadingCache<K, V> {
|
|
||||||
checkCacheName(name)
|
|
||||||
return this.build<K, V>(loader)
|
|
||||||
}
|
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
package net.corda.core.internal
|
package net.corda.core.internal
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Cache
|
||||||
|
import com.github.benmanes.caffeine.cache.CacheLoader
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class NamedCacheTest {
|
class NamedCacheTest : NamedCacheFactory {
|
||||||
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V> {
|
||||||
|
throw IllegalStateException("Should not be called")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V> {
|
||||||
|
throw IllegalStateException("Should not be called")
|
||||||
|
}
|
||||||
|
|
||||||
fun checkNameHelper(name: String, throws: Boolean) {
|
fun checkNameHelper(name: String, throws: Boolean) {
|
||||||
var exceptionThrown = false
|
var exceptionThrown = false
|
||||||
try {
|
try {
|
||||||
|
@ -18,6 +18,7 @@ import net.corda.core.contracts.TimeWindow
|
|||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.flows.NotarisationRequestSignature
|
import net.corda.core.flows.NotarisationRequestSignature
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.notary.NotaryInternalException
|
import net.corda.core.internal.notary.NotaryInternalException
|
||||||
import net.corda.core.internal.notary.UniquenessProvider
|
import net.corda.core.internal.notary.UniquenessProvider
|
||||||
import net.corda.core.schemas.PersistentStateRef
|
import net.corda.core.schemas.PersistentStateRef
|
||||||
@ -27,7 +28,6 @@ import net.corda.core.utilities.contextLogger
|
|||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
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.NamedCacheFactory
|
|
||||||
import net.corda.nodeapi.internal.config.MutualSslConfiguration
|
import net.corda.nodeapi.internal.config.MutualSslConfiguration
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
||||||
|
@ -14,7 +14,6 @@ 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.internal.configureDatabase
|
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
@ -23,6 +22,7 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.hamcrest.Matchers.instanceOf
|
import org.hamcrest.Matchers.instanceOf
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
|
@ -2,7 +2,7 @@ package net.corda.nodeapi.internal
|
|||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.CacheLoader
|
import com.github.benmanes.caffeine.cache.CacheLoader
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import net.corda.core.internal.buildNamed
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicLong
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
@ -10,11 +10,10 @@ import java.util.concurrent.atomic.AtomicLong
|
|||||||
/**
|
/**
|
||||||
* A class allowing the deduplication of a strictly incrementing sequence number.
|
* A class allowing the deduplication of a strictly incrementing sequence number.
|
||||||
*/
|
*/
|
||||||
class DeduplicationChecker(cacheExpiry: Duration, name: String = "DeduplicationChecker") {
|
class DeduplicationChecker(cacheExpiry: Duration, name: String = "DeduplicationChecker", cacheFactory: NamedCacheFactory) {
|
||||||
// dedupe identity -> watermark cache
|
// dedupe identity -> watermark cache
|
||||||
private val watermarkCache = Caffeine.newBuilder()
|
private val watermarkCache = cacheFactory.buildNamed(Caffeine.newBuilder()
|
||||||
.expireAfterAccess(cacheExpiry.toNanos(), TimeUnit.NANOSECONDS)
|
.expireAfterAccess(cacheExpiry.toNanos(), TimeUnit.NANOSECONDS), "${name}_watermark", WatermarkCacheLoader)
|
||||||
.buildNamed("${name}_watermark", WatermarkCacheLoader)
|
|
||||||
|
|
||||||
private object WatermarkCacheLoader : CacheLoader<Any, AtomicLong> {
|
private object WatermarkCacheLoader : CacheLoader<Any, AtomicLong> {
|
||||||
override fun load(key: Any) = AtomicLong(-1)
|
override fun load(key: Any) = AtomicLong(-1)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.nodeapi.internal.persistence
|
package net.corda.nodeapi.internal.persistence
|
||||||
|
|
||||||
import co.paralleluniverse.strands.Strand
|
import co.paralleluniverse.strands.Strand
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
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 rx.Observable
|
import rx.Observable
|
||||||
@ -52,6 +53,7 @@ class CordaPersistence(
|
|||||||
databaseConfig: DatabaseConfig,
|
databaseConfig: DatabaseConfig,
|
||||||
schemas: Set<MappedSchema>,
|
schemas: Set<MappedSchema>,
|
||||||
val jdbcUrl: String,
|
val jdbcUrl: String,
|
||||||
|
cacheFactory: NamedCacheFactory,
|
||||||
attributeConverters: Collection<AttributeConverter<*, *>> = emptySet()
|
attributeConverters: Collection<AttributeConverter<*, *>> = emptySet()
|
||||||
) : Closeable {
|
) : Closeable {
|
||||||
companion object {
|
companion object {
|
||||||
@ -61,7 +63,7 @@ class CordaPersistence(
|
|||||||
private val defaultIsolationLevel = databaseConfig.transactionIsolationLevel
|
private val defaultIsolationLevel = databaseConfig.transactionIsolationLevel
|
||||||
val hibernateConfig: HibernateConfiguration by lazy {
|
val hibernateConfig: HibernateConfiguration by lazy {
|
||||||
transaction {
|
transaction {
|
||||||
HibernateConfiguration(schemas, databaseConfig, attributeConverters, jdbcUrl)
|
HibernateConfiguration(schemas, databaseConfig, attributeConverters, jdbcUrl, cacheFactory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.corda.nodeapi.internal.persistence
|
package net.corda.nodeapi.internal.persistence
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import net.corda.core.internal.buildNamed
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.castIfPossible
|
import net.corda.core.internal.castIfPossible
|
||||||
import net.corda.core.schemas.MappedSchema
|
import net.corda.core.schemas.MappedSchema
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
@ -31,6 +31,7 @@ class HibernateConfiguration(
|
|||||||
private val databaseConfig: DatabaseConfig,
|
private val databaseConfig: DatabaseConfig,
|
||||||
private val attributeConverters: Collection<AttributeConverter<*, *>>,
|
private val attributeConverters: Collection<AttributeConverter<*, *>>,
|
||||||
private val jdbcUrl: String,
|
private val jdbcUrl: String,
|
||||||
|
cacheFactory: NamedCacheFactory,
|
||||||
val cordappClassLoader: ClassLoader? = null
|
val cordappClassLoader: ClassLoader? = null
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -58,7 +59,7 @@ class HibernateConfiguration(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val sessionFactories = Caffeine.newBuilder().maximumSize(databaseConfig.mappedSchemaCacheSize).buildNamed<Set<MappedSchema>, SessionFactory>("HibernateConfiguration_sessionFactories")
|
private val sessionFactories = cacheFactory.buildNamed<Set<MappedSchema>, SessionFactory>(Caffeine.newBuilder(), "HibernateConfiguration_sessionFactories")
|
||||||
|
|
||||||
val sessionFactoryForRegisteredSchemas = schemas.let {
|
val sessionFactoryForRegisteredSchemas = schemas.let {
|
||||||
logger.info("Init HibernateConfiguration for schemas: $it")
|
logger.info("Init HibernateConfiguration for schemas: $it")
|
||||||
|
@ -7,7 +7,6 @@ import net.corda.core.crypto.generateKeyPair
|
|||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
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.internal.configureDatabase
|
|
||||||
import net.corda.node.services.config.FlowTimeoutConfiguration
|
import net.corda.node.services.config.FlowTimeoutConfiguration
|
||||||
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
|
||||||
@ -21,11 +20,12 @@ import net.corda.testing.core.MAX_MESSAGE_SIZE
|
|||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import net.corda.testing.node.internal.MOCK_VERSION_INFO
|
import net.corda.testing.node.internal.MOCK_VERSION_INFO
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException
|
import org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
|
@ -2,14 +2,14 @@ package net.corda.node.services.network
|
|||||||
|
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
||||||
import net.corda.node.services.identity.InMemoryIdentityService
|
import net.corda.node.services.identity.InMemoryIdentityService
|
||||||
import net.corda.nodeapi.internal.DEV_ROOT_CA
|
import net.corda.nodeapi.internal.DEV_ROOT_CA
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
|
@ -23,6 +23,8 @@ import net.corda.nodeapi.internal.config.MutualSslConfiguration
|
|||||||
import net.corda.nodeapi.internal.config.User
|
import net.corda.nodeapi.internal.config.User
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
|
import net.corda.testing.internal.fromUserList
|
||||||
import net.corda.testing.internal.p2pSslOptions
|
import net.corda.testing.internal.p2pSslOptions
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException
|
import org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException
|
||||||
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
||||||
@ -128,7 +130,7 @@ class ArtemisRpcTests {
|
|||||||
|
|
||||||
private fun <OPS : RPCOps> InternalRPCMessagingClient.start(ops: OPS, securityManager: RPCSecurityManager, brokerControl: ActiveMQServerControl) {
|
private fun <OPS : RPCOps> InternalRPCMessagingClient.start(ops: OPS, securityManager: RPCSecurityManager, brokerControl: ActiveMQServerControl) {
|
||||||
apply {
|
apply {
|
||||||
init(ops, securityManager)
|
init(ops, securityManager, TestingNamedCacheFactory())
|
||||||
start(brokerControl)
|
start(brokerControl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import net.corda.core.identity.CordaX500Name
|
|||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
import net.corda.core.internal.FlowStateMachine
|
import net.corda.core.internal.FlowStateMachine
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.VisibleForTesting
|
import net.corda.core.internal.VisibleForTesting
|
||||||
import net.corda.core.internal.concurrent.map
|
import net.corda.core.internal.concurrent.map
|
||||||
import net.corda.core.internal.concurrent.openFuture
|
import net.corda.core.internal.concurrent.openFuture
|
||||||
@ -115,7 +116,7 @@ import net.corda.core.crypto.generateKeyPair as cryptoGenerateKeyPair
|
|||||||
// TODO Log warning if this node is a notary but not one of the ones specified in the network parameters, both for core and custom
|
// TODO Log warning if this node is a notary but not one of the ones specified in the network parameters, both for core and custom
|
||||||
abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
||||||
val platformClock: CordaClock,
|
val platformClock: CordaClock,
|
||||||
cacheFactoryPrototype: NamedCacheFactory,
|
cacheFactoryPrototype: BindableNamedCacheFactory,
|
||||||
protected val versionInfo: VersionInfo,
|
protected val versionInfo: VersionInfo,
|
||||||
protected val serverThread: AffinityExecutor.ServiceAffinityExecutor,
|
protected val serverThread: AffinityExecutor.ServiceAffinityExecutor,
|
||||||
private val busyNodeLatch: ReusableLatch = ReusableLatch()) : SingletonSerializeAsToken() {
|
private val busyNodeLatch: ReusableLatch = ReusableLatch()) : SingletonSerializeAsToken() {
|
||||||
@ -150,8 +151,8 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
identityService::wellKnownPartyFromX500Name,
|
identityService::wellKnownPartyFromX500Name,
|
||||||
identityService::wellKnownPartyFromAnonymous,
|
identityService::wellKnownPartyFromAnonymous,
|
||||||
schemaService,
|
schemaService,
|
||||||
configuration.dataSourceProperties
|
configuration.dataSourceProperties,
|
||||||
)
|
cacheFactory)
|
||||||
init {
|
init {
|
||||||
// TODO Break cyclic dependency
|
// TODO Break cyclic dependency
|
||||||
identityService.database = database
|
identityService.database = database
|
||||||
@ -169,7 +170,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
val servicesForResolution = ServicesForResolutionImpl(identityService, attachments, cordappProvider, transactionStorage)
|
val servicesForResolution = ServicesForResolutionImpl(identityService, attachments, cordappProvider, transactionStorage)
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
val vaultService = makeVaultService(keyManagementService, servicesForResolution, database).tokenize()
|
val vaultService = makeVaultService(keyManagementService, servicesForResolution, database).tokenize()
|
||||||
val nodeProperties = NodePropertiesPersistentStore(StubbedNodeUniqueIdProvider::value, database)
|
val nodeProperties = NodePropertiesPersistentStore(StubbedNodeUniqueIdProvider::value, database, cacheFactory)
|
||||||
val flowLogicRefFactory = FlowLogicRefFactoryImpl(cordappLoader.appClassLoader)
|
val flowLogicRefFactory = FlowLogicRefFactoryImpl(cordappLoader.appClassLoader)
|
||||||
val networkMapUpdater = NetworkMapUpdater(
|
val networkMapUpdater = NetworkMapUpdater(
|
||||||
networkMapCache,
|
networkMapCache,
|
||||||
@ -185,7 +186,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
).closeOnStop()
|
).closeOnStop()
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
val transactionVerifierService = InMemoryTransactionVerifierService(transactionVerifierWorkerCount).tokenize()
|
val transactionVerifierService = InMemoryTransactionVerifierService(transactionVerifierWorkerCount).tokenize()
|
||||||
val contractUpgradeService = ContractUpgradeServiceImpl().tokenize()
|
val contractUpgradeService = ContractUpgradeServiceImpl(cacheFactory).tokenize()
|
||||||
val auditService = DummyAuditService().tokenize()
|
val auditService = DummyAuditService().tokenize()
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
protected val network: MessagingService = makeMessagingService().tokenize()
|
protected val network: MessagingService = makeMessagingService().tokenize()
|
||||||
@ -999,23 +1000,12 @@ class FlowStarterImpl(private val smm: StateMachineManager, private val flowLogi
|
|||||||
|
|
||||||
class ConfigurationException(message: String) : CordaException(message)
|
class ConfigurationException(message: String) : CordaException(message)
|
||||||
|
|
||||||
// TODO This is no longer used by AbstractNode and can be moved elsewhere
|
|
||||||
fun configureDatabase(hikariProperties: Properties,
|
|
||||||
databaseConfig: DatabaseConfig,
|
|
||||||
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
|
|
||||||
wellKnownPartyFromAnonymous: (AbstractParty) -> Party?,
|
|
||||||
schemaService: SchemaService = NodeSchemaService(),
|
|
||||||
internalSchemas: Set<MappedSchema> = NodeSchemaService().internalSchemas()): CordaPersistence {
|
|
||||||
val persistence = createCordaPersistence(databaseConfig, wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous, schemaService, hikariProperties)
|
|
||||||
persistence.startHikariPool(hikariProperties, databaseConfig, internalSchemas)
|
|
||||||
return persistence
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createCordaPersistence(databaseConfig: DatabaseConfig,
|
fun createCordaPersistence(databaseConfig: DatabaseConfig,
|
||||||
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
|
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
|
||||||
wellKnownPartyFromAnonymous: (AbstractParty) -> Party?,
|
wellKnownPartyFromAnonymous: (AbstractParty) -> Party?,
|
||||||
schemaService: SchemaService,
|
schemaService: SchemaService,
|
||||||
hikariProperties: Properties): CordaPersistence {
|
hikariProperties: Properties,
|
||||||
|
cacheFactory: NamedCacheFactory): CordaPersistence {
|
||||||
// Register the AbstractPartyDescriptor so Hibernate doesn't warn when encountering AbstractParty. Unfortunately
|
// 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
|
// 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
|
// so we end up providing both descriptor and converter. We should re-examine this in later versions to see if
|
||||||
@ -1023,7 +1013,7 @@ fun createCordaPersistence(databaseConfig: DatabaseConfig,
|
|||||||
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
|
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
|
||||||
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
|
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
|
||||||
val jdbcUrl = hikariProperties.getProperty("dataSource.url", "")
|
val jdbcUrl = hikariProperties.getProperty("dataSource.url", "")
|
||||||
return CordaPersistence(databaseConfig, schemaService.schemaOptions.keys, jdbcUrl, attributeConverters)
|
return CordaPersistence(databaseConfig, schemaService.schemaOptions.keys, jdbcUrl, cacheFactory, attributeConverters)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CordaPersistence.startHikariPool(hikariProperties: Properties, databaseConfig: DatabaseConfig, schemas: Set<MappedSchema>, metricRegistry: MetricRegistry? = null) {
|
fun CordaPersistence.startHikariPool(hikariProperties: Properties, databaseConfig: DatabaseConfig, schemas: Set<MappedSchema>, metricRegistry: MetricRegistry? = null) {
|
||||||
|
@ -85,7 +85,7 @@ class NodeWithInfo(val node: Node, val info: NodeInfo) {
|
|||||||
open class Node(configuration: NodeConfiguration,
|
open class Node(configuration: NodeConfiguration,
|
||||||
versionInfo: VersionInfo,
|
versionInfo: VersionInfo,
|
||||||
private val initialiseSerialization: Boolean = true,
|
private val initialiseSerialization: Boolean = true,
|
||||||
cacheFactoryPrototype: NamedCacheFactory = DefaultNamedCacheFactory()
|
cacheFactoryPrototype: BindableNamedCacheFactory = DefaultNamedCacheFactory()
|
||||||
) : AbstractNode<NodeInfo>(
|
) : AbstractNode<NodeInfo>(
|
||||||
configuration,
|
configuration,
|
||||||
createClock(configuration),
|
createClock(configuration),
|
||||||
@ -223,7 +223,7 @@ open class Node(configuration: NodeConfiguration,
|
|||||||
val securityManagerConfig = configuration.security?.authService
|
val securityManagerConfig = configuration.security?.authService
|
||||||
?: SecurityConfiguration.AuthService.fromUsers(configuration.rpcUsers)
|
?: SecurityConfiguration.AuthService.fromUsers(configuration.rpcUsers)
|
||||||
|
|
||||||
val securityManager = with(RPCSecurityManagerImpl(securityManagerConfig)) {
|
val securityManager = with(RPCSecurityManagerImpl(securityManagerConfig, cacheFactory)) {
|
||||||
if (configuration.shouldStartLocalShell()) RPCSecurityManagerWithAdditionalUser(this, User(INTERNAL_SHELL_USER, INTERNAL_SHELL_USER, setOf(Permissions.all()))) else this
|
if (configuration.shouldStartLocalShell()) RPCSecurityManagerWithAdditionalUser(this, User(INTERNAL_SHELL_USER, INTERNAL_SHELL_USER, setOf(Permissions.all()))) else this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ open class Node(configuration: NodeConfiguration,
|
|||||||
// Start up the MQ clients.
|
// Start up the MQ clients.
|
||||||
internalRpcMessagingClient?.run {
|
internalRpcMessagingClient?.run {
|
||||||
closeOnStop()
|
closeOnStop()
|
||||||
init(rpcOps, securityManager)
|
init(rpcOps, securityManager, cacheFactory)
|
||||||
}
|
}
|
||||||
network.closeOnStop()
|
network.closeOnStop()
|
||||||
network.start(
|
network.start(
|
||||||
|
@ -4,14 +4,13 @@ package net.corda.node.internal.security
|
|||||||
import com.github.benmanes.caffeine.cache.Cache
|
import com.github.benmanes.caffeine.cache.Cache
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import com.google.common.primitives.Ints
|
import com.google.common.primitives.Ints
|
||||||
import net.corda.core.context.AuthServiceId
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.buildNamed
|
|
||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.internal.DataSourceFactory
|
import net.corda.node.internal.DataSourceFactory
|
||||||
|
import net.corda.node.services.config.AuthDataSourceType
|
||||||
import net.corda.node.services.config.PasswordEncryption
|
import net.corda.node.services.config.PasswordEncryption
|
||||||
import net.corda.node.services.config.SecurityConfiguration
|
import net.corda.node.services.config.SecurityConfiguration
|
||||||
import net.corda.node.services.config.AuthDataSourceType
|
|
||||||
import net.corda.nodeapi.internal.config.User
|
import net.corda.nodeapi.internal.config.User
|
||||||
import org.apache.shiro.authc.*
|
import org.apache.shiro.authc.*
|
||||||
import org.apache.shiro.authc.credential.PasswordMatcher
|
import org.apache.shiro.authc.credential.PasswordMatcher
|
||||||
@ -28,22 +27,22 @@ import org.apache.shiro.realm.jdbc.JdbcRealm
|
|||||||
import org.apache.shiro.subject.PrincipalCollection
|
import org.apache.shiro.subject.PrincipalCollection
|
||||||
import org.apache.shiro.subject.SimplePrincipalCollection
|
import org.apache.shiro.subject.SimplePrincipalCollection
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import javax.security.auth.login.FailedLoginException
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.TimeUnit
|
import javax.security.auth.login.FailedLoginException
|
||||||
|
|
||||||
private typealias AuthServiceConfig = SecurityConfiguration.AuthService
|
private typealias AuthServiceConfig = SecurityConfiguration.AuthService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of [RPCSecurityManager] adapting
|
* Default implementation of [RPCSecurityManager] adapting
|
||||||
* [org.apache.shiro.mgt.SecurityManager]
|
* [org.apache.shiro.mgt.SecurityManager]
|
||||||
*/
|
*/
|
||||||
class RPCSecurityManagerImpl(config: AuthServiceConfig) : RPCSecurityManager {
|
class RPCSecurityManagerImpl(config: AuthServiceConfig, cacheFactory: NamedCacheFactory) : RPCSecurityManager {
|
||||||
|
|
||||||
override val id = config.id
|
override val id = config.id
|
||||||
private val manager: DefaultSecurityManager
|
private val manager: DefaultSecurityManager
|
||||||
|
|
||||||
init {
|
init {
|
||||||
manager = buildImpl(config)
|
manager = buildImpl(config, cacheFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(FailedLoginException::class)
|
@Throws(FailedLoginException::class)
|
||||||
@ -75,14 +74,8 @@ class RPCSecurityManagerImpl(config: AuthServiceConfig) : RPCSecurityManager {
|
|||||||
|
|
||||||
private val logger = loggerFor<RPCSecurityManagerImpl>()
|
private val logger = loggerFor<RPCSecurityManagerImpl>()
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiate RPCSecurityManager initialised with users data from a list of [User]
|
|
||||||
*/
|
|
||||||
fun fromUserList(id: AuthServiceId, users: List<User>) =
|
|
||||||
RPCSecurityManagerImpl(AuthServiceConfig.fromUsers(users).copy(id = id))
|
|
||||||
|
|
||||||
// Build internal Shiro securityManager instance
|
// Build internal Shiro securityManager instance
|
||||||
private fun buildImpl(config: AuthServiceConfig): DefaultSecurityManager {
|
private fun buildImpl(config: AuthServiceConfig, cacheFactory: NamedCacheFactory): DefaultSecurityManager {
|
||||||
val realm = when (config.dataSource.type) {
|
val realm = when (config.dataSource.type) {
|
||||||
AuthDataSourceType.DB -> {
|
AuthDataSourceType.DB -> {
|
||||||
logger.info("Constructing DB-backed security data source: ${config.dataSource.connection}")
|
logger.info("Constructing DB-backed security data source: ${config.dataSource.connection}")
|
||||||
@ -98,7 +91,8 @@ class RPCSecurityManagerImpl(config: AuthServiceConfig) : RPCSecurityManager {
|
|||||||
it.cacheManager = config.options?.cache?.let {
|
it.cacheManager = config.options?.cache?.let {
|
||||||
CaffeineCacheManager(
|
CaffeineCacheManager(
|
||||||
timeToLiveSeconds = it.expireAfterSecs,
|
timeToLiveSeconds = it.expireAfterSecs,
|
||||||
maxSize = it.maxEntries)
|
maxSize = it.maxEntries,
|
||||||
|
cacheFactory = cacheFactory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,7 +288,8 @@ private fun <K : Any, V> Cache<K, V>.toShiroCache() = object : ShiroCache<K, V>
|
|||||||
* cache implementation in [com.github.benmanes.caffeine.cache.Cache]
|
* cache implementation in [com.github.benmanes.caffeine.cache.Cache]
|
||||||
*/
|
*/
|
||||||
private class CaffeineCacheManager(val maxSize: Long,
|
private class CaffeineCacheManager(val maxSize: Long,
|
||||||
val timeToLiveSeconds: Long) : CacheManager {
|
val timeToLiveSeconds: Long,
|
||||||
|
val cacheFactory: NamedCacheFactory) : CacheManager {
|
||||||
|
|
||||||
private val instances = ConcurrentHashMap<String, ShiroCache<*, *>>()
|
private val instances = ConcurrentHashMap<String, ShiroCache<*, *>>()
|
||||||
|
|
||||||
@ -306,11 +301,7 @@ private class CaffeineCacheManager(val maxSize: Long,
|
|||||||
|
|
||||||
private fun <K : Any, V> buildCache(name: String): ShiroCache<K, V> {
|
private fun <K : Any, V> buildCache(name: String): ShiroCache<K, V> {
|
||||||
logger.info("Constructing cache '$name' with maximumSize=$maxSize, TTL=${timeToLiveSeconds}s")
|
logger.info("Constructing cache '$name' with maximumSize=$maxSize, TTL=${timeToLiveSeconds}s")
|
||||||
return Caffeine.newBuilder()
|
return cacheFactory.buildNamed<K, V>(Caffeine.newBuilder(), "RPCSecurityManagerShiroCache_$name").toShiroCache()
|
||||||
.expireAfterWrite(timeToLiveSeconds, TimeUnit.SECONDS)
|
|
||||||
.maximumSize(maxSize)
|
|
||||||
.buildNamed<K, V>("RPCSecurityManagerShiroCache_$name")
|
|
||||||
.toShiroCache()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -6,6 +6,7 @@ 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.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.concurrent.OpenFuture
|
import net.corda.core.internal.concurrent.OpenFuture
|
||||||
import net.corda.core.messaging.DataFeed
|
import net.corda.core.messaging.DataFeed
|
||||||
import net.corda.core.messaging.StateMachineTransactionMapping
|
import net.corda.core.messaging.StateMachineTransactionMapping
|
||||||
@ -25,7 +26,6 @@ import net.corda.node.services.network.NetworkMapUpdater
|
|||||||
import net.corda.node.services.persistence.AttachmentStorageInternal
|
import net.corda.node.services.persistence.AttachmentStorageInternal
|
||||||
import net.corda.node.services.statemachine.ExternalEvent
|
import net.corda.node.services.statemachine.ExternalEvent
|
||||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.node.services.identity
|
|||||||
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.identity.*
|
import net.corda.core.identity.*
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.hash
|
import net.corda.core.internal.hash
|
||||||
import net.corda.core.node.services.UnknownAnonymousPartyException
|
import net.corda.core.node.services.UnknownAnonymousPartyException
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
@ -10,7 +11,6 @@ import net.corda.core.utilities.contextLogger
|
|||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
import net.corda.node.services.api.IdentityServiceInternal
|
import net.corda.node.services.api.IdentityServiceInternal
|
||||||
import net.corda.node.utilities.AppendOnlyPersistentMap
|
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
|
||||||
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
||||||
import net.corda.nodeapi.internal.crypto.x509Certificates
|
import net.corda.nodeapi.internal.crypto.x509Certificates
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
|
@ -2,11 +2,11 @@ package net.corda.node.services.keys
|
|||||||
|
|
||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.*
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
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.services.identity.PersistentIdentityService
|
import net.corda.node.services.identity.PersistentIdentityService
|
||||||
import net.corda.node.utilities.AppendOnlyPersistentMap
|
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
||||||
import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY
|
import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.node.services.messaging
|
package net.corda.node.services.messaging
|
||||||
|
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.messaging.RPCOps
|
import net.corda.core.messaging.RPCOps
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.core.serialization.internal.nodeSerializationEnv
|
import net.corda.core.serialization.internal.nodeSerializationEnv
|
||||||
@ -20,7 +21,7 @@ class InternalRPCMessagingClient(val sslConfig: MutualSslConfiguration, val serv
|
|||||||
private var locator: ServerLocator? = null
|
private var locator: ServerLocator? = null
|
||||||
private var rpcServer: RPCServer? = null
|
private var rpcServer: RPCServer? = null
|
||||||
|
|
||||||
fun init(rpcOps: RPCOps, securityManager: RPCSecurityManager) = synchronized(this) {
|
fun init(rpcOps: RPCOps, securityManager: RPCSecurityManager, cacheFactory: NamedCacheFactory) = synchronized(this) {
|
||||||
|
|
||||||
val tcpTransport = ArtemisTcpTransport.rpcInternalClientTcpTransport(serverAddress, sslConfig)
|
val tcpTransport = ArtemisTcpTransport.rpcInternalClientTcpTransport(serverAddress, sslConfig)
|
||||||
locator = ActiveMQClient.createServerLocatorWithoutHA(tcpTransport).apply {
|
locator = ActiveMQClient.createServerLocatorWithoutHA(tcpTransport).apply {
|
||||||
@ -32,7 +33,7 @@ class InternalRPCMessagingClient(val sslConfig: MutualSslConfiguration, val serv
|
|||||||
isUseGlobalPools = nodeSerializationEnv != null
|
isUseGlobalPools = nodeSerializationEnv != null
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcServer = RPCServer(rpcOps, NODE_RPC_USER, NODE_RPC_USER, locator!!, securityManager, nodeName, rpcServerConfiguration)
|
rpcServer = RPCServer(rpcOps, NODE_RPC_USER, NODE_RPC_USER, locator!!, securityManager, nodeName, rpcServerConfiguration, cacheFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun start(serverControl: ActiveMQServerControl) = synchronized(this) {
|
fun start(serverControl: ActiveMQServerControl) = synchronized(this) {
|
||||||
|
@ -2,9 +2,9 @@ package net.corda.node.services.messaging
|
|||||||
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.node.services.statemachine.DeduplicationId
|
import net.corda.node.services.statemachine.DeduplicationId
|
||||||
import net.corda.node.utilities.AppendOnlyPersistentMap
|
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
@ -4,6 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
|
|||||||
import com.codahale.metrics.MetricRegistry
|
import com.codahale.metrics.MetricRegistry
|
||||||
import net.corda.core.crypto.toStringShort
|
import net.corda.core.crypto.toStringShort
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.ThreadBox
|
import net.corda.core.internal.ThreadBox
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.messaging.MessageRecipients
|
import net.corda.core.messaging.MessageRecipients
|
||||||
@ -27,7 +28,6 @@ import net.corda.node.services.statemachine.DeduplicationId
|
|||||||
import net.corda.node.services.statemachine.ExternalEvent
|
import net.corda.node.services.statemachine.ExternalEvent
|
||||||
import net.corda.node.services.statemachine.SenderDeduplicationId
|
import net.corda.node.services.statemachine.SenderDeduplicationId
|
||||||
import net.corda.node.utilities.AffinityExecutor
|
import net.corda.node.utilities.AffinityExecutor
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.*
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.*
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.BRIDGE_CONTROL
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.BRIDGE_CONTROL
|
||||||
|
@ -13,7 +13,7 @@ import net.corda.core.context.Trace
|
|||||||
import net.corda.core.context.Trace.InvocationId
|
import net.corda.core.context.Trace.InvocationId
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.LifeCycle
|
import net.corda.core.internal.LifeCycle
|
||||||
import net.corda.core.internal.buildNamed
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.messaging.RPCOps
|
import net.corda.core.messaging.RPCOps
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.SerializationDefaults
|
import net.corda.core.serialization.SerializationDefaults
|
||||||
@ -33,13 +33,8 @@ import net.corda.nodeapi.internal.persistence.contextDatabase
|
|||||||
import net.corda.nodeapi.internal.persistence.contextDatabaseOrNull
|
import net.corda.nodeapi.internal.persistence.contextDatabaseOrNull
|
||||||
import org.apache.activemq.artemis.api.core.Message
|
import org.apache.activemq.artemis.api.core.Message
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
|
import org.apache.activemq.artemis.api.core.client.*
|
||||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE
|
import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientConsumer
|
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientMessage
|
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientProducer
|
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientSession
|
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory
|
|
||||||
import org.apache.activemq.artemis.api.core.client.ServerLocator
|
|
||||||
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
||||||
import org.apache.activemq.artemis.api.core.management.CoreNotificationType
|
import org.apache.activemq.artemis.api.core.management.CoreNotificationType
|
||||||
import org.apache.activemq.artemis.api.core.management.ManagementHelper
|
import org.apache.activemq.artemis.api.core.management.ManagementHelper
|
||||||
@ -49,12 +44,7 @@ import java.lang.reflect.InvocationTargetException
|
|||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.*
|
||||||
import java.util.concurrent.Executors
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
|
||||||
import java.util.concurrent.ScheduledFuture
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
private typealias ObservableSubscriptionMap = Cache<InvocationId, ObservableSubscription>
|
private typealias ObservableSubscriptionMap = Cache<InvocationId, ObservableSubscription>
|
||||||
@ -91,7 +81,8 @@ class RPCServer(
|
|||||||
private val serverLocator: ServerLocator,
|
private val serverLocator: ServerLocator,
|
||||||
private val securityManager: RPCSecurityManager,
|
private val securityManager: RPCSecurityManager,
|
||||||
private val nodeLegalName: CordaX500Name,
|
private val nodeLegalName: CordaX500Name,
|
||||||
private val rpcConfiguration: RPCServerConfiguration
|
private val rpcConfiguration: RPCServerConfiguration,
|
||||||
|
private val cacheFactory: NamedCacheFactory
|
||||||
) {
|
) {
|
||||||
private companion object {
|
private companion object {
|
||||||
private val log = contextLogger()
|
private val log = contextLogger()
|
||||||
@ -136,7 +127,7 @@ class RPCServer(
|
|||||||
private val responseMessageBuffer = ConcurrentHashMap<SimpleString, BufferOrNone>()
|
private val responseMessageBuffer = ConcurrentHashMap<SimpleString, BufferOrNone>()
|
||||||
private val sendJobQueue = LinkedBlockingQueue<RpcSendJob>()
|
private val sendJobQueue = LinkedBlockingQueue<RpcSendJob>()
|
||||||
|
|
||||||
private val deduplicationChecker = DeduplicationChecker(rpcConfiguration.deduplicationCacheExpiry)
|
private val deduplicationChecker = DeduplicationChecker(rpcConfiguration.deduplicationCacheExpiry, cacheFactory = cacheFactory)
|
||||||
private var deduplicationIdentity: String? = null
|
private var deduplicationIdentity: String? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -154,7 +145,7 @@ class RPCServer(
|
|||||||
log.debug { "Unsubscribing from Observable with id $key because of $cause" }
|
log.debug { "Unsubscribing from Observable with id $key because of $cause" }
|
||||||
value!!.subscription.unsubscribe()
|
value!!.subscription.unsubscribe()
|
||||||
}
|
}
|
||||||
return Caffeine.newBuilder().removalListener(onObservableRemove).executor(SameThreadExecutor.getExecutor()).buildNamed("RPCServer_observableSubscription")
|
return cacheFactory.buildNamed(Caffeine.newBuilder().removalListener(onObservableRemove).executor(SameThreadExecutor.getExecutor()), "RPCServer_observableSubscription")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun start(activeMqServerControl: ActiveMQServerControl) {
|
fun start(activeMqServerControl: ActiveMQServerControl) {
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.identity.AbstractParty
|
|||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.bufferUntilSubscribed
|
import net.corda.core.internal.bufferUntilSubscribed
|
||||||
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
|
||||||
@ -23,7 +24,6 @@ import net.corda.core.utilities.contextLogger
|
|||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
||||||
import net.corda.node.services.api.NetworkMapCacheInternal
|
import net.corda.node.services.api.NetworkMapCacheInternal
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
|
||||||
import net.corda.node.utilities.NonInvalidatingCache
|
import net.corda.node.utilities.NonInvalidatingCache
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
|
import net.corda.nodeapi.internal.persistence.bufferUntilDatabaseCommit
|
||||||
|
@ -3,6 +3,7 @@ package net.corda.node.services.persistence
|
|||||||
import net.corda.core.concurrent.CordaFuture
|
import net.corda.core.concurrent.CordaFuture
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.TransactionSignature
|
import net.corda.core.crypto.TransactionSignature
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
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.bufferUntilSubscribed
|
import net.corda.core.internal.bufferUntilSubscribed
|
||||||
@ -15,7 +16,6 @@ import net.corda.core.transactions.SignedTransaction
|
|||||||
import net.corda.node.services.api.WritableTransactionStorage
|
import net.corda.node.services.api.WritableTransactionStorage
|
||||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||||
import net.corda.node.utilities.AppendOnlyPersistentMapBase
|
import net.corda.node.utilities.AppendOnlyPersistentMapBase
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
|
||||||
import net.corda.node.utilities.WeightBasedAppendOnlyPersistentMap
|
import net.corda.node.utilities.WeightBasedAppendOnlyPersistentMap
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
||||||
|
@ -19,7 +19,6 @@ 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.NamedCacheFactory
|
|
||||||
import net.corda.node.utilities.NonInvalidatingCache
|
import net.corda.node.utilities.NonInvalidatingCache
|
||||||
import net.corda.node.utilities.NonInvalidatingWeightBasedCache
|
import net.corda.node.utilities.NonInvalidatingWeightBasedCache
|
||||||
import net.corda.nodeapi.exceptions.DuplicateAttachmentException
|
import net.corda.nodeapi.exceptions.DuplicateAttachmentException
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.corda.node.services.persistence
|
package net.corda.node.services.persistence
|
||||||
|
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
import net.corda.node.services.api.NodePropertiesStore
|
import net.corda.node.services.api.NodePropertiesStore
|
||||||
@ -17,12 +18,12 @@ import javax.persistence.Table
|
|||||||
/**
|
/**
|
||||||
* Simple node properties key value store in DB.
|
* Simple node properties key value store in DB.
|
||||||
*/
|
*/
|
||||||
class NodePropertiesPersistentStore(readPhysicalNodeId: () -> String, database: CordaPersistence) : NodePropertiesStore {
|
class NodePropertiesPersistentStore(readPhysicalNodeId: () -> String, database: CordaPersistence, cacheFactory: NamedCacheFactory) : NodePropertiesStore {
|
||||||
private companion object {
|
private companion object {
|
||||||
val logger = contextLogger()
|
val logger = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val flowsDrainingMode = FlowsDrainingModeOperationsImpl(readPhysicalNodeId, database, logger)
|
override val flowsDrainingMode = FlowsDrainingModeOperationsImpl(readPhysicalNodeId, database, logger, cacheFactory)
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
flowsDrainingMode.map.preload()
|
flowsDrainingMode.map.preload()
|
||||||
@ -40,7 +41,7 @@ class NodePropertiesPersistentStore(readPhysicalNodeId: () -> String, database:
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FlowsDrainingModeOperationsImpl(readPhysicalNodeId: () -> String, private val persistence: CordaPersistence, logger: Logger) : FlowsDrainingModeOperations {
|
class FlowsDrainingModeOperationsImpl(readPhysicalNodeId: () -> String, private val persistence: CordaPersistence, logger: Logger, cacheFactory: NamedCacheFactory) : FlowsDrainingModeOperations {
|
||||||
private val nodeSpecificFlowsExecutionModeKey = "${readPhysicalNodeId()}_flowsExecutionMode"
|
private val nodeSpecificFlowsExecutionModeKey = "${readPhysicalNodeId()}_flowsExecutionMode"
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -52,7 +53,8 @@ class FlowsDrainingModeOperationsImpl(readPhysicalNodeId: () -> String, private
|
|||||||
{ key -> key },
|
{ key -> key },
|
||||||
{ entity -> entity.key to entity.value!! },
|
{ entity -> entity.key to entity.value!! },
|
||||||
NodePropertiesPersistentStore::DBNodeProperty,
|
NodePropertiesPersistentStore::DBNodeProperty,
|
||||||
NodePropertiesPersistentStore.DBNodeProperty::class.java
|
NodePropertiesPersistentStore.DBNodeProperty::class.java,
|
||||||
|
cacheFactory
|
||||||
)
|
)
|
||||||
|
|
||||||
override val values = PublishSubject.create<Pair<Boolean, Boolean>>()!!
|
override val values = PublishSubject.create<Pair<Boolean, Boolean>>()!!
|
||||||
|
@ -9,6 +9,7 @@ import net.corda.core.flows.NotarisationRequestSignature
|
|||||||
import net.corda.core.flows.NotaryError
|
import net.corda.core.flows.NotaryError
|
||||||
import net.corda.core.flows.StateConsumptionDetails
|
import net.corda.core.flows.StateConsumptionDetails
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
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.internal.notary.AsyncUniquenessProvider
|
import net.corda.core.internal.notary.AsyncUniquenessProvider
|
||||||
@ -22,7 +23,6 @@ import net.corda.core.serialization.serialize
|
|||||||
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.NamedCacheFactory
|
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
||||||
import net.corda.nodeapi.internal.persistence.currentDBSession
|
import net.corda.nodeapi.internal.persistence.currentDBSession
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.node.services.upgrade
|
|||||||
|
|
||||||
import net.corda.core.contracts.StateRef
|
import net.corda.core.contracts.StateRef
|
||||||
import net.corda.core.contracts.UpgradedContract
|
import net.corda.core.contracts.UpgradedContract
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
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.PersistentMap
|
import net.corda.node.utilities.PersistentMap
|
||||||
@ -11,7 +12,7 @@ import javax.persistence.Entity
|
|||||||
import javax.persistence.Id
|
import javax.persistence.Id
|
||||||
import javax.persistence.Table
|
import javax.persistence.Table
|
||||||
|
|
||||||
class ContractUpgradeServiceImpl : ContractUpgradeService, SingletonSerializeAsToken() {
|
class ContractUpgradeServiceImpl(cacheFactory: NamedCacheFactory) : ContractUpgradeService, SingletonSerializeAsToken() {
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "${NODE_DATABASE_PREFIX}contract_upgrades")
|
@Table(name = "${NODE_DATABASE_PREFIX}contract_upgrades")
|
||||||
@ -26,7 +27,7 @@ class ContractUpgradeServiceImpl : ContractUpgradeService, SingletonSerializeAsT
|
|||||||
)
|
)
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
fun createContractUpgradesMap(): PersistentMap<String, String, DBContractUpgrade, String> {
|
fun createContractUpgradesMap(cacheFactory: NamedCacheFactory): PersistentMap<String, String, DBContractUpgrade, String> {
|
||||||
return PersistentMap(
|
return PersistentMap(
|
||||||
"ContractUpgradeService_upgrades",
|
"ContractUpgradeService_upgrades",
|
||||||
toPersistentEntityKey = { it },
|
toPersistentEntityKey = { it },
|
||||||
@ -37,12 +38,13 @@ class ContractUpgradeServiceImpl : ContractUpgradeService, SingletonSerializeAsT
|
|||||||
upgradedContractClassName = value
|
upgradedContractClassName = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
persistentEntityClass = DBContractUpgrade::class.java
|
persistentEntityClass = DBContractUpgrade::class.java,
|
||||||
|
cacheFactory = cacheFactory
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val authorisedUpgrade = createContractUpgradesMap()
|
private val authorisedUpgrade = createContractUpgradesMap(cacheFactory)
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
authorisedUpgrade.preload()
|
authorisedUpgrade.preload()
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.node.utilities
|
|||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
import com.github.benmanes.caffeine.cache.Weigher
|
import com.github.benmanes.caffeine.cache.Weigher
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseTransaction
|
import net.corda.nodeapi.internal.persistence.DatabaseTransaction
|
||||||
import net.corda.nodeapi.internal.persistence.contextTransaction
|
import net.corda.nodeapi.internal.persistence.contextTransaction
|
||||||
@ -12,7 +13,6 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a caching layer on top of an *append-only* table accessed via Hibernate mapping. Note that if the same key is [set] twice,
|
* Implements a caching layer on top of an *append-only* table accessed via Hibernate mapping. Note that if the same key is [set] twice,
|
||||||
* typically this will result in a duplicate insert if this is racing with another transaction. The flow framework will then retry.
|
* typically this will result in a duplicate insert if this is racing with another transaction. The flow framework will then retry.
|
||||||
|
@ -5,50 +5,77 @@ import com.github.benmanes.caffeine.cache.Cache
|
|||||||
import com.github.benmanes.caffeine.cache.CacheLoader
|
import com.github.benmanes.caffeine.cache.CacheLoader
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
import net.corda.core.internal.buildNamed
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow passing metrics and config to caching implementations.
|
* Allow passing metrics and config to caching implementations. This is needs to be distinct from [NamedCacheFactory]
|
||||||
|
* to avoid deterministic serialization from seeing metrics and config on method signatures.
|
||||||
*/
|
*/
|
||||||
interface NamedCacheFactory : SerializeAsToken {
|
interface BindableNamedCacheFactory : NamedCacheFactory, SerializeAsToken {
|
||||||
/**
|
/**
|
||||||
* Build a new cache factory of the same type that incorporates metrics.
|
* Build a new cache factory of the same type that incorporates metrics.
|
||||||
*/
|
*/
|
||||||
fun bindWithMetrics(metricRegistry: MetricRegistry): NamedCacheFactory
|
fun bindWithMetrics(metricRegistry: MetricRegistry): BindableNamedCacheFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a new cache factory of the same type that incorporates the associated configuration.
|
* Build a new cache factory of the same type that incorporates the associated configuration.
|
||||||
*/
|
*/
|
||||||
fun bindWithConfig(nodeConfiguration: NodeConfiguration): NamedCacheFactory
|
fun bindWithConfig(nodeConfiguration: NodeConfiguration): BindableNamedCacheFactory
|
||||||
|
|
||||||
fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V>
|
|
||||||
fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultNamedCacheFactory private constructor(private val metricRegistry: MetricRegistry?, private val nodeConfiguration: NodeConfiguration?) : NamedCacheFactory, SingletonSerializeAsToken() {
|
open class DefaultNamedCacheFactory private constructor(private val metricRegistry: MetricRegistry?, private val nodeConfiguration: NodeConfiguration?) : BindableNamedCacheFactory, SingletonSerializeAsToken() {
|
||||||
constructor() : this(null, null)
|
constructor() : this(null, null)
|
||||||
|
|
||||||
override fun bindWithMetrics(metricRegistry: MetricRegistry): NamedCacheFactory = DefaultNamedCacheFactory(metricRegistry, this.nodeConfiguration)
|
override fun bindWithMetrics(metricRegistry: MetricRegistry): BindableNamedCacheFactory = DefaultNamedCacheFactory(metricRegistry, this.nodeConfiguration)
|
||||||
override fun bindWithConfig(nodeConfiguration: NodeConfiguration): NamedCacheFactory = DefaultNamedCacheFactory(this.metricRegistry, nodeConfiguration)
|
override fun bindWithConfig(nodeConfiguration: NodeConfiguration): BindableNamedCacheFactory = DefaultNamedCacheFactory(this.metricRegistry, nodeConfiguration)
|
||||||
|
|
||||||
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V> {
|
protected fun <K, V> configuredForNamed(caffeine: Caffeine<K, V>, name: String): Caffeine<K, V> {
|
||||||
|
return with(nodeConfiguration!!) {
|
||||||
|
when {
|
||||||
|
name.startsWith("RPCSecurityManagerShiroCache_") -> with(security?.authService?.options?.cache!!) { caffeine.maximumSize(maxEntries).expireAfterWrite(expireAfterSecs, TimeUnit.SECONDS) }
|
||||||
|
name == "RPCServer_observableSubscription" -> caffeine
|
||||||
|
name == "RpcClientProxyHandler_rpcObservable" -> caffeine
|
||||||
|
name == "SerializationScheme_attachmentClassloader" -> caffeine
|
||||||
|
name == "HibernateConfiguration_sessionFactories" -> caffeine.maximumSize(database.mappedSchemaCacheSize)
|
||||||
|
name == "DBTransactionStorage_transactions" -> caffeine.maximumWeight(transactionCacheSizeBytes)
|
||||||
|
name == "NodeAttachmentService_attachmentContent" -> caffeine.maximumWeight(attachmentContentCacheSizeBytes)
|
||||||
|
name == "NodeAttachmentService_attachmentPresence" -> caffeine.maximumSize(attachmentCacheBound)
|
||||||
|
name == "PersistentIdentityService_partyByKey" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "PersistentIdentityService_partyByName" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "PersistentNetworkMap_nodesByKey" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "PersistentNetworkMap_idByLegalName" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "PersistentKeyManagementService_keys" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "FlowDrainingMode_nodeProperties" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "ContractUpgradeService_upgrades" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "PersistentUniquenessProvider_transactions" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "P2PMessageDeduplicator_processedMessages" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "DeduplicationChecker_watermark" -> caffeine
|
||||||
|
name == "BFTNonValidatingNotaryService_transactions" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "RaftUniquenessProvider_transactions" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
else -> throw IllegalArgumentException("Unexpected cache name $name. Did you add a new cache?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun checkState(name: String) {
|
||||||
|
checkCacheName(name)
|
||||||
checkNotNull(metricRegistry)
|
checkNotNull(metricRegistry)
|
||||||
checkNotNull(nodeConfiguration)
|
checkNotNull(nodeConfiguration)
|
||||||
return caffeine.maximumSize(1024).buildNamed<K, V>(name)
|
}
|
||||||
|
|
||||||
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V> {
|
||||||
|
checkState(name)
|
||||||
|
return configuredForNamed(caffeine, name).build<K, V>()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V> {
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V> {
|
||||||
checkNotNull(metricRegistry)
|
checkState(name)
|
||||||
checkNotNull(nodeConfiguration)
|
return configuredForNamed(caffeine, name).build<K, V>(loader)
|
||||||
val configuredCaffeine = when (name) {
|
|
||||||
"DBTransactionStorage_transactions" -> caffeine.maximumWeight(nodeConfiguration!!.transactionCacheSizeBytes)
|
|
||||||
"NodeAttachmentService_attachmentContent" -> caffeine.maximumWeight(nodeConfiguration!!.attachmentContentCacheSizeBytes)
|
|
||||||
"NodeAttachmentService_attachmentPresence" -> caffeine.maximumSize(nodeConfiguration!!.attachmentCacheBound)
|
|
||||||
else -> caffeine.maximumSize(1024)
|
|
||||||
}
|
|
||||||
return configuredCaffeine.buildNamed<K, V>(name, loader)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected val defaultCacheSize = 1024L
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import com.github.benmanes.caffeine.cache.CacheLoader
|
|||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
import com.github.benmanes.caffeine.cache.Weigher
|
import com.github.benmanes.caffeine.cache.Weigher
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
|
|
||||||
class NonInvalidatingCache<K, V> private constructor(
|
class NonInvalidatingCache<K, V> private constructor(
|
||||||
val cache: LoadingCache<K, V>
|
val cache: LoadingCache<K, V>
|
||||||
|
@ -5,21 +5,21 @@ import com.github.benmanes.caffeine.cache.CacheLoader
|
|||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
import com.github.benmanes.caffeine.cache.RemovalListener
|
import com.github.benmanes.caffeine.cache.RemovalListener
|
||||||
import net.corda.core.internal.buildNamed
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
|
|
||||||
class NonInvalidatingUnboundCache<K, V> private constructor(
|
class NonInvalidatingUnboundCache<K, V> private constructor(
|
||||||
val cache: LoadingCache<K, V>
|
val cache: LoadingCache<K, V>
|
||||||
) : LoadingCache<K, V> by cache {
|
) : LoadingCache<K, V> by cache {
|
||||||
|
|
||||||
constructor(name: String, loadFunction: (K) -> V, removalListener: RemovalListener<K, V> = RemovalListener { _, _, _ -> },
|
constructor(name: String, cacheFactory: NamedCacheFactory, loadFunction: (K) -> V, removalListener: RemovalListener<K, V> = RemovalListener { _, _, _ -> },
|
||||||
keysToPreload: () -> Iterable<K> = { emptyList() }) :
|
keysToPreload: () -> Iterable<K> = { emptyList() }) :
|
||||||
this(buildCache(name, loadFunction, removalListener, keysToPreload))
|
this(buildCache(name, cacheFactory, loadFunction, removalListener, keysToPreload))
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
private fun <K, V> buildCache(name: String, loadFunction: (K) -> V, removalListener: RemovalListener<K, V>,
|
private fun <K, V> buildCache(name: String, cacheFactory: NamedCacheFactory, loadFunction: (K) -> V, removalListener: RemovalListener<K, V>,
|
||||||
keysToPreload: () -> Iterable<K>): LoadingCache<K, V> {
|
keysToPreload: () -> Iterable<K>): LoadingCache<K, V> {
|
||||||
val builder = Caffeine.newBuilder().removalListener(removalListener).executor(SameThreadExecutor.getExecutor())
|
val builder = Caffeine.newBuilder().removalListener(removalListener).executor(SameThreadExecutor.getExecutor())
|
||||||
return builder.buildNamed(name, NonInvalidatingCacheLoader(loadFunction)).apply {
|
return cacheFactory.buildNamed(builder, name, NonInvalidatingCacheLoader(loadFunction)).apply {
|
||||||
getAll(keysToPreload())
|
getAll(keysToPreload())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.node.utilities
|
|||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.RemovalCause
|
import com.github.benmanes.caffeine.cache.RemovalCause
|
||||||
import com.github.benmanes.caffeine.cache.RemovalListener
|
import com.github.benmanes.caffeine.cache.RemovalListener
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.nodeapi.internal.persistence.currentDBSession
|
import net.corda.nodeapi.internal.persistence.currentDBSession
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -14,7 +15,8 @@ class PersistentMap<K : Any, V, E, out EK>(
|
|||||||
val toPersistentEntityKey: (K) -> EK,
|
val toPersistentEntityKey: (K) -> EK,
|
||||||
val fromPersistentEntity: (E) -> Pair<K, V>,
|
val fromPersistentEntity: (E) -> Pair<K, V>,
|
||||||
val toPersistentEntity: (key: K, value: V) -> E,
|
val toPersistentEntity: (key: K, value: V) -> E,
|
||||||
val persistentEntityClass: Class<E>
|
val persistentEntityClass: Class<E>,
|
||||||
|
cacheFactory: NamedCacheFactory
|
||||||
) : MutableMap<K, V>, AbstractMap<K, V>() {
|
) : MutableMap<K, V>, AbstractMap<K, V>() {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
@ -24,7 +26,8 @@ class PersistentMap<K : Any, V, E, out EK>(
|
|||||||
private val cache = NonInvalidatingUnboundCache(
|
private val cache = NonInvalidatingUnboundCache(
|
||||||
name,
|
name,
|
||||||
loadFunction = { key -> Optional.ofNullable(loadValue(key)) },
|
loadFunction = { key -> Optional.ofNullable(loadValue(key)) },
|
||||||
removalListener = ExplicitRemoval(toPersistentEntityKey, persistentEntityClass)
|
removalListener = ExplicitRemoval(toPersistentEntityKey, persistentEntityClass),
|
||||||
|
cacheFactory = cacheFactory
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Preload to allow [all] to take data only from the cache (cache is unbound) */
|
/** Preload to allow [all] to take data only from the cache (cache is unbound) */
|
||||||
|
@ -38,10 +38,11 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.expect
|
import net.corda.testing.core.expect
|
||||||
import net.corda.testing.core.expectEvents
|
import net.corda.testing.core.expectEvents
|
||||||
import net.corda.testing.core.sequence
|
import net.corda.testing.core.sequence
|
||||||
import net.corda.testing.node.internal.cordappsForPackages
|
import net.corda.testing.internal.fromUserList
|
||||||
import net.corda.testing.node.internal.InternalMockNetwork
|
import net.corda.testing.node.internal.InternalMockNetwork
|
||||||
import net.corda.testing.node.internal.InternalMockNodeParameters
|
import net.corda.testing.node.internal.InternalMockNodeParameters
|
||||||
import net.corda.testing.node.internal.TestStartedNode
|
import net.corda.testing.node.internal.TestStartedNode
|
||||||
|
import net.corda.testing.node.internal.cordappsForPackages
|
||||||
import net.corda.testing.node.testActor
|
import net.corda.testing.node.testActor
|
||||||
import org.apache.commons.io.IOUtils
|
import org.apache.commons.io.IOUtils
|
||||||
import org.assertj.core.api.Assertions.*
|
import org.assertj.core.api.Assertions.*
|
||||||
|
@ -7,7 +7,7 @@ import net.corda.core.utilities.contextLogger
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.testing.common.internal.relaxedThoroughness
|
import net.corda.testing.common.internal.relaxedThoroughness
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.internal.ProcessUtilities.startJavaProcess
|
import net.corda.testing.node.internal.ProcessUtilities.startJavaProcess
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
@ -18,6 +18,7 @@ import net.corda.nodeapi.internal.persistence.CordaPersistence
|
|||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.testing.core.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.createNodeInfoAndSigned
|
import net.corda.testing.internal.createNodeInfoAndSigned
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
|
@ -9,6 +9,8 @@ import net.corda.node.internal.security.tryAuthenticate
|
|||||||
import net.corda.node.services.Permissions.Companion.invokeRpc
|
import net.corda.node.services.Permissions.Companion.invokeRpc
|
||||||
import net.corda.node.services.config.SecurityConfiguration
|
import net.corda.node.services.config.SecurityConfiguration
|
||||||
import net.corda.nodeapi.internal.config.User
|
import net.corda.nodeapi.internal.config.User
|
||||||
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
|
import net.corda.testing.internal.fromUserList
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import javax.security.auth.login.FailedLoginException
|
import javax.security.auth.login.FailedLoginException
|
||||||
@ -134,7 +136,7 @@ class RPCSecurityManagerTest {
|
|||||||
|
|
||||||
private fun checkUserActions(permissions: Set<String>, permitted: Set<ArrayList<String>>) {
|
private fun checkUserActions(permissions: Set<String>, permitted: Set<ArrayList<String>>) {
|
||||||
val user = User(username = "user", password = "password", permissions = permissions)
|
val user = User(username = "user", password = "password", permissions = permissions)
|
||||||
val userRealms = RPCSecurityManagerImpl(SecurityConfiguration.AuthService.fromUsers(listOf(user)))
|
val userRealms = RPCSecurityManagerImpl(SecurityConfiguration.AuthService.fromUsers(listOf(user)), TestingNamedCacheFactory())
|
||||||
val disabled = allActions.filter { !permitted.contains(listOf(it)) }
|
val disabled = allActions.filter { !permitted.contains(listOf(it)) }
|
||||||
for (subject in listOf(
|
for (subject in listOf(
|
||||||
userRealms.authenticate("user", Password("password")),
|
userRealms.authenticate("user", Password("password")),
|
||||||
|
@ -10,13 +10,13 @@ import net.corda.core.internal.FlowStateMachine
|
|||||||
import net.corda.core.internal.concurrent.openFuture
|
import net.corda.core.internal.concurrent.openFuture
|
||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.api.FlowStarter
|
import net.corda.node.services.api.FlowStarter
|
||||||
import net.corda.node.services.api.NodePropertiesStore
|
import net.corda.node.services.api.NodePropertiesStore
|
||||||
import net.corda.node.services.messaging.DeduplicationHandler
|
import net.corda.node.services.messaging.DeduplicationHandler
|
||||||
import net.corda.node.services.statemachine.ExternalEvent
|
import net.corda.node.services.statemachine.ExternalEvent
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.doLookup
|
import net.corda.testing.internal.doLookup
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.spectator
|
import net.corda.testing.internal.spectator
|
||||||
|
@ -4,9 +4,8 @@ import net.corda.core.contracts.ScheduledStateRef
|
|||||||
import net.corda.core.contracts.StateRef
|
import net.corda.core.contracts.StateRef
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
@ -7,7 +7,6 @@ import net.corda.core.identity.CordaX500Name
|
|||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
import net.corda.core.node.services.UnknownAnonymousPartyException
|
import net.corda.core.node.services.UnknownAnonymousPartyException
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
@ -17,6 +16,7 @@ import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
|||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.internal.DEV_INTERMEDIATE_CA
|
import net.corda.testing.internal.DEV_INTERMEDIATE_CA
|
||||||
import net.corda.testing.internal.DEV_ROOT_CA
|
import net.corda.testing.internal.DEV_ROOT_CA
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import net.corda.testing.node.makeTestIdentityService
|
import net.corda.testing.node.makeTestIdentityService
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
|
@ -2,11 +2,11 @@ package net.corda.node.services.persistence
|
|||||||
|
|
||||||
import net.corda.core.schemas.MappedSchema
|
import net.corda.core.schemas.MappedSchema
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import net.corda.node.utilities.AppendOnlyPersistentMap
|
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
|
@ -3,16 +3,15 @@ package net.corda.node.services.persistence
|
|||||||
import net.corda.core.context.InvocationContext
|
import net.corda.core.context.InvocationContext
|
||||||
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.serialization.internal.CheckpointSerializationDefaults
|
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
|
import net.corda.core.serialization.internal.CheckpointSerializationDefaults
|
||||||
import net.corda.core.serialization.internal.checkpointSerialize
|
import net.corda.core.serialization.internal.checkpointSerialize
|
||||||
import net.corda.node.internal.CheckpointIncompatibleException
|
import net.corda.node.internal.CheckpointIncompatibleException
|
||||||
import net.corda.node.internal.CheckpointVerifier
|
import net.corda.node.internal.CheckpointVerifier
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.api.CheckpointStorage
|
import net.corda.node.services.api.CheckpointStorage
|
||||||
import net.corda.node.services.statemachine.Checkpoint
|
import net.corda.node.services.statemachine.Checkpoint
|
||||||
import net.corda.node.services.statemachine.SubFlowVersion
|
|
||||||
import net.corda.node.services.statemachine.FlowStart
|
import net.corda.node.services.statemachine.FlowStart
|
||||||
|
import net.corda.node.services.statemachine.SubFlowVersion
|
||||||
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
@ -20,6 +19,7 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
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
|
||||||
import org.assertj.core.api.Assertions
|
import org.assertj.core.api.Assertions
|
||||||
|
@ -7,13 +7,13 @@ import net.corda.core.crypto.SignatureMetadata
|
|||||||
import net.corda.core.crypto.TransactionSignature
|
import net.corda.core.crypto.TransactionSignature
|
||||||
import net.corda.core.toFuture
|
import net.corda.core.toFuture
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.createWireTransaction
|
import net.corda.testing.internal.createWireTransaction
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
@ -29,7 +29,6 @@ import net.corda.finance.schemas.test.SampleCashSchemaV1
|
|||||||
import net.corda.finance.schemas.test.SampleCashSchemaV2
|
import net.corda.finance.schemas.test.SampleCashSchemaV2
|
||||||
import net.corda.finance.schemas.test.SampleCashSchemaV3
|
import net.corda.finance.schemas.test.SampleCashSchemaV3
|
||||||
import net.corda.finance.utils.sumCash
|
import net.corda.finance.utils.sumCash
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.api.IdentityServiceInternal
|
import net.corda.node.services.api.IdentityServiceInternal
|
||||||
import net.corda.node.services.api.WritableTransactionStorage
|
import net.corda.node.services.api.WritableTransactionStorage
|
||||||
import net.corda.node.services.schema.ContractStateAndRef
|
import net.corda.node.services.schema.ContractStateAndRef
|
||||||
@ -41,6 +40,7 @@ import net.corda.nodeapi.internal.persistence.CordaPersistence
|
|||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
|
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.vault.DummyDealStateSchemaV1
|
import net.corda.testing.internal.vault.DummyDealStateSchemaV1
|
||||||
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
|
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
|
||||||
|
@ -13,12 +13,12 @@ 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.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import net.corda.testing.node.internal.InternalMockNetwork
|
import net.corda.testing.node.internal.InternalMockNetwork
|
||||||
import net.corda.testing.node.internal.startFlow
|
import net.corda.testing.node.internal.startFlow
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.corda.node.services.persistence
|
package net.corda.node.services.persistence
|
||||||
|
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
@ -7,24 +7,21 @@ import net.corda.core.contracts.TransactionState
|
|||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.identity.AbstractParty
|
import net.corda.core.identity.AbstractParty
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.node.services.Vault
|
|
||||||
import net.corda.core.schemas.MappedSchema
|
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.internal.configureDatabase
|
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.nodeapi.internal.persistence.currentDBSession
|
import net.corda.nodeapi.internal.persistence.currentDBSession
|
||||||
import net.corda.testing.internal.LogHelper
|
|
||||||
import net.corda.testing.core.TestIdentity
|
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
|
import net.corda.testing.core.TestIdentity
|
||||||
|
import net.corda.testing.internal.LogHelper
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Ignore
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import rx.subjects.PublishSubject
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class PersistentStateServiceTests {
|
class PersistentStateServiceTests {
|
||||||
|
@ -8,7 +8,6 @@ import net.corda.core.flows.NotarisationRequestSignature
|
|||||||
import net.corda.core.flows.NotaryError
|
import net.corda.core.flows.NotaryError
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.notary.NotaryInternalException
|
import net.corda.core.internal.notary.NotaryInternalException
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
@ -17,6 +16,7 @@ import net.corda.testing.core.SerializationEnvironmentRule
|
|||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.core.generateStateRef
|
import net.corda.testing.core.generateStateRef
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
@ -24,13 +24,13 @@ import net.corda.finance.schemas.CashSchemaV1.PersistentCashState
|
|||||||
import net.corda.finance.schemas.CommercialPaperSchemaV1
|
import net.corda.finance.schemas.CommercialPaperSchemaV1
|
||||||
import net.corda.finance.schemas.test.SampleCashSchemaV2
|
import net.corda.finance.schemas.test.SampleCashSchemaV2
|
||||||
import net.corda.finance.schemas.test.SampleCashSchemaV3
|
import net.corda.finance.schemas.test.SampleCashSchemaV3
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseTransaction
|
import net.corda.nodeapi.internal.persistence.DatabaseTransaction
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.internal.TEST_TX_TIME
|
import net.corda.testing.internal.TEST_TX_TIME
|
||||||
import net.corda.testing.internal.chooseIdentity
|
import net.corda.testing.internal.chooseIdentity
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.vault.*
|
import net.corda.testing.internal.vault.*
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
|
@ -3,8 +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.internal.configureDatabase
|
|
||||||
import net.corda.nodeapi.internal.persistence.*
|
import net.corda.nodeapi.internal.persistence.*
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package net.corda.node.utilities
|
package net.corda.node.utilities
|
||||||
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.services.upgrade.ContractUpgradeServiceImpl
|
import net.corda.node.services.upgrade.ContractUpgradeServiceImpl
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@ -25,7 +26,8 @@ class PersistentMapTests {
|
|||||||
upgradedContractClassName = value
|
upgradedContractClassName = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
persistentEntityClass = ContractUpgradeServiceImpl.DBContractUpgrade::class.java
|
persistentEntityClass = ContractUpgradeServiceImpl.DBContractUpgrade::class.java,
|
||||||
|
cacheFactory = TestingNamedCacheFactory()
|
||||||
).apply { preload() }
|
).apply { preload() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,13 +10,14 @@ import net.corda.finance.DOLLARS
|
|||||||
import net.corda.finance.contracts.Fix
|
import net.corda.finance.contracts.Fix
|
||||||
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.node.internal.configureDatabase
|
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.node.*
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
|
import net.corda.testing.node.createMockCordaService
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
@ -6,7 +6,6 @@ import net.corda.core.DeleteForDJVM
|
|||||||
import net.corda.core.KeepForDJVM
|
import net.corda.core.KeepForDJVM
|
||||||
import net.corda.core.contracts.Attachment
|
import net.corda.core.contracts.Attachment
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.internal.buildNamed
|
|
||||||
import net.corda.core.internal.copyBytes
|
import net.corda.core.internal.copyBytes
|
||||||
import net.corda.core.serialization.*
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.utilities.ByteSequence
|
import net.corda.core.utilities.ByteSequence
|
||||||
@ -77,7 +76,7 @@ data class SerializationContextImpl @JvmOverloads constructor(override val prefe
|
|||||||
*/
|
*/
|
||||||
@DeleteForDJVM
|
@DeleteForDJVM
|
||||||
internal class AttachmentsClassLoaderBuilder(private val properties: Map<Any, Any>, private val deserializationClassLoader: ClassLoader) {
|
internal class AttachmentsClassLoaderBuilder(private val properties: Map<Any, Any>, private val deserializationClassLoader: ClassLoader) {
|
||||||
private val cache: Cache<List<SecureHash>, AttachmentsClassLoader> = Caffeine.newBuilder().weakValues().maximumSize(1024).buildNamed("SerializationScheme_attachmentClassloader")
|
private val cache: Cache<List<SecureHash>, AttachmentsClassLoader> = Caffeine.newBuilder().weakValues().maximumSize(1024).build()
|
||||||
|
|
||||||
fun build(attachmentHashes: List<SecureHash>): AttachmentsClassLoader? {
|
fun build(attachmentHashes: List<SecureHash>): AttachmentsClassLoader? {
|
||||||
val serializationContext = properties[serializationContextKey] as? SerializeAsTokenContext ?: return null // Some tests don't set one.
|
val serializationContext = properties[serializationContextKey] as? SerializeAsTokenContext ?: return null // Some tests don't set one.
|
||||||
|
@ -21,7 +21,6 @@ import net.corda.core.utilities.NetworkHostAndPort
|
|||||||
import net.corda.node.VersionInfo
|
import net.corda.node.VersionInfo
|
||||||
import net.corda.node.cordapp.CordappLoader
|
import net.corda.node.cordapp.CordappLoader
|
||||||
import net.corda.node.internal.ServicesForResolutionImpl
|
import net.corda.node.internal.ServicesForResolutionImpl
|
||||||
import net.corda.node.internal.configureDatabase
|
|
||||||
import net.corda.node.internal.cordapp.JarScanningCordappLoader
|
import net.corda.node.internal.cordapp.JarScanningCordappLoader
|
||||||
import net.corda.node.services.api.*
|
import net.corda.node.services.api.*
|
||||||
import net.corda.node.services.identity.InMemoryIdentityService
|
import net.corda.node.services.identity.InMemoryIdentityService
|
||||||
@ -34,6 +33,7 @@ import net.corda.testing.common.internal.testNetworkParameters
|
|||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.internal.DEV_ROOT_CA
|
import net.corda.testing.internal.DEV_ROOT_CA
|
||||||
import net.corda.testing.internal.MockCordappProvider
|
import net.corda.testing.internal.MockCordappProvider
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.*
|
||||||
import net.corda.testing.services.MockAttachmentStorage
|
import net.corda.testing.services.MockAttachmentStorage
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
|
@ -24,12 +24,14 @@ import net.corda.node.services.messaging.RPCServerConfiguration
|
|||||||
import net.corda.nodeapi.RPCApi
|
import net.corda.nodeapi.RPCApi
|
||||||
import net.corda.nodeapi.internal.ArtemisTcpTransport
|
import net.corda.nodeapi.internal.ArtemisTcpTransport
|
||||||
import net.corda.serialization.internal.AMQP_RPC_CLIENT_CONTEXT
|
import net.corda.serialization.internal.AMQP_RPC_CLIENT_CONTEXT
|
||||||
import net.corda.testing.node.TestCordapp
|
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
import net.corda.testing.driver.JmxPolicy
|
import net.corda.testing.driver.JmxPolicy
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
|
import net.corda.testing.internal.fromUserList
|
||||||
import net.corda.testing.node.NotarySpec
|
import net.corda.testing.node.NotarySpec
|
||||||
|
import net.corda.testing.node.TestCordapp
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import net.corda.testing.node.internal.DriverDSLImpl.Companion.cordappsInCurrentAndAdditionalPackages
|
import net.corda.testing.node.internal.DriverDSLImpl.Companion.cordappsInCurrentAndAdditionalPackages
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
@ -485,7 +487,8 @@ data class RPCDriverDSL(
|
|||||||
locator,
|
locator,
|
||||||
rpcSecurityManager,
|
rpcSecurityManager,
|
||||||
nodeLegalName,
|
nodeLegalName,
|
||||||
configuration
|
configuration,
|
||||||
|
TestingNamedCacheFactory()
|
||||||
)
|
)
|
||||||
driverDSL.shutdownManager.registerShutdown {
|
driverDSL.shutdownManager.registerShutdown {
|
||||||
rpcServer.close(queueDrainTimeout)
|
rpcServer.close(queueDrainTimeout)
|
||||||
|
@ -1,26 +1,42 @@
|
|||||||
package net.corda.testing.internal
|
package net.corda.testing.internal
|
||||||
|
|
||||||
|
import net.corda.core.context.AuthServiceId
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.identity.AbstractParty
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
|
import net.corda.core.schemas.MappedSchema
|
||||||
import net.corda.core.transactions.WireTransaction
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
|
import net.corda.node.internal.createCordaPersistence
|
||||||
|
import net.corda.node.internal.security.RPCSecurityManagerImpl
|
||||||
|
import net.corda.node.internal.startHikariPool
|
||||||
|
import net.corda.node.services.api.SchemaService
|
||||||
|
import net.corda.node.services.config.SecurityConfiguration
|
||||||
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import net.corda.nodeapi.BrokerRpcSslOptions
|
import net.corda.nodeapi.BrokerRpcSslOptions
|
||||||
import net.corda.nodeapi.internal.config.MutualSslConfiguration
|
import net.corda.nodeapi.internal.config.MutualSslConfiguration
|
||||||
import net.corda.nodeapi.internal.registerDevP2pCertificates
|
import net.corda.nodeapi.internal.config.User
|
||||||
import net.corda.nodeapi.internal.createDevNodeCa
|
import net.corda.nodeapi.internal.createDevNodeCa
|
||||||
import net.corda.nodeapi.internal.crypto.*
|
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||||
|
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
import net.corda.nodeapi.internal.loadDevCaTrustStore
|
import net.corda.nodeapi.internal.loadDevCaTrustStore
|
||||||
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
|
import net.corda.nodeapi.internal.registerDevP2pCertificates
|
||||||
import net.corda.serialization.internal.amqp.AMQP_ENABLED
|
import net.corda.serialization.internal.amqp.AMQP_ENABLED
|
||||||
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
|
import java.util.*
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@ -136,3 +152,24 @@ fun createWireTransaction(inputs: List<StateRef>,
|
|||||||
val componentGroups = WireTransaction.createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow)
|
val componentGroups = WireTransaction.createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow)
|
||||||
return WireTransaction(componentGroups, privacySalt)
|
return WireTransaction(componentGroups, privacySalt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate RPCSecurityManager initialised with users data from a list of [User]
|
||||||
|
*/
|
||||||
|
fun RPCSecurityManagerImpl.Companion.fromUserList(id: AuthServiceId, users: List<User>) =
|
||||||
|
RPCSecurityManagerImpl(SecurityConfiguration.AuthService.fromUsers(users).copy(id = id), TestingNamedCacheFactory())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method for configuring a database for some tests.
|
||||||
|
*/
|
||||||
|
fun configureDatabase(hikariProperties: Properties,
|
||||||
|
databaseConfig: DatabaseConfig,
|
||||||
|
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
|
||||||
|
wellKnownPartyFromAnonymous: (AbstractParty) -> Party?,
|
||||||
|
schemaService: SchemaService = NodeSchemaService(),
|
||||||
|
internalSchemas: Set<MappedSchema> = NodeSchemaService().internalSchemas(),
|
||||||
|
cacheFactory: NamedCacheFactory = TestingNamedCacheFactory()): CordaPersistence {
|
||||||
|
val persistence = createCordaPersistence(databaseConfig, wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous, schemaService, hikariProperties, cacheFactory)
|
||||||
|
persistence.startHikariPool(hikariProperties, databaseConfig, internalSchemas)
|
||||||
|
return persistence
|
||||||
|
}
|
@ -5,21 +5,20 @@ import com.github.benmanes.caffeine.cache.Cache
|
|||||||
import com.github.benmanes.caffeine.cache.CacheLoader
|
import com.github.benmanes.caffeine.cache.CacheLoader
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||||
import net.corda.core.internal.buildNamed
|
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.node.services.config.MB
|
import net.corda.node.services.config.MB
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
import net.corda.node.utilities.NamedCacheFactory
|
import net.corda.node.utilities.BindableNamedCacheFactory
|
||||||
|
|
||||||
class TestingNamedCacheFactory private constructor(private val sizeOverride: Long, private val metricRegistry: MetricRegistry?, private val nodeConfiguration: NodeConfiguration?) : NamedCacheFactory, SingletonSerializeAsToken() {
|
class TestingNamedCacheFactory private constructor(private val sizeOverride: Long, private val metricRegistry: MetricRegistry?, private val nodeConfiguration: NodeConfiguration?) : BindableNamedCacheFactory, SingletonSerializeAsToken() {
|
||||||
constructor(sizeOverride: Long = 1024) : this(sizeOverride, null, null)
|
constructor(sizeOverride: Long = 1024) : this(sizeOverride, null, null)
|
||||||
|
|
||||||
override fun bindWithMetrics(metricRegistry: MetricRegistry): NamedCacheFactory = TestingNamedCacheFactory(sizeOverride, metricRegistry, this.nodeConfiguration)
|
override fun bindWithMetrics(metricRegistry: MetricRegistry): BindableNamedCacheFactory = TestingNamedCacheFactory(sizeOverride, metricRegistry, this.nodeConfiguration)
|
||||||
override fun bindWithConfig(nodeConfiguration: NodeConfiguration): NamedCacheFactory = TestingNamedCacheFactory(sizeOverride, this.metricRegistry, nodeConfiguration)
|
override fun bindWithConfig(nodeConfiguration: NodeConfiguration): BindableNamedCacheFactory = TestingNamedCacheFactory(sizeOverride, this.metricRegistry, nodeConfiguration)
|
||||||
|
|
||||||
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V> {
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String): Cache<K, V> {
|
||||||
// Does not check metricRegistry or nodeConfiguration, because for tests we don't care.
|
// Does not check metricRegistry or nodeConfiguration, because for tests we don't care.
|
||||||
return caffeine.maximumSize(sizeOverride).buildNamed<K, V>(name)
|
return caffeine.maximumSize(sizeOverride).build<K, V>()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V> {
|
override fun <K, V> buildNamed(caffeine: Caffeine<in K, in V>, name: String, loader: CacheLoader<K, V>): LoadingCache<K, V> {
|
||||||
@ -29,6 +28,6 @@ class TestingNamedCacheFactory private constructor(private val sizeOverride: Lon
|
|||||||
"NodeAttachmentService_attachmentContent" -> caffeine.maximumWeight(1.MB)
|
"NodeAttachmentService_attachmentContent" -> caffeine.maximumWeight(1.MB)
|
||||||
else -> caffeine.maximumSize(sizeOverride)
|
else -> caffeine.maximumSize(sizeOverride)
|
||||||
}
|
}
|
||||||
return configuredCaffeine.buildNamed<K, V>(name, loader)
|
return configuredCaffeine.build<K, V>(loader)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,7 +14,6 @@ import javafx.scene.image.WritableImage
|
|||||||
import javafx.scene.paint.Color
|
import javafx.scene.paint.Color
|
||||||
import javafx.scene.text.TextAlignment
|
import javafx.scene.text.TextAlignment
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.internal.buildNamed
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
@ -76,7 +75,7 @@ object IdenticonRenderer {
|
|||||||
|
|
||||||
private const val renderingSize = 30.0
|
private const val renderingSize = 30.0
|
||||||
|
|
||||||
private val cache = Caffeine.newBuilder().buildNamed("IdentIconRenderer_image", CacheLoader<SecureHash, Image> { key ->
|
private val cache = Caffeine.newBuilder().build(CacheLoader<SecureHash, Image> { key ->
|
||||||
key.let { render(key.hashCode(), renderingSize) }
|
key.let { render(key.hashCode(), renderingSize) }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user