CORDA-535: Move MySQL notary into a separate module

This commit is contained in:
Andrius Dagys 2018-10-10 12:12:45 +01:00
parent 69ae8e5565
commit 504cefc6f6
18 changed files with 102 additions and 70 deletions

8
.idea/compiler.xml generated
View File

@ -195,6 +195,8 @@
<module name="loadtest_test" target="1.8" />
<module name="mock_main" target="1.8" />
<module name="mock_test" target="1.8" />
<module name="mysql_main" target="1.8" />
<module name="mysql_test" target="1.8" />
<module name="net.corda_buildSrc_main" target="1.8" />
<module name="net.corda_buildSrc_test" target="1.8" />
<module name="net.corda_canonicalizer_main" target="1.8" />
@ -229,13 +231,15 @@
<module name="notary-healthcheck-cordapp_test" target="1.8" />
<module name="notary-healthcheck_main" target="1.8" />
<module name="notary-healthcheck_test" target="1.8" />
<module name="notary-raft_main" target="1.8" />
<module name="notary-raft_test" target="1.8" />
<module name="notary_main" target="1.8" />
<module name="notary_test" target="1.8" />
<module name="notarytest_main" target="1.8" />
<module name="notarytest_test" target="1.8" />
<module name="perftestcordapp_integrationTest" target="1.8" />
<module name="perftestcordapp_main" target="1.8" />
<module name="perftestcordapp_test" target="1.8" />
<module name="notary-raft_main" target="1.8" />
<module name="notary-raft_test" target="1.8" />
<module name="publish-utils_main" target="1.8" />
<module name="publish-utils_test" target="1.8" />
<module name="qa-behave_main" target="1.8" />

View File

