mirror of
https://github.com/corda/corda.git
synced 2025-01-18 10:46:38 +00:00
Merge pull request #1252 from corda/feature/kat/moveAMQPSerialiserTowardCommonInterface
Move AMQP serialiser toward common interface
This commit is contained in:
commit
2dc362a409
@ -41,7 +41,7 @@ abstract class AbstractAMQPSerializationScheme : SerializationScheme {
|
||||
rpcClientSerializerFactory(context)
|
||||
SerializationContext.UseCase.RPCServer ->
|
||||
rpcServerSerializerFactory(context)
|
||||
else -> SerializerFactory(context.whitelist) // TODO pass class loader also
|
||||
else -> SerializerFactory(context.whitelist, context.deserializationClassLoader)
|
||||
}
|
||||
}.also { registerCustomSerializers(it) }
|
||||
}
|
||||
|
@ -6,12 +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
|
||||
|
||||
/**
|
||||
* This [Kryo] custom [Serializer] switches the object graph of anything annotated with `@CordaSerializable`
|
||||
@ -34,4 +31,4 @@ class KryoAMQPSerializer(val serializationFactory: SerializationFactory, val ser
|
||||
input.readBytes(allBytes, peekedBytes.size, size - peekedBytes.size)
|
||||
return serializationFactory.deserialize(allBytes.sequence(), type, serializationContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) }
|
||||
|
||||
@ -151,25 +148,27 @@ abstract class CustomSerializer<T> : AMQPSerializer<T> {
|
||||
* @param unmake A lambda that extracts the string value for an instance, that defaults to the [toString] method.
|
||||
*/
|
||||
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) } },
|
||||
private val unmaker: (T) -> String = { obj -> obj.toString() }) : Proxy<T, String>(clazz, String::class.java, /* Unused */ SerializerFactory(), withInheritance) {
|
||||
private val maker: (String) -> T = clazz.getConstructor(String::class.java).let {
|
||||
`constructor` ->
|
||||
{ string -> `constructor`.newInstance(string) }
|
||||
},
|
||||
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 = SerializerFactory()) {
|
||||
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 = SerializerFactory()) {
|
||||
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()
|
||||
|
@ -4,7 +4,6 @@ import com.google.common.primitives.Primitives
|
||||
import com.google.common.reflect.TypeResolver
|
||||
import net.corda.core.serialization.ClassWhitelist
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.carpenter.CarpenterSchemas
|
||||
import net.corda.nodeapi.internal.serialization.carpenter.ClassCarpenter
|
||||
import net.corda.nodeapi.internal.serialization.carpenter.MetaCarpenter
|
||||
@ -44,11 +43,13 @@ import javax.annotation.concurrent.ThreadSafe
|
||||
// TODO: need to rethink matching of constructor to properties in relation to implementing interfaces and needing those properties etc.
|
||||
// TODO: need to support super classes as well as interfaces with our current code base... what's involved? If we continue to ban, what is the impact?
|
||||
@ThreadSafe
|
||||
class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
|
||||
class SerializerFactory(val whitelist: ClassWhitelist, cl : ClassLoader) {
|
||||
private val serializersByType = ConcurrentHashMap<Type, AMQPSerializer<Any>>()
|
||||
private val serializersByDescriptor = ConcurrentHashMap<Any, AMQPSerializer<Any>>()
|
||||
private val customSerializers = CopyOnWriteArrayList<CustomSerializer<out Any>>()
|
||||
private val classCarpenter = ClassCarpenter()
|
||||
private val classCarpenter = ClassCarpenter(cl)
|
||||
val classloader : ClassLoader
|
||||
get() = classCarpenter.classloader
|
||||
|
||||
/**
|
||||
* Look up, and manufacture if necessary, a serializer for the given type.
|
||||
@ -176,15 +177,18 @@ class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun processSchema(schema: Schema, sentinal: Boolean = false) {
|
||||
/**
|
||||
* Iterate over an AMQP schema, for each type ascertain weather it's on ClassPath of [classloader] amd
|
||||
* if not use the [ClassCarpenter] to generate a class to use in it's place
|
||||
*/
|
||||
private fun processSchema(schema: Schema, sentinel: Boolean = false) {
|
||||
val carpenterSchemas = CarpenterSchemas.newInstance()
|
||||
for (typeNotation in schema.types) {
|
||||
try {
|
||||
processSchemaEntry(typeNotation, classCarpenter.classloader)
|
||||
processSchemaEntry(typeNotation)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
if (sentinal || (typeNotation !is CompositeType)) throw e
|
||||
typeNotation.carpenterSchema(
|
||||
classLoaders = listOf(classCarpenter.classloader), carpenterSchemas = carpenterSchemas)
|
||||
if (sentinel || (typeNotation !is CompositeType)) throw e
|
||||
typeNotation.carpenterSchema(classloader, carpenterSchemas = carpenterSchemas)
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,24 +199,22 @@ class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun processSchemaEntry(typeNotation: TypeNotation,
|
||||
cl: ClassLoader = DeserializedParameterizedType::class.java.classLoader) {
|
||||
private fun processSchemaEntry(typeNotation: TypeNotation) {
|
||||
when (typeNotation) {
|
||||
is CompositeType -> processCompositeType(typeNotation, cl) // java.lang.Class (whether a class or interface)
|
||||
is CompositeType -> processCompositeType(typeNotation) // java.lang.Class (whether a class or interface)
|
||||
is RestrictedType -> processRestrictedType(typeNotation) // Collection / Map, possibly with generics
|
||||
}
|
||||
}
|
||||
|
||||
private fun processRestrictedType(typeNotation: RestrictedType) {
|
||||
// TODO: class loader logic, and compare the schema.
|
||||
val type = typeForName(typeNotation.name)
|
||||
val type = typeForName(typeNotation.name, classloader)
|
||||
get(null, type)
|
||||
}
|
||||
|
||||
private fun processCompositeType(typeNotation: CompositeType,
|
||||
cl: ClassLoader = DeserializedParameterizedType::class.java.classLoader) {
|
||||
private fun processCompositeType(typeNotation: CompositeType) {
|
||||
// TODO: class loader logic, and compare the schema.
|
||||
val type = typeForName(typeNotation.name, cl)
|
||||
val type = typeForName(typeNotation.name, classloader)
|
||||
get(type.asClass() ?: throw NotSerializableException("Unable to build composite type for $type"), type)
|
||||
}
|
||||
|
||||
@ -322,11 +324,9 @@ class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
|
||||
else -> throw NotSerializableException("Unable to render type $type to a string.")
|
||||
}
|
||||
|
||||
private fun typeForName(
|
||||
name: String,
|
||||
cl: ClassLoader = DeserializedParameterizedType::class.java.classLoader): Type {
|
||||
private fun typeForName(name: String, classloader: ClassLoader): Type {
|
||||
return if (name.endsWith("[]")) {
|
||||
val elementType = typeForName(name.substring(0, name.lastIndex - 1))
|
||||
val elementType = typeForName(name.substring(0, name.lastIndex - 1), classloader)
|
||||
if (elementType is ParameterizedType || elementType is GenericArrayType) {
|
||||
DeserializedGenericArrayType(elementType)
|
||||
} else if (elementType is Class<*>) {
|
||||
@ -349,7 +349,7 @@ class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
|
||||
else -> throw NotSerializableException("Not able to deserialize array type: $name")
|
||||
}
|
||||
} else {
|
||||
DeserializedParameterizedType.make(name, cl)
|
||||
DeserializedParameterizedType.make(name, classloader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,11 @@ import net.corda.nodeapi.internal.serialization.amqp.CompositeType
|
||||
import net.corda.nodeapi.internal.serialization.amqp.Field as AMQPField
|
||||
import net.corda.nodeapi.internal.serialization.amqp.Schema as AMQPSchema
|
||||
|
||||
fun AMQPSchema.carpenterSchema(
|
||||
loaders: List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader()))
|
||||
: CarpenterSchemas {
|
||||
fun AMQPSchema.carpenterSchema(classloader: ClassLoader) : CarpenterSchemas {
|
||||
val rtn = CarpenterSchemas.newInstance()
|
||||
|
||||
types.filterIsInstance<CompositeType>().forEach {
|
||||
it.carpenterSchema(classLoaders = loaders, carpenterSchemas = rtn)
|
||||
it.carpenterSchema(classloader, carpenterSchemas = rtn)
|
||||
}
|
||||
|
||||
return rtn
|
||||
@ -19,10 +17,9 @@ fun AMQPSchema.carpenterSchema(
|
||||
/**
|
||||
* if we can load the class then we MUST know about all of it's composite elements
|
||||
*/
|
||||
private fun CompositeType.validatePropertyTypes(
|
||||
classLoaders: List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader())) {
|
||||
private fun CompositeType.validatePropertyTypes(classloader: ClassLoader) {
|
||||
fields.forEach {
|
||||
if (!it.validateType(classLoaders)) throw UncarpentableException(name, it.name, it.type)
|
||||
if (!it.validateType(classloader)) throw UncarpentableException(name, it.name, it.type)
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,24 +31,21 @@ fun AMQPField.typeAsString() = if (type == "*") requires[0] else type
|
||||
* b) add the class to the dependency tree in [carpenterSchemas] if it cannot be instantiated
|
||||
* at this time
|
||||
*
|
||||
* @param classLoaders list of classLoaders, defaulting toe the system class loader, that might
|
||||
* be used to load objects
|
||||
* @param classloader the class loader provided dby the [SerializationContext]
|
||||
* @param carpenterSchemas structure that holds the dependency tree and list of classes that
|
||||
* need constructing
|
||||
* @param force by default a schema is not added to [carpenterSchemas] if it already exists
|
||||
* on the class path. For testing purposes schema generation can be forced
|
||||
*/
|
||||
fun CompositeType.carpenterSchema(
|
||||
classLoaders: List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader()),
|
||||
carpenterSchemas: CarpenterSchemas,
|
||||
force: Boolean = false) {
|
||||
if (classLoaders.exists(name)) {
|
||||
validatePropertyTypes(classLoaders)
|
||||
fun CompositeType.carpenterSchema(classloader: ClassLoader,
|
||||
carpenterSchemas: CarpenterSchemas,
|
||||
force: Boolean = false) {
|
||||
if (classloader.exists(name)) {
|
||||
validatePropertyTypes(classloader)
|
||||
if (!force) return
|
||||
}
|
||||
|
||||
val providesList = mutableListOf<Class<*>>()
|
||||
|
||||
var isInterface = false
|
||||
var isCreatable = true
|
||||
|
||||
@ -62,7 +56,7 @@ fun CompositeType.carpenterSchema(
|
||||
}
|
||||
|
||||
try {
|
||||
providesList.add(classLoaders.loadIfExists(it))
|
||||
providesList.add(classloader.loadClass(it))
|
||||
} catch (e: ClassNotFoundException) {
|
||||
carpenterSchemas.addDepPair(this, name, it)
|
||||
isCreatable = false
|
||||
@ -73,7 +67,7 @@ fun CompositeType.carpenterSchema(
|
||||
|
||||
fields.forEach {
|
||||
try {
|
||||
m[it.name] = FieldFactory.newInstance(it.mandatory, it.name, it.getTypeAsClass(classLoaders))
|
||||
m[it.name] = FieldFactory.newInstance(it.mandatory, it.name, it.getTypeAsClass(classloader))
|
||||
} catch (e: ClassNotFoundException) {
|
||||
carpenterSchemas.addDepPair(this, name, it.typeAsString())
|
||||
isCreatable = false
|
||||
@ -110,33 +104,18 @@ val typeStrToType: Map<Pair<String, Boolean>, Class<out Any?>> = mapOf(
|
||||
Pair("byte", false) to Byte::class.javaObjectType
|
||||
)
|
||||
|
||||
fun AMQPField.getTypeAsClass(
|
||||
classLoaders: List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader())
|
||||
) = typeStrToType[Pair(type, mandatory)] ?: when (type) {
|
||||
fun AMQPField.getTypeAsClass(classloader: ClassLoader) = typeStrToType[Pair(type, mandatory)] ?: when (type) {
|
||||
"string" -> String::class.java
|
||||
"*" -> classLoaders.loadIfExists(requires[0])
|
||||
else -> classLoaders.loadIfExists(type)
|
||||
"*" -> classloader.loadClass(requires[0])
|
||||
else -> classloader.loadClass(type)
|
||||
}
|
||||
|
||||
fun AMQPField.validateType(
|
||||
classLoaders: List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader())
|
||||
) = when (type) {
|
||||
fun AMQPField.validateType(classloader: ClassLoader) = when (type) {
|
||||
"byte", "int", "string", "short", "long", "char", "boolean", "double", "float" -> true
|
||||
"*" -> classLoaders.exists(requires[0])
|
||||
else -> classLoaders.exists(type)
|
||||
"*" -> classloader.exists(requires[0])
|
||||
else -> classloader.exists(type)
|
||||
}
|
||||
|
||||
private fun List<ClassLoader>.exists(clazz: String) = this.find {
|
||||
try { it.loadClass(clazz); true } catch (e: ClassNotFoundException) { false }
|
||||
} != null
|
||||
private fun ClassLoader.exists(clazz: String) = run {
|
||||
try { this.loadClass(clazz); true } catch (e: ClassNotFoundException) { false } }
|
||||
|
||||
private fun List<ClassLoader>.loadIfExists(clazz: String): Class<*> {
|
||||
this.forEach {
|
||||
try {
|
||||
return it.loadClass(clazz)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
throw ClassNotFoundException(clazz)
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ interface SimpleFieldAccess {
|
||||
operator fun get(name: String): Any?
|
||||
}
|
||||
|
||||
class CarpenterClassLoader : ClassLoader(Thread.currentThread().contextClassLoader) {
|
||||
class CarpenterClassLoader (parentClassLoader: ClassLoader = Thread.currentThread().contextClassLoader) :
|
||||
ClassLoader(parentClassLoader) {
|
||||
fun load(name: String, bytes: ByteArray) = defineClass(name, bytes, 0, bytes.size)
|
||||
}
|
||||
|
||||
@ -66,14 +67,14 @@ class CarpenterClassLoader : ClassLoader(Thread.currentThread().contextClassLoad
|
||||
*
|
||||
* Equals/hashCode methods are not yet supported.
|
||||
*/
|
||||
class ClassCarpenter {
|
||||
class ClassCarpenter(cl: ClassLoader = Thread.currentThread().contextClassLoader) {
|
||||
// TODO: Generics.
|
||||
// TODO: Sandbox the generated code when a security manager is in use.
|
||||
// TODO: Generate equals/hashCode.
|
||||
// TODO: Support annotations.
|
||||
// TODO: isFoo getter patterns for booleans (this is what Kotlin generates)
|
||||
|
||||
val classloader = CarpenterClassLoader()
|
||||
val classloader = CarpenterClassLoader(cl)
|
||||
|
||||
private val _loaded = HashMap<String, Class<*>>()
|
||||
private val String.jvm: String get() = replace(".", "/")
|
||||
|
@ -73,9 +73,7 @@ abstract class MetaCarpenterBase (val schemas : CarpenterSchemas, val cc : Class
|
||||
// we're out of blockers so we can now create the type
|
||||
if (schemas.dependencies[dependent]?.second?.isEmpty() ?: false) {
|
||||
(schemas.dependencies.remove (dependent)?.first as CompositeType).carpenterSchema (
|
||||
classLoaders = listOf<ClassLoader> (
|
||||
ClassLoader.getSystemClassLoader(),
|
||||
cc.classloader),
|
||||
classloader = cc.classloader,
|
||||
carpenterSchemas = schemas)
|
||||
}
|
||||
}
|
||||
|
@ -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 = SerializerFactory()) : 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 = SerializerFactory()
|
||||
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 = SerializerFactory()
|
||||
val factory = testDefaultFactory()
|
||||
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||
|
||||
|
@ -8,7 +8,7 @@ import net.corda.nodeapi.internal.serialization.carpenter.*
|
||||
// those classes don't exist within the system's Class Loader the deserialiser will be forced to carpent
|
||||
// versions of them up using its own internal class carpenter (each carpenter houses it's own loader). This
|
||||
// replicates the situation where a receiver doesn't have some or all elements of a schema present on it's classpath
|
||||
class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
companion object {
|
||||
/**
|
||||
* If you want to see the schema encoded into the envelope after serialisation change this to true
|
||||
@ -16,12 +16,12 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
private const val VERBOSE = false
|
||||
}
|
||||
|
||||
val sf = SerializerFactory()
|
||||
val sf2 = SerializerFactory()
|
||||
val sf = testDefaultFactory()
|
||||
val sf2 = testDefaultFactory()
|
||||
|
||||
@Test
|
||||
fun singleInt() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"int" to NonNullableField(Integer::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -41,7 +41,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleIntNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"int" to NullableField(Integer::class.java)
|
||||
)))
|
||||
|
||||
@ -57,7 +57,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleIntNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"int" to NullableField(Integer::class.java)
|
||||
)))
|
||||
|
||||
@ -73,7 +73,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleChar() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"char" to NonNullableField(Character::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -86,7 +86,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleCharNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"char" to NullableField(Character::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -99,7 +99,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleCharNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"char" to NullableField(java.lang.Character::class.java)
|
||||
)))
|
||||
|
||||
@ -112,7 +112,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleLong() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"long" to NonNullableField(Long::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -126,7 +126,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleLongNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"long" to NullableField(Long::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -140,7 +140,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleLongNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"long" to NullableField(Long::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -153,7 +153,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleBoolean() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"boolean" to NonNullableField(Boolean::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -166,7 +166,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleBooleanNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"boolean" to NullableField(Boolean::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -179,7 +179,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleBooleanNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"boolean" to NullableField(Boolean::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -192,7 +192,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleDouble() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"double" to NonNullableField(Double::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -205,7 +205,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleDoubleNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"double" to NullableField(Double::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -218,7 +218,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleDoubleNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"double" to NullableField(Double::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -231,7 +231,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleShort() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"short" to NonNullableField(Short::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -244,7 +244,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleShortNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"short" to NullableField(Short::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -257,7 +257,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleShortNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"short" to NullableField(Short::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -270,7 +270,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleFloat() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"float" to NonNullableField(Float::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -283,7 +283,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleFloatNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"float" to NullableField(Float::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -296,7 +296,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleFloatNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"float" to NullableField(Float::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -309,7 +309,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleByte() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"byte" to NonNullableField(Byte::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -324,7 +324,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleByteNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"byte" to NullableField(Byte::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -339,7 +339,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun singleByteNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("single", mapOf(
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
"byte" to NullableField(Byte::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -353,11 +353,10 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
@Test
|
||||
fun simpleTypeKnownInterface() {
|
||||
val clazz = ClassCarpenter().build (ClassSchema(
|
||||
"oneType", mapOf("name" to NonNullableField(String::class.java)),
|
||||
testName(), mapOf("name" to NonNullableField(String::class.java)),
|
||||
interfaces = listOf (I::class.java)))
|
||||
val testVal = "Some Person"
|
||||
val classInstance = clazz.constructors[0].newInstance(testVal)
|
||||
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(classInstance)
|
||||
val deserializedObj = DeserializationInput(sf2).deserialize(serialisedBytes)
|
||||
|
||||
@ -368,7 +367,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
|
||||
@Test
|
||||
fun manyTypes() {
|
||||
val manyClass = ClassCarpenter().build (ClassSchema("many", mapOf(
|
||||
val manyClass = ClassCarpenter().build (ClassSchema(testName(), mapOf(
|
||||
"intA" to NonNullableField (Int::class.java),
|
||||
"intB" to NullableField (Integer::class.java),
|
||||
"intC" to NullableField (Integer::class.java),
|
||||
@ -397,7 +396,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest {
|
||||
"byteB" to NullableField (Byte::class.javaObjectType),
|
||||
"byteC" to NullableField (Byte::class.javaObjectType))))
|
||||
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, factory).serialize(
|
||||
manyClass.constructors.first().newInstance(
|
||||
1, 2, null,
|
||||
"a", "b", null,
|
||||
|
@ -3,22 +3,21 @@ package net.corda.nodeapi.internal.serialization.amqp
|
||||
import org.junit.Test
|
||||
import kotlin.test.*
|
||||
import net.corda.nodeapi.internal.serialization.carpenter.*
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
|
||||
interface I {
|
||||
fun getName() : String
|
||||
}
|
||||
|
||||
/**
|
||||
* These tests work by having the class carpenter build the classes we serialise and then deserialise them
|
||||
* within the context of a second serialiser factory. The second factory is required as the first, having
|
||||
* been used to serialise the class, will have cached a copy of the class and will thus bypass the need
|
||||
* to pull it out of the class loader.
|
||||
*
|
||||
* However, those classes don't exist within the system's Class Loader and thus the deserialiser will be forced
|
||||
* to carpent versions of them up using its own internal class carpenter (each carpenter houses it's own loader). This
|
||||
* replicates the situation where a receiver doesn't have some or all elements of a schema present on it's classpath
|
||||
*/
|
||||
class DeserializeNeedingCarpentryTests {
|
||||
// These tests work by having the class carpenter build the classes we serialise and then deserialise them
|
||||
// within the context of a second serialiser factory. The second factory is required as the first, having
|
||||
// been used to serialise the class, will have cached a copy of the class and will thus bypass the need
|
||||
// to pull it out of the class loader.
|
||||
//
|
||||
// However, those classes don't exist within the system's Class Loader and thus the deserialiser will be forced
|
||||
// to carpent versions of them up using its own internal class carpenter (each carpenter houses it's own loader). This
|
||||
// replicates the situation where a receiver doesn't have some or all elements of a schema present on it's classpath
|
||||
class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
companion object {
|
||||
/**
|
||||
* If you want to see the schema encoded into the envelope after serialisation change this to true
|
||||
@ -26,13 +25,13 @@ class DeserializeNeedingCarpentryTests {
|
||||
private const val VERBOSE = false
|
||||
}
|
||||
|
||||
val sf1 = SerializerFactory()
|
||||
val sf2 = SerializerFactory()
|
||||
val sf1 = testDefaultFactory()
|
||||
val sf2 = testDefaultFactory()
|
||||
|
||||
@Test
|
||||
fun verySimpleType() {
|
||||
val testVal = 10
|
||||
val clazz = ClassCarpenter().build(ClassSchema("oneType", mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val classInstance = clazz.constructors[0].newInstance(testVal)
|
||||
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf1).serialize(classInstance)
|
||||
@ -66,16 +65,20 @@ class DeserializeNeedingCarpentryTests {
|
||||
val testValA = 10
|
||||
val testValB = 20
|
||||
val testValC = 20
|
||||
val clazz = ClassCarpenter().build(ClassSchema("oneType", mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val clazz = ClassCarpenter().build(ClassSchema("${testName()}_clazz",
|
||||
mapOf("a" to NonNullableField(Int::class.java))))
|
||||
|
||||
val concreteA = clazz.constructors[0].newInstance(testValA)
|
||||
val concreteB = clazz.constructors[0].newInstance(testValB)
|
||||
val concreteC = clazz.constructors[0].newInstance(testValC)
|
||||
|
||||
val deserialisedA = DeserializationInput(sf2).deserialize(TestSerializationOutput(VERBOSE, sf1).serialize(concreteA))
|
||||
val deserialisedA = DeserializationInput(sf2).deserialize(
|
||||
TestSerializationOutput(VERBOSE, sf1).serialize(concreteA))
|
||||
|
||||
assertEquals (testValA, deserialisedA::class.java.getMethod("getA").invoke(deserialisedA))
|
||||
|
||||
val deserialisedB = DeserializationInput(sf2).deserialize(TestSerializationOutput(VERBOSE, sf1).serialize(concreteB))
|
||||
val deserialisedB = DeserializationInput(sf2).deserialize(
|
||||
TestSerializationOutput(VERBOSE, sf1).serialize(concreteB))
|
||||
|
||||
assertEquals (testValB, deserialisedA::class.java.getMethod("getA").invoke(deserialisedB))
|
||||
assertEquals (deserialisedA::class.java, deserialisedB::class.java)
|
||||
@ -84,8 +87,10 @@ class DeserializeNeedingCarpentryTests {
|
||||
// won't already exist and it will be carpented a second time showing that when A and B are the
|
||||
// same underlying class that we didn't create a second instance of the class with the
|
||||
// second deserialisation
|
||||
val lsf = SerializerFactory()
|
||||
val deserialisedC = DeserializationInput(lsf).deserialize(TestSerializationOutput(VERBOSE, lsf).serialize(concreteC))
|
||||
val lfactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
val deserialisedC = DeserializationInput(lfactory).deserialize(
|
||||
TestSerializationOutput(VERBOSE, lfactory).serialize(concreteC))
|
||||
|
||||
assertEquals (testValC, deserialisedC::class.java.getMethod("getA").invoke(deserialisedC))
|
||||
assertNotEquals (deserialisedA::class.java, deserialisedC::class.java)
|
||||
assertNotEquals (deserialisedB::class.java, deserialisedC::class.java)
|
||||
@ -94,7 +99,7 @@ class DeserializeNeedingCarpentryTests {
|
||||
@Test
|
||||
fun simpleTypeKnownInterface() {
|
||||
val clazz = ClassCarpenter().build (ClassSchema(
|
||||
"oneType", mapOf("name" to NonNullableField(String::class.java)),
|
||||
testName(), mapOf("name" to NonNullableField(String::class.java)),
|
||||
interfaces = listOf (I::class.java)))
|
||||
val testVal = "Some Person"
|
||||
val classInstance = clazz.constructors[0].newInstance(testVal)
|
||||
@ -108,7 +113,7 @@ class DeserializeNeedingCarpentryTests {
|
||||
|
||||
@Test
|
||||
fun arrayOfTypes() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema("oneType", mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf("a" to NonNullableField(Int::class.java))))
|
||||
|
||||
data class Outer (val a : Array<Any>)
|
||||
|
||||
@ -142,8 +147,8 @@ class DeserializeNeedingCarpentryTests {
|
||||
fun reusedClasses() {
|
||||
val cc = ClassCarpenter()
|
||||
|
||||
val innerType = cc.build(ClassSchema("inner", mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val outerType = cc.build(ClassSchema("outer", mapOf("a" to NonNullableField(innerType))))
|
||||
val innerType = cc.build(ClassSchema("${testName()}.inner", mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val outerType = cc.build(ClassSchema("${testName()}.outer", mapOf("a" to NonNullableField(innerType))))
|
||||
val inner = innerType.constructors[0].newInstance(1)
|
||||
val outer = outerType.constructors[0].newInstance(innerType.constructors[0].newInstance(2))
|
||||
|
||||
@ -195,7 +200,7 @@ class DeserializeNeedingCarpentryTests {
|
||||
|
||||
@Test
|
||||
fun listOfType() {
|
||||
val unknownClass = ClassCarpenter().build (ClassSchema("unknownClass", mapOf(
|
||||
val unknownClass = ClassCarpenter().build (ClassSchema(testName(), mapOf(
|
||||
"v1" to NonNullableField(Int::class.java),
|
||||
"v2" to NonNullableField(Int::class.java))))
|
||||
|
||||
@ -223,7 +228,7 @@ class DeserializeNeedingCarpentryTests {
|
||||
"gen.Interface",
|
||||
mapOf("age" to NonNullableField (Int::class.java))))
|
||||
|
||||
val concreteClass = cc.build (ClassSchema ("gen.Class", mapOf(
|
||||
val concreteClass = cc.build (ClassSchema (testName(), mapOf(
|
||||
"age" to NonNullableField (Int::class.java),
|
||||
"name" to NonNullableField(String::class.java)),
|
||||
interfaces = listOf (I::class.java, interfaceClass)))
|
||||
|
@ -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(sf1).deserialize(SerializationOutput(sf1).serialize(C('c')))
|
||||
assertEquals('c', deserializedC.c)
|
||||
|
||||
// CYRILLIC CAPITAL LETTER YU (U+042E)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('Ю')))
|
||||
deserializedC = DeserializationInput(sf1).deserialize(SerializationOutput(sf1).serialize(C('Ю')))
|
||||
assertEquals('Ю', deserializedC.c)
|
||||
|
||||
// ARABIC LETTER FEH WITH DOT BELOW (U+06A3)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('ڣ')))
|
||||
deserializedC = DeserializationInput(sf1).deserialize(SerializationOutput(sf1).serialize(C('ڣ')))
|
||||
assertEquals('ڣ', deserializedC.c)
|
||||
|
||||
// ARABIC LETTER DAD WITH DOT BELOW (U+06FB)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('ۻ')))
|
||||
deserializedC = DeserializationInput(sf1).deserialize(SerializationOutput(sf1).serialize(C('ۻ')))
|
||||
assertEquals('ۻ', deserializedC.c)
|
||||
|
||||
// BENGALI LETTER AA (U+0986)
|
||||
deserializedC = DeserializationInput().deserialize(SerializationOutput().serialize(C('আ')))
|
||||
deserializedC = DeserializationInput(sf1).deserialize(SerializationOutput(sf1).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(sf1).serialize(c)
|
||||
val deserializedC = DeserializationInput(sf1).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(sf1).serialize(c)
|
||||
val deserializedC = DeserializationInput(sf1).deserialize(serialisedC)
|
||||
|
||||
assertEquals(c.c, deserializedC.c)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp;
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist;
|
||||
import net.corda.core.serialization.SerializedBytes;
|
||||
import org.apache.qpid.proton.codec.DecoderImpl;
|
||||
import org.apache.qpid.proton.codec.EncoderImpl;
|
||||
@ -167,7 +168,7 @@ public class JavaSerializationOutputTests {
|
||||
}
|
||||
|
||||
private Object serdes(Object obj) throws NotSerializableException {
|
||||
SerializerFactory factory = new SerializerFactory();
|
||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader());
|
||||
SerializationOutput ser = new SerializationOutput(factory);
|
||||
SerializedBytes<Object> bytes = ser.serialize(obj);
|
||||
|
||||
|
@ -14,7 +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.amqp.custom.*
|
||||
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.*
|
||||
@ -136,8 +138,10 @@ class SerializationOutputTests {
|
||||
data class PolymorphicProperty(val foo: FooInterface?)
|
||||
|
||||
private fun serdes(obj: Any,
|
||||
factory: SerializerFactory = SerializerFactory(),
|
||||
freshDeserializationFactory: SerializerFactory = SerializerFactory(),
|
||||
factory: SerializerFactory = SerializerFactory (
|
||||
AllWhitelist, ClassLoader.getSystemClassLoader()),
|
||||
freshDeserializationFactory: SerializerFactory = SerializerFactory(
|
||||
AllWhitelist, ClassLoader.getSystemClassLoader()),
|
||||
expectedEqual: Boolean = true,
|
||||
expectDeserializedEqual: Boolean = true): Any {
|
||||
val ser = SerializationOutput(factory)
|
||||
@ -285,13 +289,13 @@ class SerializationOutputTests {
|
||||
@Test(expected = NotSerializableException::class)
|
||||
fun `test whitelist`() {
|
||||
val obj = Woo2(4)
|
||||
serdes(obj, SerializerFactory(EmptyWhitelist))
|
||||
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test annotation whitelisting`() {
|
||||
val obj = AnnotatedWoo(5)
|
||||
serdes(obj, SerializerFactory(EmptyWhitelist))
|
||||
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()))
|
||||
}
|
||||
|
||||
@Test(expected = NotSerializableException::class)
|
||||
@ -387,10 +391,10 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test custom serializers on public key`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(PublicKeySerializer)
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(PublicKeySerializer)
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.PublicKeySerializer)
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.PublicKeySerializer)
|
||||
val obj = MEGA_CORP_PUBKEY
|
||||
serdes(obj, factory, factory2)
|
||||
}
|
||||
@ -398,16 +402,16 @@ class SerializationOutputTests {
|
||||
@Test
|
||||
fun `test annotation is inherited`() {
|
||||
val obj = InheritAnnotation("blah")
|
||||
serdes(obj, SerializerFactory(EmptyWhitelist))
|
||||
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test throwables serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(ThrowableSerializer(factory))
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(ThrowableSerializer(factory2))
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
val t = IllegalAccessException("message").fillInStackTrace()
|
||||
val desThrowable = serdes(t, factory, factory2, false) as Throwable
|
||||
@ -416,11 +420,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test complex throwables serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(ThrowableSerializer(factory))
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(ThrowableSerializer(factory2))
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
try {
|
||||
try {
|
||||
@ -447,11 +451,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test suppressed throwables serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(ThrowableSerializer(factory))
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(ThrowableSerializer(factory2))
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
try {
|
||||
try {
|
||||
@ -469,11 +473,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test flow corda exception subclasses serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(ThrowableSerializer(factory))
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(ThrowableSerializer(factory2))
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
val obj = FlowException("message").fillInStackTrace()
|
||||
serdes(obj, factory, factory2)
|
||||
@ -481,11 +485,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test RPC corda exception subclasses serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(ThrowableSerializer(factory))
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(ThrowableSerializer(factory2))
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
val obj = RPCException("message").fillInStackTrace()
|
||||
serdes(obj, factory, factory2)
|
||||
@ -525,12 +529,12 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test transaction state`() {
|
||||
val state = TransactionState<FooState>(FooState(), MEGA_CORP)
|
||||
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)
|
||||
@ -542,11 +546,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test currencies serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(CurrencySerializer)
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.CurrencySerializer)
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(CurrencySerializer)
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.CurrencySerializer)
|
||||
|
||||
val obj = Currency.getInstance("USD")
|
||||
serdes(obj, factory, factory2)
|
||||
@ -554,11 +558,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test big decimals serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(BigDecimalSerializer)
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.BigDecimalSerializer)
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(BigDecimalSerializer)
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.BigDecimalSerializer)
|
||||
|
||||
val obj = BigDecimal("100000000000000000000000000000.00")
|
||||
serdes(obj, factory, factory2)
|
||||
@ -566,11 +570,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test instants serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(InstantSerializer(factory))
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.InstantSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(InstantSerializer(factory2))
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.InstantSerializer(factory2))
|
||||
|
||||
val obj = Instant.now()
|
||||
serdes(obj, factory, factory2)
|
||||
@ -578,11 +582,11 @@ class SerializationOutputTests {
|
||||
|
||||
@Test
|
||||
fun `test StateRef serialize`() {
|
||||
val factory = SerializerFactory()
|
||||
factory.register(InstantSerializer(factory))
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.InstantSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory()
|
||||
factory2.register(InstantSerializer(factory2))
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.InstantSerializer(factory2))
|
||||
|
||||
val obj = StateRef(SecureHash.randomSHA256(), 0)
|
||||
serdes(obj, factory, factory2)
|
||||
|
@ -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.SerializerFactory
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializationOutput
|
||||
|
||||
fun mangleName(name: String) = "${name}__carpenter"
|
||||
|
||||
@ -37,7 +34,7 @@ fun Schema.mangleNames(names: List<String>): Schema {
|
||||
}
|
||||
|
||||
open class AmqpCarpenterBase {
|
||||
var factory = SerializerFactory()
|
||||
var factory = testDefaultFactory()
|
||||
|
||||
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
||||
fun testName(): String = Thread.currentThread().stackTrace[2].methodName
|
||||
|
@ -63,7 +63,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
assertEquals("b", amqpSchemaB.fields[1].name)
|
||||
assertEquals("int", amqpSchemaB.fields[1].type)
|
||||
|
||||
val metaSchema = obj.envelope.schema.carpenterSchema()
|
||||
val metaSchema = obj.envelope.schema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// if we know all the classes there is nothing to really achieve here
|
||||
assert(metaSchema.carpenterSchemas.isEmpty())
|
||||
@ -92,7 +92,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
|
||||
assert(obj.obj is B)
|
||||
|
||||
amqpSchema.carpenterSchema()
|
||||
amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -112,7 +112,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
assert(obj.obj is B)
|
||||
|
||||
val amqpSchema = obj.envelope.schema.mangleNames(listOf(classTestName("B")))
|
||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||
val carpenterSchema = amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
assertEquals(1, carpenterSchema.size)
|
||||
|
||||
@ -140,7 +140,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
assert(obj.obj is B)
|
||||
|
||||
val amqpSchema = obj.envelope.schema.mangleNames(listOf(classTestName("A"), classTestName("B")))
|
||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||
val carpenterSchema = amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// just verify we're in the expected initial state, A is carpentable, B is not because
|
||||
// it depends on A and the dependency chains are in place
|
||||
@ -200,7 +200,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
|
||||
val amqpSchema = obj.envelope.schema.mangleNames(listOf(classTestName("A"), classTestName("B")))
|
||||
|
||||
amqpSchema.carpenterSchema()
|
||||
amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
}
|
||||
|
||||
@Test(expected = UncarpentableException::class)
|
||||
@ -226,7 +226,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
|
||||
val amqpSchema = obj.envelope.schema.mangleNames(listOf(classTestName("A"), classTestName("B")))
|
||||
|
||||
amqpSchema.carpenterSchema()
|
||||
amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
}
|
||||
|
||||
@Suppress("UNUSED")
|
||||
@ -251,7 +251,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
assert(obj.obj is C)
|
||||
|
||||
val carpenterSchema = obj.envelope.schema.mangleNames(listOf(classTestName("A"), classTestName("B")))
|
||||
TestMetaCarpenter(carpenterSchema.carpenterSchema())
|
||||
TestMetaCarpenter(carpenterSchema.carpenterSchema(ClassLoader.getSystemClassLoader()))
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -45,14 +45,14 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertTrue(obj.obj is A)
|
||||
val serSchema = obj.envelope.schema
|
||||
assertEquals(2, serSchema.types.size)
|
||||
val l1 = serSchema.carpenterSchema()
|
||||
val l1 = serSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// since we're using an envelope generated by seilaising classes defined locally
|
||||
// it's extremely unlikely we'd need to carpent any classes
|
||||
assertEquals(0, l1.size)
|
||||
|
||||
val mangleSchema = serSchema.mangleNames(listOf(classTestName("A")))
|
||||
val l2 = mangleSchema.carpenterSchema()
|
||||
val l2 = mangleSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
assertEquals(1, l2.size)
|
||||
|
||||
val aSchema = l2.carpenterSchemas.find { it.name == mangleName(classTestName("A")) }
|
||||
@ -88,13 +88,13 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
|
||||
assertEquals(2, serSchema.types.size)
|
||||
|
||||
val l1 = serSchema.carpenterSchema()
|
||||
val l1 = serSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
assertEquals(0, l1.size)
|
||||
|
||||
val mangleSchema = serSchema.mangleNames(listOf(classTestName("A")))
|
||||
val aName = mangleName(classTestName("A"))
|
||||
val l2 = mangleSchema.carpenterSchema()
|
||||
val l2 = mangleSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
assertEquals(1, l2.size)
|
||||
|
||||
@ -132,7 +132,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
|
||||
assertEquals(3, serSchema.types.size)
|
||||
|
||||
val l1 = serSchema.carpenterSchema()
|
||||
val l1 = serSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// since we're using an envelope generated by serialising classes defined locally
|
||||
// it's extremely unlikely we'd need to carpent any classes
|
||||
@ -141,7 +141,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
// pretend we don't know the class we've been sent, i.e. it's unknown to the class loader, and thus
|
||||
// needs some carpentry
|
||||
val mangleSchema = serSchema.mangleNames(listOf(classTestName("A")))
|
||||
val l2 = mangleSchema.carpenterSchema()
|
||||
val l2 = mangleSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
val aName = mangleName(classTestName("A"))
|
||||
|
||||
assertEquals(1, l2.size)
|
||||
@ -180,14 +180,14 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
|
||||
assertEquals(3, serSchema.types.size)
|
||||
|
||||
val l1 = serSchema.carpenterSchema()
|
||||
val l1 = serSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// since we're using an envelope generated by serialising classes defined locally
|
||||
// it's extremely unlikely we'd need to carpent any classes
|
||||
assertEquals(0, l1.size)
|
||||
|
||||
val mangleSchema = serSchema.mangleNames(listOf(classTestName("A")))
|
||||
val l2 = mangleSchema.carpenterSchema()
|
||||
val l2 = mangleSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
val aName = mangleName(classTestName("A"))
|
||||
|
||||
assertEquals(1, l2.size)
|
||||
@ -235,7 +235,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals(4, serSchema.types.size)
|
||||
|
||||
val mangleSchema = serSchema.mangleNames(listOf(classTestName("A"), classTestName("B")))
|
||||
val cSchema = mangleSchema.carpenterSchema()
|
||||
val cSchema = mangleSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
val aName = mangleName(classTestName("A"))
|
||||
val bName = mangleName(classTestName("B"))
|
||||
|
||||
@ -292,7 +292,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
|
||||
// ignore the return as we expect this to throw
|
||||
serSchema.mangleNames(listOf(
|
||||
classTestName("A"), "${this.javaClass.`package`.name}.I")).carpenterSchema()
|
||||
classTestName("A"), "${this.javaClass.`package`.name}.I")).carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -315,7 +315,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
val amqpSchema = serSchema.mangleNames(listOf(classTestName("A"), "${this.javaClass.`package`.name}.I"))
|
||||
val aName = mangleName(classTestName("A"))
|
||||
val iName = mangleName("${this.javaClass.`package`.name}.I")
|
||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||
val carpenterSchema = amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// whilst there are two unknown classes within the envelope A depends on I so we can't construct a
|
||||
// schema for A until we have for I
|
||||
@ -362,7 +362,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
val aName = mangleName(classTestName("A"))
|
||||
val iName = mangleName("${this.javaClass.`package`.name}.I")
|
||||
val iiName = mangleName("${this.javaClass.`package`.name}.II")
|
||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||
val carpenterSchema = amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// there is nothing preventing us from carpenting up the two interfaces so
|
||||
// our initial list should contain both interface with A being dependent on both
|
||||
@ -414,7 +414,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
val aName = mangleName(classTestName("A"))
|
||||
val iName = mangleName("${this.javaClass.`package`.name}.I")
|
||||
val iiiName = mangleName("${this.javaClass.`package`.name}.III")
|
||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||
val carpenterSchema = amqpSchema.carpenterSchema(ClassLoader.getSystemClassLoader())
|
||||
|
||||
// Since A depends on III and III extends I we will have to construct them
|
||||
// in that reverse order (I -> III -> A)
|
||||
|
@ -36,7 +36,10 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals("int", amqpSchema.fields[1].type)
|
||||
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
assertEquals(1, carpenterSchema.size)
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }
|
||||
@ -77,7 +80,10 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals("string", amqpSchema.fields[1].type)
|
||||
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
assertEquals(1, carpenterSchema.size)
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }
|
||||
|
@ -30,7 +30,10 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals("int", amqpSchema.fields[0].type)
|
||||
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
@ -58,7 +61,10 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
|
||||
val amqpSchema = obj.envelope.schema.types[0] as CompositeType
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
@ -90,7 +96,10 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals("long", amqpSchema.fields[0].type)
|
||||
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
@ -122,7 +131,10 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals("short", amqpSchema.fields[0].type)
|
||||
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
@ -154,7 +166,10 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals("double", amqpSchema.fields[0].type)
|
||||
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
@ -186,7 +201,10 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals("float", amqpSchema.fields[0].type)
|
||||
|
||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||
amqpSchema.carpenterSchema(
|
||||
classloader = ClassLoader.getSystemClassLoader(),
|
||||
carpenterSchemas = carpenterSchema,
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
|
Loading…
Reference in New Issue
Block a user