mirror of
https://github.com/corda/corda.git
synced 2025-05-04 17:53:05 +00:00
Update code to use AppServiceHub in services and support for services when using MockServices hub.
This commit is contained in:
parent
daa6caeee2
commit
f19ff141dd
@ -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
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user