Update code to use AppServiceHub in services and support for services when using MockServices hub.

This commit is contained in:
Matthew Nesbit 2017-10-09 10:44:32 +01:00
parent daa6caeee2
commit f19ff141dd
7 changed files with 45 additions and 11 deletions

View File

@ -36,6 +36,10 @@ UNRELEASED
* Cordformation node building DSL can have an additional parameter `configFile` with the path to a properties file * Cordformation node building DSL can have an additional parameter `configFile` with the path to a properties file
to be appended to node.conf. to be appended to node.conf.
* ``CordaService`` annotated classes should be upgraded to take a constructor parameter of type ``AppServiceHub`` which
allows services to start flows marked with the ``StartableByService`` annotation. For backwards compatability
service classes with only ``ServiceHub`` constructors will still work.
.. _changelog_v1: .. _changelog_v1:
Release 1.0 Release 1.0

View File

@ -4,7 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.TimeWindow import net.corda.core.contracts.TimeWindow
import net.corda.core.contracts.TransactionVerificationException import net.corda.core.contracts.TransactionVerificationException
import net.corda.core.flows.* import net.corda.core.flows.*
import net.corda.core.node.ServiceHub import net.corda.core.node.AppServiceHub
import net.corda.core.node.services.CordaService import net.corda.core.node.services.CordaService
import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TimeWindowChecker
import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.core.node.services.TrustedAuthorityNotaryService
@ -15,7 +15,7 @@ import java.security.SignatureException
// START 1 // START 1
@CordaService @CordaService
class MyCustomValidatingNotaryService(override val services: ServiceHub, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { class MyCustomValidatingNotaryService(override val services: AppServiceHub, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() {
override val timeWindowChecker = TimeWindowChecker(services.clock) override val timeWindowChecker = TimeWindowChecker(services.clock)
override val uniquenessProvider = PersistentUniquenessProvider() override val uniquenessProvider = PersistentUniquenessProvider()

View File

@ -4,7 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.flows.* import net.corda.core.flows.*
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub import net.corda.core.node.AppServiceHub
import net.corda.core.node.services.CordaService import net.corda.core.node.services.CordaService
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
@ -23,7 +23,7 @@ import java.util.*
object CustomVaultQuery { object CustomVaultQuery {
@CordaService @CordaService
class Service(val services: ServiceHub) : SingletonSerializeAsToken() { class Service(val services: AppServiceHub) : SingletonSerializeAsToken() {
private companion object { private companion object {
val log = loggerFor<Service>() val log = loggerFor<Service>()
} }
@ -49,7 +49,7 @@ object CustomVaultQuery {
val session = services.jdbcSession() val session = services.jdbcSession()
val prepStatement = session.prepareStatement(nativeQuery) val prepStatement = session.prepareStatement(nativeQuery)
val rs = prepStatement.executeQuery() val rs = prepStatement.executeQuery()
var topUpLimits: MutableList<Amount<Currency>> = mutableListOf() val topUpLimits: MutableList<Amount<Currency>> = mutableListOf()
while (rs.next()) { while (rs.next()) {
val currencyStr = rs.getString(1) val currencyStr = rs.getString(1)
val amount = rs.getLong(2) val amount = rs.getLong(2)

View File

@ -9,7 +9,7 @@ Writing a custom notary service
Similarly to writing an oracle service, the first step is to create a service class in your CorDapp and annotate it Similarly to writing an oracle service, the first step is to create a service class in your CorDapp and annotate it
with ``@CordaService``. The Corda node scans for any class with this annotation and initialises them. The only requirement with ``@CordaService``. The Corda node scans for any class with this annotation and initialises them. The only requirement
is that the class provide a constructor with a single parameter of type ``ServiceHub``. is that the class provide a constructor with a single parameter of type ``AppServiceHub``.
.. literalinclude:: example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt
:language: kotlin :language: kotlin

View File

@ -2,11 +2,10 @@ package net.corda.irs.api
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.Command import net.corda.core.contracts.Command
import net.corda.core.crypto.MerkleTreeException
import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.* import net.corda.core.flows.*
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.node.ServiceHub import net.corda.core.node.AppServiceHub
import net.corda.core.node.services.CordaService import net.corda.core.node.services.CordaService
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.FilteredTransaction import net.corda.core.transactions.FilteredTransaction
@ -78,7 +77,7 @@ object NodeInterestRates {
@ThreadSafe @ThreadSafe
// DOCSTART 3 // DOCSTART 3
@CordaService @CordaService
class Oracle(private val services: ServiceHub) : SingletonSerializeAsToken() { class Oracle(private val services: AppServiceHub) : SingletonSerializeAsToken() {
private val mutex = ThreadBox(InnerState()) private val mutex = ThreadBox(InnerState())
init { init {

View File

@ -24,6 +24,7 @@ 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.MockServices.Companion.makeTestDatabaseProperties import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
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
@ -65,7 +66,8 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
setCordappPackages("net.corda.finance.contracts") setCordappPackages("net.corda.finance.contracts")
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
database.transaction { database.transaction {
oracle = NodeInterestRates.Oracle(services).apply { knownFixes = TEST_DATA } oracle = createMockCordaService(services, NodeInterestRates::Oracle)
oracle.knownFixes = TEST_DATA
} }
} }

View File

@ -1,10 +1,15 @@
package net.corda.testing.node package net.corda.testing.node
import com.google.common.collect.MutableClassToInstanceMap
import net.corda.core.cordapp.CordappProvider import net.corda.core.cordapp.CordappProvider
import net.corda.core.crypto.* import net.corda.core.crypto.*
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.messaging.FlowHandle
import net.corda.core.messaging.FlowProgressHandle
import net.corda.core.node.AppServiceHub
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.StateLoader import net.corda.core.node.StateLoader
@ -173,7 +178,11 @@ open class MockServices(
return vaultService return vaultService
} }
override fun <T : SerializeAsToken> cordaService(type: Class<T>): T = throw IllegalArgumentException("${type.name} not found") val cordappServices = MutableClassToInstanceMap.create<SerializeAsToken>()
override fun <T : SerializeAsToken> cordaService(type: Class<T>): T {
require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" }
return cordappServices.getInstance(type) ?: throw IllegalArgumentException("Corda service ${type.name} does not exist")
}
override fun jdbcSession(): Connection = throw UnsupportedOperationException() override fun jdbcSession(): Connection = throw UnsupportedOperationException()
} }
@ -244,3 +253,23 @@ open class MockTransactionStorage : WritableTransactionStorage, SingletonSeriali
override fun getTransaction(id: SecureHash): SignedTransaction? = txns[id] override fun getTransaction(id: SecureHash): SignedTransaction? = txns[id]
} }
fun <T : SerializeAsToken> createMockCordaService(serviceHub: MockServices, serviceConstructor: (AppServiceHub) -> T): T {
class MockAppServiceHubImpl<T : SerializeAsToken>(val serviceHub: MockServices, serviceConstructor: (AppServiceHub) -> T) : AppServiceHub, ServiceHub by serviceHub {
val serviceInstance: T
init {
serviceInstance = serviceConstructor(this)
serviceHub.cordappServices.putInstance(serviceInstance.javaClass, serviceInstance)
}
override fun <T> startFlow(flow: FlowLogic<T>): FlowHandle<T> {
throw UnsupportedOperationException()
}
override fun <T> startTrackedFlow(flow: FlowLogic<T>): FlowProgressHandle<T> {
throw UnsupportedOperationException()
}
}
return MockAppServiceHubImpl(serviceHub, serviceConstructor).serviceInstance
}