CORDA-535: Remove the old mechanism for loading custom notary service implementations.

All notary service implementations are now assumed to be loaded from CorDapps.
This commit is contained in:
Andrius Dagys
2018-10-10 13:31:29 +01:00
parent 554b1fa371
commit b8b2cc772d
6 changed files with 32 additions and 72 deletions

View File

@ -42,9 +42,12 @@ import net.corda.node.services.ContractUpgradeHandler
import net.corda.node.services.FinalityHandler
import net.corda.node.services.NotaryChangeHandler
import net.corda.node.services.api.*
import net.corda.node.services.config.*
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.config.configureWithDevSSLCertificate
import net.corda.node.services.config.rpc.NodeRpcOptions
import net.corda.node.services.config.shell.toShellConfig
import net.corda.node.services.config.shouldInitCrashShell
import net.corda.node.services.events.NodeSchedulerService
import net.corda.node.services.events.ScheduledActivityObserver
import net.corda.node.services.identity.PersistentIdentityService
@ -59,7 +62,8 @@ import net.corda.node.services.network.PersistentNetworkMapCache
import net.corda.node.services.persistence.*
import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.statemachine.*
import net.corda.node.services.transactions.*
import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.node.services.upgrade.ContractUpgradeServiceImpl
import net.corda.node.services.vault.NodeVaultService
import net.corda.node.utilities.*
@ -518,9 +522,9 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
private fun installCordaServices(myNotaryIdentity: PartyAndCertificate?) {
val loadedServices = cordappLoader.cordapps.flatMap { it.services }
filterServicesToInstall(loadedServices).forEach {
loadedServices.forEach {
try {
installCordaService(flowStarter, it, myNotaryIdentity)
installCordaService(flowStarter, it)
} catch (e: NoSuchMethodException) {
log.error("${it.name}, as a Corda service, must have a constructor with a single parameter of type " +
ServiceHub::class.java.name)
@ -532,24 +536,6 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
}
}
private fun filterServicesToInstall(loadedServices: List<Class<out SerializeAsToken>>): List<Class<out SerializeAsToken>> {
val customNotaryServiceList = loadedServices.filter { isNotaryService(it) }
if (customNotaryServiceList.isNotEmpty()) {
if (configuration.notary?.custom == true) {
require(customNotaryServiceList.size == 1) {
"Attempting to install more than one notary service: ${customNotaryServiceList.joinToString()}"
}
} else return loadedServices - customNotaryServiceList
}
return loadedServices
}
/**
* If the [serviceClass] is a notary service, it will only be enabled if the "custom" flag is set in
* the notary configuration.
*/
private fun isNotaryService(serviceClass: Class<*>) = NotaryService::class.java.isAssignableFrom(serviceClass)
/**
* This customizes the ServiceHub for each CordaService that is initiating flows.
*/
@ -590,53 +576,30 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
override fun hashCode() = Objects.hash(serviceHub, flowStarter, serviceInstance)
}
private fun <T : SerializeAsToken> installCordaService(flowStarter: FlowStarter, serviceClass: Class<T>, myNotaryIdentity: PartyAndCertificate?) {
private fun <T : SerializeAsToken> installCordaService(flowStarter: FlowStarter, serviceClass: Class<T>) {
serviceClass.requireAnnotation<CordaService>()
val service = try {
if (isNotaryService(serviceClass)) {
myNotaryIdentity ?: throw IllegalStateException("Trying to install a notary service but no notary identity specified")
try {
val constructor = serviceClass.getDeclaredConstructor(ServiceHubInternal::class.java, PublicKey::class.java).apply { isAccessible = true }
constructor.newInstance(services, myNotaryIdentity.owningKey )
} catch (ex: NoSuchMethodException) {
val constructor = serviceClass.getDeclaredConstructor(AppServiceHub::class.java, PublicKey::class.java).apply { isAccessible = true }
val serviceContext = AppServiceHubImpl<T>(services, flowStarter)
val service = constructor.newInstance(serviceContext, myNotaryIdentity.owningKey)
serviceContext.serviceInstance = service
service
}
} else {
try {
val serviceContext = AppServiceHubImpl<T>(services, flowStarter)
val extendedServiceConstructor = serviceClass.getDeclaredConstructor(AppServiceHub::class.java).apply { isAccessible = true }
val service = extendedServiceConstructor.newInstance(serviceContext)
serviceContext.serviceInstance = service
service
} catch (ex: NoSuchMethodException) {
val constructor = serviceClass.getDeclaredConstructor(ServiceHub::class.java).apply { isAccessible = true }
log.warn("${serviceClass.name} is using legacy CordaService constructor with ServiceHub parameter. " +
"Upgrade to an AppServiceHub parameter to enable updated API features.")
constructor.newInstance(services)
}
}
val serviceContext = AppServiceHubImpl<T>(services, flowStarter)
val extendedServiceConstructor = serviceClass.getDeclaredConstructor(AppServiceHub::class.java).apply { isAccessible = true }
val service = extendedServiceConstructor.newInstance(serviceContext)
serviceContext.serviceInstance = service
service
} catch (ex: NoSuchMethodException) {
val constructor = serviceClass.getDeclaredConstructor(ServiceHub::class.java).apply { isAccessible = true }
log.warn("${serviceClass.name} is using legacy CordaService constructor with ServiceHub parameter. " +
"Upgrade to an AppServiceHub parameter to enable updated API features.")
constructor.newInstance(services)
} catch (e: InvocationTargetException) {
throw ServiceInstantiationException(e.cause)
}
cordappServices.putInstance(serviceClass, service)
if (service is NotaryService) handleCustomNotaryService(service)
service.tokenize()
log.info("Installed ${serviceClass.name} Corda service")
}
private fun handleCustomNotaryService(service: NotaryService) {
runOnStop += service::stop
installCoreFlow(NotaryFlow.Client::class, service::createServiceFlow)
service.start()
}
private fun registerCordappFlows() {
cordappLoader.cordapps.flatMap { it.initiatedFlows }
.forEach {

View File

@ -122,13 +122,12 @@ fun NodeConfiguration.shouldInitCrashShell() = shouldStartLocalShell() || should
data class NotaryConfig(val validating: Boolean,
val raft: RaftConfig? = null,
val bftSMaRt: BFTSMaRtConfiguration? = null,
val custom: Boolean = false,
val serviceLegalName: CordaX500Name? = null,
val className: String = "net.corda.node.services.transactions.SimpleNotaryService"
) {
init {
require(raft == null || bftSMaRt == null || !custom) {
"raft, bftSMaRt, and custom configs cannot be specified together"
require(raft == null || bftSMaRt == null) {
"raft and bftSMaRt configs cannot be specified together"
}
}

View File

@ -88,7 +88,6 @@ class TimedFlowTests {
val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notaryIdentity, true))))
val notaryConfig = mock<NotaryConfig> {
whenever(it.custom).thenReturn(true)
whenever(it.isClusterConfig).thenReturn(true)
whenever(it.validating).thenReturn(true)
whenever(it.className).thenReturn(TestNotaryService::class.java.name)