mirror of
https://github.com/corda/corda.git
synced 2025-02-20 17:33:15 +00:00
Refactoring changes to work with interface changes
Specifically we don't need the factory factory as that functionality lives in the global defaults
This commit is contained in:
parent
139eef2ccb
commit
825908cf15
@ -47,8 +47,9 @@ abstract class AbstractAMQPSerializationScheme : SerializationScheme {
|
||||
}
|
||||
|
||||
fun getSerializerFactory(): SerializerFactory {
|
||||
return serializerFactoriesForContexts.computeIfAbsent(Pair(AllWhitelist, deserializationClassLoader)) {
|
||||
SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
return serializerFactoriesForContexts.computeIfAbsent(Pair(
|
||||
AllWhitelist, SerializationDefaults.javaClass.classLoader)) {
|
||||
SerializerFactory(AllWhitelist, SerializationDefaults.javaClass.classLoader)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,13 +6,9 @@ import com.esotericsoftware.kryo.io.Input
|
||||
import com.esotericsoftware.kryo.io.Output
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.SerializationFactory
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.utilities.sequence
|
||||
import net.corda.nodeapi.internal.serialization.amqp.AmqpHeaderV1_0
|
||||
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializationOutput
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactoryFactory
|
||||
|
||||
/**
|
||||
* This [Kryo] custom [Serializer] switches the object graph of anything annotated with `@CordaSerializable`
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.core.serialization.SerializationDefaults
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.nameForType
|
||||
import org.apache.qpid.proton.codec.Data
|
||||
import java.lang.reflect.Type
|
||||
@ -68,26 +69,26 @@ abstract class CustomSerializer<T> : AMQPSerializer<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional base features for a custom serializer for a particular class, that excludes subclasses.
|
||||
* Additional base features for a custom serializer for a particular class [withInheritance] is false
|
||||
* or super class / interfaces [withInheritance] is true
|
||||
*/
|
||||
abstract class Is<T>(protected val clazz: Class<T>) : CustomSerializer<T>() {
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = clazz == this.clazz
|
||||
abstract class CustomSerializerImp<T>(protected val clazz: Class<T>, protected val withInheritance: Boolean) : CustomSerializer<T>() {
|
||||
override val type: Type get() = clazz
|
||||
override val typeDescriptor: String = "$DESCRIPTOR_DOMAIN:${nameForType(clazz)}"
|
||||
override fun writeClassInfo(output: SerializationOutput) {}
|
||||
override val descriptor: Descriptor = Descriptor(typeDescriptor)
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = if (withInheritance) this.clazz.isAssignableFrom(clazz) else this.clazz == clazz
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional base features for a custom serializer for a particular class, that excludes subclasses.
|
||||
*/
|
||||
abstract class Is<T>(clazz: Class<T>) : CustomSerializerImp<T>(clazz, false)
|
||||
|
||||
/**
|
||||
* Additional base features for a custom serializer for all implementations of a particular interface or super class.
|
||||
*/
|
||||
abstract class Implements<T>(protected val clazz: Class<T>) : CustomSerializer<T>() {
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = this.clazz.isAssignableFrom(clazz)
|
||||
override val type: Type get() = clazz
|
||||
override val typeDescriptor: String = "$DESCRIPTOR_DOMAIN:${nameForType(clazz)}"
|
||||
override fun writeClassInfo(output: SerializationOutput) {}
|
||||
override val descriptor: Descriptor = Descriptor(typeDescriptor)
|
||||
}
|
||||
abstract class Implements<T>(clazz: Class<T>) : CustomSerializerImp<T>(clazz, true)
|
||||
|
||||
/**
|
||||
* Additional base features over and above [Implements] or [Is] custom serializer for when the serialized form should be
|
||||
@ -96,15 +97,11 @@ abstract class CustomSerializer<T> : AMQPSerializer<T> {
|
||||
* The proxy class must use only types which are either native AMQP or other types for which there are pre-registered
|
||||
* custom serializers.
|
||||
*/
|
||||
abstract class Proxy<T, P>(protected val clazz: Class<T>,
|
||||
abstract class Proxy<T, P>(clazz: Class<T>,
|
||||
protected val proxyClass: Class<P>,
|
||||
protected val factory: SerializerFactory,
|
||||
val withInheritance: Boolean = true) : CustomSerializer<T>() {
|
||||
withInheritance: Boolean = true) : CustomSerializerImp<T>(clazz, withInheritance) {
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = if (withInheritance) this.clazz.isAssignableFrom(clazz) else this.clazz == clazz
|
||||
override val type: Type get() = clazz
|
||||
override val typeDescriptor: String = "$DESCRIPTOR_DOMAIN:${nameForType(clazz)}"
|
||||
override fun writeClassInfo(output: SerializationOutput) {}
|
||||
override val descriptor: Descriptor = Descriptor(typeDescriptor)
|
||||
|
||||
private val proxySerializer: ObjectSerializer by lazy { ObjectSerializer(proxyClass, factory) }
|
||||
|
||||
@ -152,26 +149,26 @@ abstract class CustomSerializer<T> : AMQPSerializer<T> {
|
||||
*/
|
||||
abstract class ToString<T>(clazz: Class<T>, withInheritance: Boolean = false,
|
||||
private val maker: (String) -> T = clazz.getConstructor(String::class.java).let {
|
||||
`constructor` -> { string -> `constructor`.newInstance(string) }
|
||||
`constructor` ->
|
||||
{ string -> `constructor`.newInstance(string) }
|
||||
},
|
||||
private val unmaker: (T) -> String = { obj -> obj.toString() }) : Proxy<T, String>(clazz, String::class.java, /* Unused */ SerializerFactoryFactory.get(), withInheritance) {
|
||||
private val unmaker: (T) -> String = { obj -> obj.toString() })
|
||||
: CustomSerializerImp<T>(clazz, withInheritance) {
|
||||
|
||||
override val additionalSerializers: Iterable<CustomSerializer<out Any>> = emptyList()
|
||||
|
||||
override val schemaForDocumentation = Schema(listOf(RestrictedType(nameForType(type), "", listOf(nameForType(type)), SerializerFactory.primitiveTypeName(String::class.java)!!, descriptor, emptyList())))
|
||||
|
||||
override fun toProxy(obj: T): String = unmaker(obj)
|
||||
|
||||
override fun fromProxy(proxy: String): T = maker(proxy)
|
||||
override val schemaForDocumentation = Schema(
|
||||
listOf(RestrictedType(nameForType(type), "", listOf(nameForType(type)),
|
||||
SerializerFactory.primitiveTypeName(String::class.java)!!,
|
||||
descriptor, emptyList())))
|
||||
|
||||
override fun writeDescribedObject(obj: T, data: Data, type: Type, output: SerializationOutput) {
|
||||
val proxy = toProxy(obj)
|
||||
data.putObject(proxy)
|
||||
data.putObject(unmaker(obj))
|
||||
}
|
||||
|
||||
override fun readObject(obj: Any, schema: Schema, input: DeserializationInput): T {
|
||||
val proxy = input.readObject(obj, schema, String::class.java) as String
|
||||
return fromProxy(proxy)
|
||||
return maker(proxy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ data class ObjectAndEnvelope<out T>(val obj: T, val envelope: Envelope)
|
||||
* @param serializerFactory This is the factory for [AMQPSerializer] instances and can be shared across multiple
|
||||
* instances and threads.
|
||||
*/
|
||||
class DeserializationInput(internal val serializerFactory: SerializerFactory = SerializerFactoryFactory.get()) {
|
||||
class DeserializationInput(internal val serializerFactory: SerializerFactory) {
|
||||
// TODO: we're not supporting object refs yet
|
||||
private val objectHistory: MutableList<Any> = ArrayList()
|
||||
|
||||
|
@ -14,7 +14,7 @@ import kotlin.collections.LinkedHashSet
|
||||
* @param serializerFactory This is the factory for [AMQPSerializer] instances and can be shared across multiple
|
||||
* instances and threads.
|
||||
*/
|
||||
open class SerializationOutput(internal val serializerFactory: SerializerFactory = SerializerFactoryFactory.get()) {
|
||||
open class SerializationOutput(internal val serializerFactory: SerializerFactory) {
|
||||
// TODO: we're not supporting object refs yet
|
||||
private val objectHistory: MutableMap<Any, Int> = IdentityHashMap()
|
||||
private val serializerHistory: MutableSet<AMQPSerializer<*>> = LinkedHashSet()
|
||||
|
@ -1,22 +0,0 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.ClassWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
|
||||
/**
|
||||
* Factory singleton that maps unique Serializer Factories from a pair of WhitleList and ClassLoader
|
||||
*/
|
||||
object SerializerFactoryFactory {
|
||||
val factories : MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory> = mutableMapOf()
|
||||
|
||||
fun get(context: SerializationContext) : SerializerFactory =
|
||||
factories.computeIfAbsent(Pair(context.whitelist, context.deserializationClassLoader)) {
|
||||
SerializerFactory(context.whitelist, context.deserializationClassLoader)
|
||||
}
|
||||
|
||||
fun get() : SerializerFactory =
|
||||
factories.computeIfAbsent(Pair(AllWhitelist, ClassLoader.getSystemClassLoader())) {
|
||||
SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
}
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import org.apache.qpid.proton.codec.Data
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
|
||||
fun testDefaultFactory() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
|
||||
class TestSerializationOutput(
|
||||
private val verbose: Boolean,
|
||||
serializerFactory: SerializerFactory = SerializerFactoryFactory.get()) : SerializationOutput(serializerFactory) {
|
||||
serializerFactory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()))
|
||||
: SerializationOutput(serializerFactory) {
|
||||
|
||||
override fun writeSchema(schema: Schema, data: Data) {
|
||||
if (verbose) println(schema)
|
||||
|
@ -18,7 +18,7 @@ class DeserializeAndReturnEnvelopeTests {
|
||||
|
||||
val a = A(10, "20")
|
||||
|
||||
val factory = SerializerFactoryFactory.get()
|
||||
val factory = testDefaultFactory()
|
||||
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||
|
||||
@ -34,7 +34,7 @@ class DeserializeAndReturnEnvelopeTests {
|
||||
|
||||
val b = B(A(10, "20"), 30.0F)
|
||||
|
||||
val factory = SerializerFactoryFactory.get()
|
||||
val factory = testDefaultFactory()
|
||||
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||
|
||||
|
@ -16,30 +16,30 @@ class DeserializeSimpleTypesTests {
|
||||
private const val VERBOSE = false
|
||||
}
|
||||
|
||||
val sf1 = SerializerFactory()
|
||||
val sf2 = SerializerFactory()
|
||||
val sf1 = testDefaultFactory()
|
||||
val sf2 = testDefaultFactory()
|
||||
|
||||
@Test
|
||||
fun testChar() {
|
||||
data class C(val c: Char)
|
||||
|
||||
var deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('c')))
|
||||
var deserializedC = DeserializationInput(sf).deserialize(SerializationOutput(sf).serialize(C('c')))
|
||||
assertEquals('c', deserializedC.c)
|
||||
|
||||
// CYRILLIC CAPITAL LETTER YU (U+042E)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('Ю')))
|
||||
deserializedC = DeserializationInput(sf).deserialize(SerializationOutput(sf).serialize(C('Ю')))
|
||||
assertEquals('Ю', deserializedC.c)
|
||||
|
||||
// ARABIC LETTER FEH WITH DOT BELOW (U+06A3)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('ڣ')))
|
||||
deserializedC = DeserializationInput(sf).deserialize(SerializationOutput(sf).serialize(C('ڣ')))
|
||||
assertEquals('ڣ', deserializedC.c)
|
||||
|
||||
// ARABIC LETTER DAD WITH DOT BELOW (U+06FB)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('ۻ')))
|
||||
deserializedC = DeserializationInput(sf).deserialize(SerializationOutput(sf).serialize(C('ۻ')))
|
||||
assertEquals('ۻ', deserializedC.c)
|
||||
|
||||
// BENGALI LETTER AA (U+0986)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('আ')))
|
||||
deserializedC = DeserializationInput(sf).deserialize(SerializationOutput(sf).serialize(C('আ')))
|
||||
assertEquals('আ', deserializedC.c)
|
||||
}
|
||||
|
||||
@ -49,8 +49,8 @@ class DeserializeSimpleTypesTests {
|
||||
data class C(val c: Character)
|
||||
|
||||
val c = C(Character('c'))
|
||||
val serialisedC = SerializationOutput().serialize(c)
|
||||
val deserializedC = DeserializationInput().deserialize(serialisedC)
|
||||
val serialisedC = SerializationOutput(sf).serialize(c)
|
||||
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
|
||||
|
||||
assertEquals(c.c, deserializedC.c)
|
||||
}
|
||||
@ -60,8 +60,8 @@ class DeserializeSimpleTypesTests {
|
||||
data class C(val c: Char?)
|
||||
|
||||
val c = C(null)
|
||||
val serialisedC = SerializationOutput().serialize(c)
|
||||
val deserializedC = DeserializationInput().deserialize(serialisedC)
|
||||
val serialisedC = SerializationOutput(sf).serialize(c)
|
||||
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
|
||||
|
||||
assertEquals(c.c, deserializedC.c)
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ import net.corda.nodeapi.RPCException
|
||||
import net.corda.nodeapi.internal.serialization.AbstractAMQPSerializationScheme
|
||||
import net.corda.nodeapi.internal.serialization.EmptyWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.isPrimitive
|
||||
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
|
||||
import net.corda.nodeapi.internal.serialization.AMQPServerSerializationScheme
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.testing.MEGA_CORP
|
||||
import net.corda.testing.MEGA_CORP_PUBKEY
|
||||
import org.apache.qpid.proton.amqp.*
|
||||
@ -135,7 +138,8 @@ class SerializationOutputTests {
|
||||
data class PolymorphicProperty(val foo: FooInterface?)
|
||||
|
||||
private fun serdes(obj: Any,
|
||||
factory: SerializerFactory = SerializerFactoryFactory.get(),
|
||||
factory: SerializerFactory = SerializerFactory (
|
||||
AllWhitelist, ClassLoader.getSystemClassLoader()),
|
||||
freshDeserializationFactory: SerializerFactory = SerializerFactory(
|
||||
AllWhitelist, ClassLoader.getSystemClassLoader()),
|
||||
expectedEqual: Boolean = true,
|
||||
@ -527,10 +531,10 @@ class SerializationOutputTests {
|
||||
fun `test transaction state`() {
|
||||
val state = TransactionState(FooState(), MEGA_CORP)
|
||||
|
||||
val factory = SerializerFactory()
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
AbstractAMQPSerializationScheme.registerCustomSerializers(factory)
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
AbstractAMQPSerializationScheme.registerCustomSerializers(factory2)
|
||||
|
||||
val desState = serdes(state, factory, factory2, expectedEqual = false, expectDeserializedEqual = false)
|
||||
|
@ -1,11 +1,8 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.amqp.*
|
||||
import net.corda.nodeapi.internal.serialization.amqp.Field
|
||||
import net.corda.nodeapi.internal.serialization.amqp.Schema
|
||||
import net.corda.nodeapi.internal.serialization.amqp.TypeNotation
|
||||
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializationOutput
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactoryFactory
|
||||
|
||||
fun mangleName(name: String) = "${name}__carpenter"
|
||||
|
||||
@ -37,7 +34,7 @@ fun Schema.mangleNames(names: List<String>): Schema {
|
||||
}
|
||||
|
||||
open class AmqpCarpenterBase {
|
||||
var factory = SerializerFactoryFactory.get()
|
||||
var factory = testDefaultFactory()
|
||||
|
||||
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
||||
fun testName(): String = Thread.currentThread().stackTrace[2].methodName
|
||||
|
Loading…
x
Reference in New Issue
Block a user