@ -117,7 +117,7 @@ class FlowWorkerServiceHub(override val configuration: NodeConfiguration, overri
private val metricRegistry = MetricRegistry()
override val cacheFactory = EnterpriseNamedCacheFactory(configuration.enterpriseConfiguration.getTracingConfig()).bindWithConfig(configuration).bindWithMetrics(metricRegistry).tokenize()
override val schemaService = NodeSchemaService(cordappLoader.cordappSchemas, false).tokenize()
override val schemaService = NodeSchemaService(cordappLoader.cordappSchemas).tokenize()
override val identityService = PersistentIdentityService(cacheFactory).tokenize()
override val database: CordaPersistence = createCordaPersistence(
configuration.database,

View File

@ -75,7 +75,7 @@ class RpcWorkerServiceHub(override val configuration: NodeConfiguration, overrid
private val metricRegistry = MetricRegistry()
override val cacheFactory = EnterpriseNamedCacheFactory(configuration.enterpriseConfiguration.getTracingConfig()).bindWithConfig(configuration).bindWithMetrics(metricRegistry)
override val schemaService = NodeSchemaService(cordappLoader.cordappSchemas, false)
override val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
override val identityService = PersistentIdentityService(cacheFactory)
override val database: CordaPersistence = createCordaPersistence(
configuration.database,

View File

@ -141,9 +141,6 @@ dependencies {
// For H2 database support in persistence
compile "com.h2database:h2:$h2_version"
// For the MySQLUniquenessProvider
compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.6'
// SQL connection pooling library
compile "com.zaxxer:HikariCP:${hikari_version}"

View File

@ -9,6 +9,7 @@ import net.corda.core.flows.*
import net.corda.core.internal.*
import net.corda.core.internal.cordapp.CordappImpl
import net.corda.core.internal.cordapp.CordappInfoResolver
import net.corda.core.internal.notary.AsyncCFTNotaryService
import net.corda.core.internal.notary.NotaryService
import net.corda.core.internal.notary.TrustedAuthorityNotaryService
import net.corda.core.node.services.CordaService
@ -133,7 +134,8 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
// the scanner won't find subclasses deeper down the hierarchy if any intermediate class is not
// present in the CorDapp.
val result = scanResult.getClassesWithSuperclass(NotaryService::class) +
scanResult.getClassesWithSuperclass(TrustedAuthorityNotaryService::class)
scanResult.getClassesWithSuperclass(TrustedAuthorityNotaryService::class) +
scanResult.getClassesWithSuperclass(AsyncCFTNotaryService::class)
logger.info("Found notary service CorDapp implementations: " + result.joinToString(", "))
return result.firstOrNull()
}

View File

@ -1,45 +0,0 @@
package net.corda.node.services.transactions
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.internal.notary.AsyncCFTNotaryService
import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.config.MySQLConfiguration
import java.security.PublicKey
/** Notary service backed by a replicated MySQL database. */
abstract class MySQLNotaryService(
final override val services: ServiceHubInternal,
override val notaryIdentityKey: PublicKey,
configuration: MySQLConfiguration,
/** Database table will be automatically created in dev mode */
val devMode: Boolean) : AsyncCFTNotaryService() {
override val asyncUniquenessProvider = MySQLUniquenessProvider(
services.monitoringService.metrics,
services.clock,
configuration
)
override fun start() {
if (devMode) asyncUniquenessProvider.createTable()
}
override fun stop() {
asyncUniquenessProvider.stop()
}
}
class MySQLNonValidatingNotaryService(services: ServiceHubInternal,
notaryIdentityKey: PublicKey,
configuration: MySQLConfiguration,
devMode: Boolean = false) : MySQLNotaryService(services, notaryIdentityKey, configuration, devMode) {
override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic<Void?> = NonValidatingNotaryFlow(otherPartySession, this)
}
class MySQLValidatingNotaryService(services: ServiceHubInternal,
notaryIdentityKey: PublicKey,
configuration: MySQLConfiguration,
devMode: Boolean = false) : MySQLNotaryService(services, notaryIdentityKey, configuration, devMode) {
override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic<Void?> = ValidatingNotaryFlow(otherPartySession, this)
}

View File

@ -66,7 +66,7 @@ class TimedFlowTestRule(val clusterSize: Int) : ExternalResource() {
whenever(it.custom).thenReturn(true)
whenever(it.isClusterConfig).thenReturn(true)
whenever(it.validating).thenReturn(true)
whenever(it.className).thenReturn(TestNotaryService::class.java.name)
whenever(it.className).thenReturn(TimedFlowTests.TestNotaryService::class.java.name)
}
val notaryNodes = (0 until clusterSize).map {
@ -193,7 +193,7 @@ class TimedFlowTests {
}.bufferUntilSubscribed().toBlocking().toFuture()
}
private class TestNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() {
class TestNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() {
override val uniquenessProvider = mock<UniquenessProvider>()
override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic<Void?> = TestNotaryFlow(otherPartySession, this)
override fun start() {}

View File

@ -37,11 +37,11 @@ import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.schema.PersistentStateService
import net.corda.node.services.vault.NodeVaultService
import net.corda.node.services.vault.VaultSchemaV1
import net.corda.node.utilities.TestingNamedCacheFactory
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.testing.core.*
import net.corda.testing.internal.TestingNamedCacheFactory
import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.vault.DummyDealStateSchemaV1
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1

29
notary/mysql/build.gradle Normal file
View File

@ -0,0 +1,29 @@
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.publish-utils'
apply plugin: 'net.corda.plugins.quasar-utils'
dependencies {
cordaCompile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
// Corda integration dependencies
cordaCompile project(':node')
// For the MySQLUniquenessProvider
compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.6'
testCompile "junit:junit:$junit_version"
testCompile project(':node-driver')
}
idea {
module {
downloadJavadoc = true // defaults to false
downloadSources = true
}
}
publish {
name 'corda-notary-mysql'
}

View File

@ -0,0 +1,46 @@
package net.corda.notary.mysql
import net.corda.core.flows.FlowSession
import net.corda.core.internal.notary.AsyncCFTNotaryService
import net.corda.core.internal.notary.NotaryServiceFlow
import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.transactions.NonValidatingNotaryFlow
import net.corda.node.services.transactions.ValidatingNotaryFlow
import java.security.PublicKey
/** Notary service backed by a replicated MySQL database. */
class MySQLNotaryService(
override val services: ServiceHubInternal,
override val notaryIdentityKey: PublicKey) : AsyncCFTNotaryService() {
/** Database table will be automatically created in dev mode */
private val devMode = services.configuration.devMode
private val notaryConfig = services.configuration.notary
?: throw IllegalArgumentException("Failed to register ${this::class.java}: notary configuration not present")
override val asyncUniquenessProvider = with(services) {
val mysqlConfig = notaryConfig.mysql
?: throw IllegalArgumentException("Failed to register ${this::class.java}: raft configuration not present")
MySQLUniquenessProvider(
services.monitoringService.metrics,
services.clock,
mysqlConfig
)
}
override fun createServiceFlow(otherPartySession: FlowSession): NotaryServiceFlow {
return if (notaryConfig.validating) {
ValidatingNotaryFlow(otherPartySession, this)
} else NonValidatingNotaryFlow(otherPartySession, this)
}
override fun start() {
if (devMode) asyncUniquenessProvider.createTable()
}
override fun stop() {
asyncUniquenessProvider.stop()
}
}

View File

@ -1,4 +1,4 @@
package net.corda.node.services.transactions
package net.corda.notary.mysql
import com.codahale.metrics.Gauge
import com.codahale.metrics.MetricRegistry

View File

@ -1,4 +1,4 @@
package net.corda.node.services
package net.corda.notary.mysql
import co.paralleluniverse.fibers.Suspendable
import com.nhaarman.mockito_kotlin.doReturn
@ -24,7 +24,6 @@ import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds
import net.corda.node.services.config.MySQLConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.transactions.MySQLNotaryService
import net.corda.nodeapi.internal.DevIdentityGenerator
import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters
@ -64,9 +63,9 @@ class MySQLNotaryServiceTests : IntegrationTest() {
@Before
fun before() {
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts"), threadPerNode = true)
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts", "net.corda.notary.mysql"), threadPerNode = true)
notaryParty = DevIdentityGenerator.generateDistributedNotarySingularIdentity(listOf(mockNet.baseDirectory(mockNet.nextNodeId)), notaryName)
val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notaryParty, false))))
val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notaryParty, true))))
val notaryNodeUnstarted = createNotaryNode()
val nodeUnstarted = mockNet.createUnstartedNode()
val startedNodes = listOf(notaryNodeUnstarted, nodeUnstarted).map { n ->
@ -256,8 +255,9 @@ class MySQLNotaryServiceTests : IntegrationTest() {
entropyRoot = BigInteger.valueOf(60L),
configOverrides = {
val notaryConfig = NotaryConfig(
validating = false,
mysql = MySQLConfiguration(dataStoreProperties, maxBatchSize = 10, maxBatchInputStates = 100)
validating = true,
mysql = MySQLConfiguration(dataStoreProperties, maxBatchSize = 10, maxBatchInputStates = 100),
className = MySQLNotaryService::class.java.name
)
doReturn(notaryConfig).whenever(it).notary
}

View File

@ -327,7 +327,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
private fun makeNodeWithTracking(
name: CordaX500Name): TestStartedNode {
// Create a node in the mock network ...
return mockNet.createNode(InternalMockNodeParameters(legalName = name), nodeFactory = { args, _ ->
return mockNet.createNode(InternalMockNodeParameters(legalName = name), nodeFactory = { args ->
object : InternalMockNetwork.MockNode(args) {
// That constructs a recording tx storage
override fun makeTransactionStorage(transactionCacheSizeBytes: Long): WritableTransactionStorage {

View File

@ -81,6 +81,7 @@ include 'node:dist'
include 'tools:notary-healthcheck:contract'
include 'tools:notary-healthcheck:cordapp'
include 'tools:notary-healthcheck:client'
include 'notary:mysql'
apply from: 'buildCacheSettings.gradle'

View File

@ -33,10 +33,7 @@ import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.services.api.FlowStarter
import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.api.StartedNodeServices
import net.corda.node.services.config.FlowTimeoutConfiguration
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.config.VerifierType
import net.corda.node.services.config.*
import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.services.keys.E2ETestKeyManagementService
import net.corda.node.services.keys.KeyManagementServiceInternal

View File

@ -153,7 +153,7 @@ private class DbManagementTool : CordaCliWrapper("database-manager", "The Corda
val nodeConfig = ConfigHelper.loadConfig(baseDirectory, config).parseAs<NodeConfigurationImpl>(UnknownConfigKeysPolicy.IGNORE::handle)
val cordappLoader = JarScanningCordappLoader.fromDirectories(setOf(baseDirectory, baseDirectory / "cordapps"))
val schemaService = NodeSchemaService(extraSchemas = cordappLoader.cordappSchemas, includeNotarySchemas = nodeConfig.notary != null)
val schemaService = NodeSchemaService(extraSchemas = cordappLoader.cordappSchemas)
handleCommand(baseDirectory, config, cmdLineOptions.mode, cordappLoader.appClassLoader, schemaService.schemaOptions.keys)
}

View File

@ -15,6 +15,7 @@ dependencies {
cordaCompile project(':core')
cordaCompile project(':client:rpc')
cordaCompile project(':node-driver')
compile project(':notary:mysql')
compile project(':client:mock')
compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.6'
compile group: 'io.dropwizard.metrics', name: 'metrics-graphite', version: '3.2.5'

View File

@ -13,9 +13,9 @@ import net.corda.core.node.services.CordaService
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.services.config.ConfigHelper
import net.corda.node.services.config.MySQLConfiguration
import net.corda.node.services.transactions.MySQLUniquenessProvider
import net.corda.node.services.transactions.NonValidatingNotaryFlow
import net.corda.nodeapi.internal.config.parseAs
import net.corda.notary.mysql.MySQLUniquenessProvider
import net.corda.notarytest.flows.AsyncLoadTestFlow
import java.net.InetAddress
import java.net.InetSocketAddress