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
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:
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.TransactionVerificationException
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.TimeWindowChecker
import net.corda.core.node.services.TrustedAuthorityNotaryService
@ -15,7 +15,7 @@ import java.security.SignatureException
// START 1
@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 uniquenessProvider = PersistentUniquenessProvider()

View File

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

View File

@ -2,11 +2,10 @@ package net.corda.irs.api
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.Command
import net.corda.core.crypto.MerkleTreeException
import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.*
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.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.FilteredTransaction
@ -78,7 +77,7 @@ object NodeInterestRates {
@ThreadSafe
// DOCSTART 3
@CordaService
class Oracle(private val services: ServiceHub) : SingletonSerializeAsToken() {
class Oracle(private val services: AppServiceHub) : SingletonSerializeAsToken() {
private val mutex = ThreadBox(InnerState())
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.makeTestDatabaseProperties
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
import net.corda.testing.node.createMockCordaService
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
@ -65,7 +66,8 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
setCordappPackages("net.corda.finance.contracts")
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
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
import com.google.common.collect.MutableClassToInstanceMap
import net.corda.core.cordapp.CordappProvider
import net.corda.core.crypto.*
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.PartyAndCertificate
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.ServiceHub
import net.corda.core.node.StateLoader
@ -173,7 +178,11 @@ open class MockServices(
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()
}
@ -244,3 +253,23 @@ open class MockTransactionStorage : WritableTransactionStorage, SingletonSeriali
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
}