Minor: refactoring to reduce dependencies of the JSON object mapper. Clean up how mock identities are handled a little. This assists with the simulation code.

This commit is contained in:
Mike Hearn 2016-03-31 12:52:48 +02:00
parent a2bd9f63a4
commit 10ee49d994
9 changed files with 45 additions and 30 deletions

View File

@ -18,4 +18,5 @@ import java.security.PublicKey
*/
interface IdentityService {
fun partyFromKey(key: PublicKey): Party?
fun partyFromName(name: String): Party?
}

View File

@ -12,6 +12,6 @@ import javax.ws.rs.ext.Provider
*/
@Provider
class Config(val services: ServiceHub): ContextResolver<ObjectMapper> {
val defaultObjectMapper = JsonSupport.createDefaultMapper(services)
val defaultObjectMapper = JsonSupport.createDefaultMapper(services.identityService)
override fun getContext(type: java.lang.Class<*>) = defaultObjectMapper
}

View File

@ -36,6 +36,7 @@ import java.nio.file.FileAlreadyExistsException
import java.nio.file.Files
import java.nio.file.Path
import java.security.KeyPair
import java.security.PublicKey
import java.time.Clock
import java.util.*
import java.util.concurrent.Executors
@ -142,13 +143,28 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
}
protected open fun makeIdentityService(): IdentityService {
// We don't have any identity infrastructure right now, so we just throw together the only two identities we
// know about: our own, and the identity of the remote timestamper node (if any).
val knownIdentities = if (timestamperAddress != null)
// We don't have any identity infrastructure right now, so we just throw together the only identities we
// know about: our own, the identity of the remote timestamper node (if any), plus whatever is in the
// network map.
//
// TODO: All this will be replaced soon enough.
val fixedIdentities = if (timestamperAddress != null)
listOf(storage.myLegalIdentity, timestamperAddress.identity)
else
listOf(storage.myLegalIdentity)
return FixedIdentityService(knownIdentities)
return object : IdentityService {
private val identities: List<Party> get() = fixedIdentities + services.networkMapCache.partyNodes.map { it.identity }
private val keyToParties: Map<PublicKey, Party> get() = identities.associateBy { it.owningKey }
private val nameToParties: Map<String, Party> get() = identities.associateBy { it.name }
override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]
override fun partyFromName(name: String): Party? = nameToParties[name]
override fun toString(): String {
return identities.joinToString { it.name }
}
}
}
open fun stop() {

View File

@ -8,14 +8,23 @@
package core.node.services
import core.node.services.IdentityService
import core.Party
import java.security.PublicKey
import javax.annotation.concurrent.ThreadSafe
/**
* Scaffolding: a dummy identity service that just expects to have identities loaded off disk or found elsewhere.
* This class allows the provided list of identities to be mutated after construction, so it takes the list lock
* when doing lookups and recalculates the mapping each time. The ability to change the list is used by the
* MockNetwork code.
*/
class FixedIdentityService(private val identities: List<Party>) : IdentityService {
private val keyToParties: Map<PublicKey, Party> get() = identities.associateBy { it.owningKey }
@ThreadSafe
class FixedIdentityService(val identities: List<Party>) : IdentityService {
private val keyToParties: Map<PublicKey, Party>
get() = synchronized(identities) { identities.associateBy { it.owningKey } }
private val nameToParties: Map<String, Party>
get() = synchronized(identities) { identities.associateBy { it.name } }
override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]
override fun partyFromName(name: String): Party? = nameToParties[name]
}

View File

@ -20,7 +20,7 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule
import core.BusinessCalendar
import core.Party
import core.crypto.SecureHash
import core.node.services.ServiceHub
import core.node.services.IdentityService
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime
@ -30,8 +30,8 @@ import java.time.LocalDateTime
* the java.time API, some core types, and Kotlin data classes.
*/
object JsonSupport {
fun createDefaultMapper(services: ServiceHub): ObjectMapper {
val mapper = ServiceHubObjectMapper(services)
fun createDefaultMapper(identities: IdentityService): ObjectMapper {
val mapper = ServiceHubObjectMapper(identities)
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
@ -59,7 +59,7 @@ object JsonSupport {
return mapper
}
class ServiceHubObjectMapper(val serviceHub: ServiceHub): ObjectMapper()
class ServiceHubObjectMapper(val identities: IdentityService): ObjectMapper()
object ToStringSerializer: JsonSerializer<Any>() {
override fun serialize(obj: Any, generator: JsonGenerator, provider: SerializerProvider) {
@ -97,8 +97,7 @@ object JsonSupport {
}
val mapper = parser.codec as ServiceHubObjectMapper
// TODO this needs to use some industry identifier(s) not just these human readable names
val nodeForPartyName = mapper.serviceHub.networkMapCache.nodeForPartyName(parser.text) ?: throw JsonParseException("Could not find a Party with name: ${parser.text}", parser.currentLocation)
return nodeForPartyName.identity
return mapper.identities.partyFromName(parser.text) ?: throw JsonParseException("Could not find a Party with name: ${parser.text}", parser.currentLocation)
}
}

View File

@ -14,7 +14,7 @@ import core.messaging.MessagingService
import core.node.services.*
import core.serialization.SerializedBytes
import core.serialization.deserialize
import core.testutils.TEST_KEYS_TO_CORP_MAP
import core.testutils.MockIdentityService
import core.testutils.TEST_PROGRAM_MAP
import core.testutils.TEST_TX_TIME
import java.io.ByteArrayInputStream
@ -50,10 +50,6 @@ class DummyTimestamper(var clock: Clock = Clock.fixed(TEST_TX_TIME, ZoneId.syste
val DUMMY_TIMESTAMPER = DummyTimestamper()
object MockIdentityService : IdentityService {
override fun partyFromKey(key: PublicKey): Party? = TEST_KEYS_TO_CORP_MAP[key]
}
class MockKeyManagementService(vararg initialKeys: KeyPair) : KeyManagementService {
override val keys: MutableMap<PublicKey, PrivateKey>

View File

@ -48,7 +48,7 @@ class TwoPartyTradeProtocolTests : TestWithInMemoryNetwork() {
@Before
fun before() {
net = MockNetwork(false)
net.identities += TEST_KEYS_TO_CORP_MAP.values
net.identities += MockIdentityService.identities
BriefLogFormatter.loggingOn("platform.trade", "core.TransactionGroup", "recordingmap")
}

View File

@ -11,10 +11,7 @@ package core.serialization
import contracts.Cash
import core.*
import core.crypto.SecureHash
import core.testutils.DUMMY_PUBKEY_1
import core.testutils.MINI_CORP
import core.testutils.TEST_TX_TIME
import core.testutils.TestUtils
import core.testutils.*
import org.junit.Before
import org.junit.Test
import java.security.SignatureException

View File

@ -15,6 +15,7 @@ import contracts.*
import core.*
import core.crypto.*
import core.node.services.DummyTimestampingAuthority
import core.node.services.FixedIdentityService
import core.serialization.serialize
import core.visualiser.GraphVisualiser
import java.security.KeyPair
@ -66,11 +67,7 @@ val MINI_CORP = Party("MiniCorp", MINI_CORP_PUBKEY)
val ALL_TEST_KEYS = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DummyTimestampingAuthority.key)
val TEST_KEYS_TO_CORP_MAP: Map<PublicKey, Party> = mapOf(
MEGA_CORP_PUBKEY to MEGA_CORP,
MINI_CORP_PUBKEY to MINI_CORP,
DUMMY_TIMESTAMPER.identity.owningKey to DUMMY_TIMESTAMPER.identity
)
val MockIdentityService = FixedIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_TIMESTAMPER.identity))
// In a real system this would be a persistent map of hash to bytecode and we'd instantiate the object as needed inside
// a sandbox. For unit tests we just have a hard-coded list.
@ -128,7 +125,7 @@ abstract class AbstractTransactionForTest {
open fun output(label: String? = null, s: () -> ContractState) = LabeledOutput(label, s()).apply { outStates.add(this) }
protected fun commandsToAuthenticatedObjects(): List<AuthenticatedObject<CommandData>> {
return commands.map { AuthenticatedObject(it.pubkeys, it.pubkeys.mapNotNull { TEST_KEYS_TO_CORP_MAP[it] }, it.data) }
return commands.map { AuthenticatedObject(it.pubkeys, it.pubkeys.mapNotNull { MockIdentityService.partyFromKey(it) }, it.data) }
}
fun attachment(attachmentID: SecureHash) {