Remove mock identity service

Remove mock identity service and merge it with the in memory identity service. The two services
provide extremely similar functionality, and having two different version for production/test
risks subtle implementation differences. On that note, this patch includes changes to a number
of tests which worked only with mock identity service.
This commit is contained in:
Ross Nicoll 2017-05-19 11:22:47 +01:00 committed by GitHub
parent d288fcc979
commit 794ce03958
8 changed files with 39 additions and 56 deletions

View File

@ -4,7 +4,6 @@ import net.corda.core.identity.Party
import net.corda.core.utilities.ALICE
import net.corda.core.utilities.BOB
import net.corda.core.utilities.DUMMY_NOTARY
import net.corda.testing.MOCK_IDENTITY_SERVICE
import net.corda.testing.node.MockNetwork
import org.junit.Before
import org.junit.Test
@ -17,7 +16,6 @@ class TxKeyFlowUtilitiesTests {
@Before
fun before() {
net = MockNetwork(false)
net.identities += MOCK_IDENTITY_SERVICE.identities
}
@Test

View File

@ -4,11 +4,11 @@ import com.google.common.util.concurrent.ListenableFuture
import net.corda.contracts.testing.calculateRandomlySizedAmounts
import net.corda.core.contracts.Amount
import net.corda.core.contracts.DOLLARS
import net.corda.core.contracts.PartyAndReference
import net.corda.core.contracts.currency
import net.corda.core.flows.FlowException
import net.corda.core.flows.FlowStateMachine
import net.corda.core.getOrThrow
import net.corda.core.identity.Party
import net.corda.core.map
import net.corda.core.serialization.OpaqueBytes
import net.corda.core.transactions.SignedTransaction
@ -40,13 +40,14 @@ class IssuerFlowTest {
bankClientNode = net.createPartyNode(notaryNode.info.address, MEGA_CORP.name)
// using default IssueTo Party Reference
val issueToPartyAndRef = bankClientNode.info.legalIdentity.ref(OpaqueBytes.of(123))
val (issuer, issuerResult) = runIssuerAndIssueRequester(bankOfCordaNode, bankClientNode, 1000000.DOLLARS, issueToPartyAndRef)
val (issuer, issuerResult) = runIssuerAndIssueRequester(bankOfCordaNode, bankClientNode, 1000000.DOLLARS,
bankClientNode.info.legalIdentity, OpaqueBytes.of(123))
assertEquals(issuerResult.get(), issuer.get().resultFuture.get())
// try to issue an amount of a restricted currency
assertFailsWith<FlowException> {
runIssuerAndIssueRequester(bankOfCordaNode, bankClientNode, Amount(100000L, currency("BRL")), issueToPartyAndRef).issueRequestResult.getOrThrow()
runIssuerAndIssueRequester(bankOfCordaNode, bankClientNode, Amount(100000L, currency("BRL")),
bankClientNode.info.legalIdentity, OpaqueBytes.of(123)).issueRequestResult.getOrThrow()
}
bankOfCordaNode.stop()
@ -62,8 +63,8 @@ class IssuerFlowTest {
bankOfCordaNode = net.createPartyNode(notaryNode.info.address, BOC.name)
// using default IssueTo Party Reference
val issueToPartyAndRef = bankOfCordaNode.info.legalIdentity.ref(OpaqueBytes.of(123))
val (issuer, issuerResult) = runIssuerAndIssueRequester(bankOfCordaNode, bankOfCordaNode, 1000000.DOLLARS, issueToPartyAndRef)
val (issuer, issuerResult) = runIssuerAndIssueRequester(bankOfCordaNode, bankOfCordaNode, 1000000.DOLLARS,
bankOfCordaNode.info.legalIdentity, OpaqueBytes.of(123))
assertEquals(issuerResult.get(), issuer.get().resultFuture.get())
bankOfCordaNode.stop()
@ -79,14 +80,12 @@ class IssuerFlowTest {
bankOfCordaNode = net.createPartyNode(notaryNode.info.address, BOC.name)
bankClientNode = net.createPartyNode(notaryNode.info.address, MEGA_CORP.name)
// using default IssueTo Party Reference
val issueToPartyAndRef = bankClientNode.info.legalIdentity.ref(OpaqueBytes.of(123))
// this test exercises the Cashflow issue and move subflows to ensure consistent spending of issued states
val amount = 10000.DOLLARS
val amounts = calculateRandomlySizedAmounts(10000.DOLLARS, 10, 10, Random())
val handles = amounts.map { pennies ->
runIssuerAndIssueRequester(bankOfCordaNode, bankClientNode, Amount(pennies, amount.token), issueToPartyAndRef)
runIssuerAndIssueRequester(bankOfCordaNode, bankClientNode, Amount(pennies, amount.token),
bankClientNode.info.legalIdentity, OpaqueBytes.of(123))
}
handles.forEach {
require(it.issueRequestResult.get() is SignedTransaction)
@ -98,13 +97,14 @@ class IssuerFlowTest {
}
private fun runIssuerAndIssueRequester(issuerNode: MockNode, issueToNode: MockNode,
amount: Amount<Currency>, issueToPartyAndRef: PartyAndReference): RunResult {
val resolvedIssuerParty = issuerNode.services.identityService.partyFromAnonymous(issueToPartyAndRef) ?: throw IllegalStateException()
amount: Amount<Currency>,
party: Party, ref: OpaqueBytes): RunResult {
val issueToPartyAndRef = party.ref(ref)
val issuerFuture = issuerNode.initiateSingleShotFlow(IssuerFlow.IssuanceRequester::class) { _ ->
IssuerFlow.Issuer(resolvedIssuerParty)
IssuerFlow.Issuer(party)
}.map { it.stateMachine }
val issueRequest = IssuanceRequester(amount, resolvedIssuerParty, issueToPartyAndRef.reference, issuerNode.info.legalIdentity)
val issueRequest = IssuanceRequester(amount, party, issueToPartyAndRef.reference, issuerNode.info.legalIdentity)
val issueRequestResultFuture = issueToNode.services.startFlow(issueRequest).resultFuture
return IssuerFlowTest.RunResult(issuerFuture, issueRequestResultFuture)

View File

@ -20,9 +20,13 @@ import javax.annotation.concurrent.ThreadSafe
/**
* Simple identity service which caches parties and provides functionality for efficient lookup.
*
* @param identities initial set of identities for the service, typically only used for unit tests.
* @param certPaths initial set of certificate paths for the service, typically only used for unit tests.
*/
@ThreadSafe
class InMemoryIdentityService : SingletonSerializeAsToken(), IdentityService {
class InMemoryIdentityService(identities: Iterable<Party> = emptySet(),
certPaths: Map<AnonymousParty, CertPath> = emptyMap()) : SingletonSerializeAsToken(), IdentityService {
companion object {
private val log = loggerFor<InMemoryIdentityService>()
}
@ -31,6 +35,12 @@ class InMemoryIdentityService : SingletonSerializeAsToken(), IdentityService {
private val principalToParties = ConcurrentHashMap<X500Name, Party>()
private val partyToPath = ConcurrentHashMap<AnonymousParty, CertPath>()
init {
keyToParties.putAll(identities.associateBy { it.owningKey } )
principalToParties.putAll(identities.associateBy { it.name })
partyToPath.putAll(certPaths)
}
override fun registerIdentity(party: Party) {
log.trace { "Registering identity $party" }
keyToParties[party.owningKey] = party

View File

@ -70,7 +70,6 @@ class TwoPartyTradeFlowTests {
@Before
fun before() {
net = MockNetwork(false)
net.identities += MOCK_IDENTITY_SERVICE.identities
LogHelper.setLevel("platform.trade", "core.contract.TransactionGroup", "recordingmap")
}
@ -501,6 +500,8 @@ class TwoPartyTradeFlowTests {
serviceHub.legalIdentityKey))
}
sellerNode.services.identityService.registerIdentity(buyerNode.info.legalIdentity)
buyerNode.services.identityService.registerIdentity(sellerNode.info.legalIdentity)
val buyerFuture = buyerNode.initiateSingleShotFlow(SellerRunnerFlow::class) { otherParty ->
Buyer(otherParty, notaryNode.info.notaryIdentity, 1000.DOLLARS, CommercialPaper.State::class.java)
}.map { it.stateMachine }

View File

@ -1,6 +1,7 @@
package net.corda.irs.simulation
import co.paralleluniverse.fibers.Suspendable
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.google.common.util.concurrent.FutureCallback
import com.google.common.util.concurrent.Futures
@ -13,7 +14,6 @@ import net.corda.core.flatMap
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowStateMachine
import net.corda.core.flows.InitiatingFlow
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party
import net.corda.core.map
import net.corda.core.node.services.linearHeadsOfType
@ -24,10 +24,10 @@ import net.corda.flows.TwoPartyDealFlow.AutoOffer
import net.corda.flows.TwoPartyDealFlow.Instigator
import net.corda.irs.contract.InterestRateSwap
import net.corda.jackson.JacksonSupport
import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.utilities.transaction
import net.corda.testing.initiateSingleShotFlow
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MockIdentityService
import java.security.PublicKey
import java.time.LocalDate
import java.util.*
@ -37,7 +37,7 @@ import java.util.*
* A simulation in which banks execute interest rate swaps with each other, including the fixing events.
*/
class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) : Simulation(networkSendManuallyPumped, runAsync, latencyInjector) {
val om = JacksonSupport.createInMemoryMapper(MockIdentityService(network.identities))
lateinit var om: ObjectMapper
init {
currentDateAndTime = LocalDate.of(2016, 3, 8).atStartOfDay()
@ -47,6 +47,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
override fun startMainSimulation(): ListenableFuture<Unit> {
val future = SettableFuture.create<Unit>()
om = JacksonSupport.createInMemoryMapper(InMemoryIdentityService((banks + regulators + networkMap).map { it.info.legalIdentity }))
startIRSDealBetween(0, 1).success {
// Next iteration is a pause.

View File

@ -11,6 +11,7 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub
import net.corda.core.node.VersionInfo
import net.corda.core.node.services.IdentityService
import net.corda.core.serialization.OpaqueBytes
import net.corda.core.toFuture
import net.corda.core.transactions.TransactionBuilder
@ -18,17 +19,16 @@ import net.corda.core.utilities.*
import net.corda.node.internal.AbstractNode
import net.corda.node.internal.NetworkMapInfo
import net.corda.node.services.config.*
import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.statemachine.FlowStateMachineImpl
import net.corda.node.services.statemachine.StateMachineManager
import net.corda.nodeapi.User
import net.corda.nodeapi.config.SSLConfiguration
import net.corda.testing.node.MockIdentityService
import net.corda.testing.node.MockServices
import net.corda.testing.node.makeTestDataSourceProperties
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x500.X500NameBuilder
import org.bouncycastle.asn1.x500.style.BCStyle
import java.net.ServerSocket
import java.net.URL
import java.nio.file.Files
import java.nio.file.Path
@ -85,7 +85,7 @@ val BIG_CORP_PARTY_REF = BIG_CORP.ref(OpaqueBytes.of(1)).reference
val ALL_TEST_KEYS: List<KeyPair> get() = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY)
val MOCK_IDENTITY_SERVICE: MockIdentityService get() = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
val MOCK_IDENTITY_SERVICE: IdentityService get() = InMemoryIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
val MOCK_VERSION_INFO = VersionInfo(1, "Mock release", "Mock revision", "Mock Vendor")

View File

@ -20,6 +20,7 @@ import net.corda.core.utilities.loggerFor
import net.corda.node.internal.AbstractNode
import net.corda.node.internal.ServiceFlowInfo
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.keys.E2ETestKeyManagementService
import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.network.InMemoryNetworkMapService
@ -166,7 +167,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
.getOrThrow()
}
override fun makeIdentityService() = MockIdentityService(mockNet.identities)
override fun makeIdentityService() = InMemoryIdentityService(mockNet.identities)
override fun makeVaultService(dataSourceProperties: Properties): VaultService = NodeVaultService(services, dataSourceProperties)

View File

@ -14,6 +14,7 @@ import net.corda.core.node.services.*
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.DUMMY_NOTARY
import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.persistence.InMemoryStateMachineRecordedTransactionMappingStorage
import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService
@ -37,6 +38,7 @@ import java.security.cert.CertPath
import java.security.cert.X509Certificate
import java.time.Clock
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.jar.JarInputStream
import javax.annotation.concurrent.ThreadSafe
@ -62,7 +64,7 @@ open class MockServices(vararg val keys: KeyPair) : ServiceHub {
}
override val storageService: TxWritableStorageService = MockStorageService()
override val identityService: MockIdentityService = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
override val identityService: IdentityService = InMemoryIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
override val keyManagementService: KeyManagementService = MockKeyManagementService(*keys)
override val vaultService: VaultService get() = throw UnsupportedOperationException()
@ -79,36 +81,6 @@ open class MockServices(vararg val keys: KeyPair) : ServiceHub {
}
}
@ThreadSafe
class MockIdentityService(val identities: List<Party>,
val certificates: List<Triple<AnonymousParty, Party, CertPath>> = emptyList()) : IdentityService, SingletonSerializeAsToken() {
private val keyToParties: Map<PublicKey, Party>
get() = synchronized(identities) { identities.associateBy { it.owningKey } }
private val nameToParties: Map<X500Name, Party>
get() = synchronized(identities) { identities.associateBy { it.name } }
private val anonymousToPath: Map<AnonymousParty, Pair<Party, CertPath>>
get() = synchronized(certificates) { certificates.map { Pair(it.first, Pair(it.second, it.third)) }.toMap() }
override fun registerIdentity(party: Party) {
throw UnsupportedOperationException()
}
override fun getAllIdentities(): Iterable<Party> = ArrayList(keyToParties.values)
override fun partyFromAnonymous(party: AbstractParty): Party? = keyToParties[party.owningKey]
override fun partyFromAnonymous(partyRef: PartyAndReference): Party? = partyFromAnonymous(partyRef.party)
override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]
override fun partyFromName(name: String): Party? = nameToParties[X500Name(name)]
override fun partyFromX500Name(principal: X500Name): Party? = nameToParties[principal]
@Throws(IllegalStateException::class)
override fun assertOwnership(party: Party, anonymousParty: AnonymousParty) {
check(anonymousToPath[anonymousParty]?.first == party)
}
override fun pathForAnonymous(anonymousParty: AnonymousParty): CertPath? = anonymousToPath[anonymousParty]?.second
override fun registerPath(trustedRoot: X509Certificate, anonymousParty: AnonymousParty, path: CertPath) { throw UnsupportedOperationException() }
}
class MockKeyManagementService(vararg initialKeys: KeyPair) : SingletonSerializeAsToken(), KeyManagementService {
private val keyStore: MutableMap<PublicKey, PrivateKey> = initialKeys.associateByTo(HashMap(), { it.public }, { it.private })