CORDA-2099 make serializer factory interface (#4137)

* Separate SerializerFactory construction from concrete implementation

* Fewer build methods

* Method naming that doesn't fatally confuse determinisation

* Extract SerializerFactory interface

* Reset to master's version of compiler.xml

* Un-ignore flickering test

* Remove unnecessary build method

* Whitespace

* Unused import

* Change build method

* Formatting fixes

* Fix test
This commit is contained in:
Dominic Fox 2018-11-07 13:48:45 +00:00 committed by GitHub
parent 7f01f9ca61
commit f3b372d31d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 599 additions and 309 deletions

View File

@ -38,10 +38,7 @@ import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.parseAsHex import net.corda.core.utilities.parseAsHex
import net.corda.core.utilities.toHexString import net.corda.core.utilities.toHexString
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.amqp.*
import net.corda.serialization.internal.amqp.constructorForDeserialization
import net.corda.serialization.internal.amqp.hasCordaSerializable
import net.corda.serialization.internal.amqp.propertiesForSerialization
import java.math.BigDecimal import java.math.BigDecimal
import java.security.PublicKey import java.security.PublicKey
import java.security.cert.CertPath import java.security.cert.CertPath
@ -88,7 +85,7 @@ class CordaModule : SimpleModule("corda-core") {
*/ */
private class CordaSerializableBeanSerializerModifier : BeanSerializerModifier() { private class CordaSerializableBeanSerializerModifier : BeanSerializerModifier() {
// We need to pass in a SerializerFactory when scanning for properties, but don't actually do any serialisation so any will do. // We need to pass in a SerializerFactory when scanning for properties, but don't actually do any serialisation so any will do.
private val serializerFactory = SerializerFactory(AllWhitelist, javaClass.classLoader) private val serializerFactory = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader)
override fun changeProperties(config: SerializationConfig, override fun changeProperties(config: SerializationConfig,
beanDesc: BeanDescription, beanDesc: BeanDescription,

View File

@ -8,10 +8,7 @@ import net.corda.core.serialization.SerializationCustomSerializer
import net.corda.core.serialization.internal.SerializationEnvironment import net.corda.core.serialization.internal.SerializationEnvironment
import net.corda.core.serialization.internal.nodeSerializationEnv import net.corda.core.serialization.internal.nodeSerializationEnv
import net.corda.serialization.internal.* import net.corda.serialization.internal.*
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme import net.corda.serialization.internal.amqp.*
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.amqpMagic
import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer
/** /**
@ -52,7 +49,7 @@ class AMQPClientSerializationScheme(
} }
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory { override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply { return SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply {
register(RpcClientObservableDeSerializer) register(RpcClientObservableDeSerializer)
register(RpcClientCordaFutureSerializer(this)) register(RpcClientCordaFutureSerializer(this))
register(RxNotificationSerializer(this)) register(RxNotificationSerializer(this))

View File

@ -1,4 +1,4 @@
gradlePluginsVersion=4.0.33 gradlePluginsVersion=4.0.34
kotlinVersion=1.2.71 kotlinVersion=1.2.71
# ***************************************************************# # ***************************************************************#
# When incrementing platformVersion make sure to update # # When incrementing platformVersion make sure to update #

View File

@ -6,7 +6,7 @@ import net.corda.serialization.internal.AMQP_RPC_CLIENT_CONTEXT
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.DeserializationInput import net.corda.serialization.internal.amqp.DeserializationInput
import net.corda.serialization.internal.amqp.SerializationOutput import net.corda.serialization.internal.amqp.SerializationOutput
import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.serialization.internal.amqp.custom.PublicKeySerializer import net.corda.serialization.internal.amqp.custom.PublicKeySerializer
import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME
@ -15,7 +15,7 @@ import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class TransactionVerificationExceptionSerialisationTests { class TransactionVerificationExceptionSerialisationTests {
private fun defaultFactory() = SerializerFactory( private fun defaultFactory() = SerializerFactoryBuilder.build(
AllWhitelist, AllWhitelist,
ClassLoader.getSystemClassLoader() ClassLoader.getSystemClassLoader()
) )

View File

@ -8,6 +8,7 @@ import net.corda.serialization.internal.CordaSerializationMagic
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer
/** /**
@ -28,7 +29,7 @@ class AMQPServerSerializationScheme(
} }
override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory { override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply { return SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply {
register(RpcServerObservableSerializer()) register(RpcServerObservableSerializer())
register(RpcServerCordaFutureSerializer(this)) register(RpcServerCordaFutureSerializer(this))
register(RxNotificationSerializer(this)) register(RxNotificationSerializer(this))

View File

@ -10,7 +10,7 @@ import net.corda.node.serialization.amqp.RpcServerObservableSerializer
import net.corda.node.services.messaging.ObservableSubscription import net.corda.node.services.messaging.ObservableSubscription
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.SerializationOutput import net.corda.serialization.internal.amqp.SerializationOutput
import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.SimpleString
import org.junit.Test import org.junit.Test
import rx.Observable import rx.Observable
@ -34,7 +34,7 @@ class RpcServerObservableSerializerTests {
@Test @Test
fun canSerializerBeRegistered() { fun canSerializerBeRegistered() {
val sf = SerializerFactory(AllWhitelist, javaClass.classLoader) val sf = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader)
try { try {
sf.register(RpcServerObservableSerializer()) sf.register(RpcServerObservableSerializer())
@ -67,7 +67,7 @@ class RpcServerObservableSerializerTests {
deduplicationIdentity = "thisIsATest", deduplicationIdentity = "thisIsATest",
clientAddress = SimpleString(testClientAddress)) clientAddress = SimpleString(testClientAddress))
val sf = SerializerFactory(AllWhitelist, javaClass.classLoader).apply { val sf = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply {
register(RpcServerObservableSerializer()) register(RpcServerObservableSerializer())
} }

View File

@ -12,6 +12,7 @@ import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.client.rpc.internal.ObservableContext as ClientObservableContext import net.corda.client.rpc.internal.ObservableContext as ClientObservableContext
/** /**
@ -28,13 +29,13 @@ class AMQPRoundTripRPCSerializationScheme(
cordappCustomSerializers, serializerFactoriesForContexts cordappCustomSerializers, serializerFactoriesForContexts
) { ) {
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory { override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(AllWhitelist, javaClass.classLoader).apply { return SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply {
register(RpcClientObservableDeSerializer) register(RpcClientObservableDeSerializer)
} }
} }
override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory { override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(AllWhitelist, javaClass.classLoader).apply { return SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply {
register(RpcServerObservableSerializer()) register(RpcServerObservableSerializer())
} }
} }

View File

@ -50,6 +50,7 @@ task patchSerialization(type: Zip, dependsOn: serializationJarTask) {
exclude 'net/corda/serialization/internal/amqp/AMQPSerializerFactories*' exclude 'net/corda/serialization/internal/amqp/AMQPSerializerFactories*'
exclude 'net/corda/serialization/internal/amqp/AMQPStreams*' exclude 'net/corda/serialization/internal/amqp/AMQPStreams*'
exclude 'net/corda/serialization/internal/amqp/AMQPSerializationThreadContext*' exclude 'net/corda/serialization/internal/amqp/AMQPSerializationThreadContext*'
exclude 'net/corda/serialization/internal/model/DefaultCacheProvider*'
} }
reproducibleFileOrder = true reproducibleFileOrder = true

View File

@ -15,15 +15,9 @@ fun createSerializerFactoryFactory(): SerializerFactoryFactory = DeterministicSe
private class DeterministicSerializerFactoryFactory : SerializerFactoryFactory { private class DeterministicSerializerFactoryFactory : SerializerFactoryFactory {
override fun make(context: SerializationContext) = override fun make(context: SerializationContext) =
SerializerFactory( SerializerFactoryBuilder.build(
whitelist = context.whitelist, whitelist = context.whitelist,
classCarpenter = DummyClassCarpenter(context.whitelist, context.deserializationClassLoader), classCarpenter = DummyClassCarpenter(context.whitelist, context.deserializationClassLoader))
serializersByType = mutableMapOf(),
serializersByDescriptor = mutableMapOf(),
customSerializers = ArrayList(),
customSerializersCache = mutableMapOf(),
transformsCache = mutableMapOf()
)
} }
private class DummyClassCarpenter( private class DummyClassCarpenter(

View File

@ -0,0 +1,9 @@
package net.corda.serialization.internal.model
/**
* We can't have [ConcurrentHashMap]s in the DJVM, so it must supply its own version of this object which returns
* plain old [MutableMap]s instead.
*/
object DefaultCacheProvider {
fun <K, V> createCache(): MutableMap<K, V> = mutableMapOf()
}

View File

@ -3,11 +3,14 @@
package net.corda.serialization.internal.amqp package net.corda.serialization.internal.amqp
import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.SerializationContext
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
fun createSerializerFactoryFactory(): SerializerFactoryFactory = SerializerFactoryFactoryImpl() fun createSerializerFactoryFactory(): SerializerFactoryFactory = SerializerFactoryFactoryImpl()
open class SerializerFactoryFactoryImpl : SerializerFactoryFactory { open class SerializerFactoryFactoryImpl : SerializerFactoryFactory {
override fun make(context: SerializationContext): SerializerFactory { override fun make(context: SerializationContext): SerializerFactory {
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled) return SerializerFactoryBuilder.build(context.whitelist,
ClassCarpenterImpl(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled)
)
} }
} }

View File

@ -1,7 +1,6 @@
package net.corda.serialization.internal.amqp package net.corda.serialization.internal.amqp
import com.google.common.primitives.Primitives import com.google.common.primitives.Primitives
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM import net.corda.core.KeepForDJVM
import net.corda.core.StubOutForDJVM import net.corda.core.StubOutForDJVM
import net.corda.core.internal.kotlinObjectInstance import net.corda.core.internal.kotlinObjectInstance
@ -12,12 +11,11 @@ import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.trace import net.corda.core.utilities.trace
import net.corda.serialization.internal.carpenter.* import net.corda.serialization.internal.carpenter.*
import net.corda.serialization.internal.model.DefaultCacheProvider
import org.apache.qpid.proton.amqp.* import org.apache.qpid.proton.amqp.*
import java.io.NotSerializableException import java.io.NotSerializableException
import java.lang.reflect.* import java.lang.reflect.*
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList
import javax.annotation.concurrent.ThreadSafe import javax.annotation.concurrent.ThreadSafe
@KeepForDJVM @KeepForDJVM
@ -49,54 +47,122 @@ data class CustomSerializersCacheKey(val clazz: Class<*>, val declaredType: Type
// 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? // 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?
@KeepForDJVM @KeepForDJVM
@ThreadSafe @ThreadSafe
open class SerializerFactory( interface SerializerFactory {
val whitelist: ClassWhitelist, val whitelist: ClassWhitelist
val classCarpenter: ClassCarpenter, val classCarpenter: ClassCarpenter
private val evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider, val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter
val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter, // Caches
private val serializersByType: MutableMap<Type, AMQPSerializer<Any>>, val serializersByType: MutableMap<Type, AMQPSerializer<Any>>
val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>>, val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>>
private val customSerializers: MutableList<SerializerFor>, val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>>
private val customSerializersCache: MutableMap<CustomSerializersCacheKey, AMQPSerializer<Any>?>, val fingerPrinter: FingerPrinter
val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>>, val classloader: ClassLoader
/**
* Look up, and manufacture if necessary, a serializer for the given type.
*
* @param actualClass Will be null if there isn't an actual object instance available (e.g. for
* restricted type processing).
*/
@Throws(NotSerializableException::class)
fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer<Any>
/**
* Lookup and manufacture a serializer for the given AMQP type descriptor, assuming we also have the necessary types
* contained in the [Schema].
*/
@Throws(NotSerializableException::class)
fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer<Any>
/**
* Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer
* that expects to find getters and a constructor with a parameter for each property.
*/
fun register(customSerializer: CustomSerializer<out Any>)
fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer<Any>?
fun registerExternal(customSerializer: CorDappCustomSerializer)
fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer<Any>): AMQPSerializer<Any>
object AnyType : WildcardType {
override fun getUpperBounds(): Array<Type> = arrayOf(Object::class.java)
override fun getLowerBounds(): Array<Type> = emptyArray()
override fun toString(): String = "?"
}
companion object {
fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null
fun primitiveTypeName(type: Type): String? {
val clazz = type as? Class<*> ?: return null
return primitiveTypeNames[Primitives.unwrap(clazz)]
}
fun primitiveType(type: String): Class<*>? {
return namesOfPrimitiveTypes[type]
}
private val primitiveTypeNames: Map<Class<*>, String> = mapOf(
Character::class.java to "char",
Char::class.java to "char",
Boolean::class.java to "boolean",
Byte::class.java to "byte",
UnsignedByte::class.java to "ubyte",
Short::class.java to "short",
UnsignedShort::class.java to "ushort",
Int::class.java to "int",
UnsignedInteger::class.java to "uint",
Long::class.java to "long",
UnsignedLong::class.java to "ulong",
Float::class.java to "float",
Double::class.java to "double",
Decimal32::class.java to "decimal32",
Decimal64::class.java to "decimal62",
Decimal128::class.java to "decimal128",
Date::class.java to "timestamp",
UUID::class.java to "uuid",
ByteArray::class.java to "binary",
String::class.java to "string",
Symbol::class.java to "symbol")
private val namesOfPrimitiveTypes: Map<String, Class<*>> = primitiveTypeNames.map { it.value to it.key }.toMap()
fun nameForType(type: Type): String = when (type) {
is Class<*> -> {
primitiveTypeName(type) ?: if (type.isArray) {
"${nameForType(type.componentType)}${if (type.componentType.isPrimitive) "[p]" else "[]"}"
} else type.name
}
is ParameterizedType -> {
"${nameForType(type.rawType)}<${type.actualTypeArguments.joinToString { nameForType(it) }}>"
}
is GenericArrayType -> "${nameForType(type.genericComponentType)}[]"
is WildcardType -> "?"
is TypeVariable<*> -> "?"
else -> throw AMQPNotSerializableException(type, "Unable to render type $type to a string.")
}
}
}
open class DefaultSerializerFactory(
override val whitelist: ClassWhitelist,
override val classCarpenter: ClassCarpenter,
private val evolutionSerializerProvider: EvolutionSerializerProvider,
override val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter,
private val onlyCustomSerializers: Boolean = false private val onlyCustomSerializers: Boolean = false
) { ) : SerializerFactory {
@DeleteForDJVM
constructor(whitelist: ClassWhitelist,
classCarpenter: ClassCarpenter,
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
onlyCustomSerializers: Boolean = false
) : this(
whitelist,
classCarpenter,
evolutionSerializerProvider,
fingerPrinterConstructor,
ConcurrentHashMap(),
ConcurrentHashMap(),
CopyOnWriteArrayList(),
ConcurrentHashMap(),
ConcurrentHashMap(),
onlyCustomSerializers
)
@DeleteForDJVM // Caches
constructor(whitelist: ClassWhitelist, override val serializersByType: MutableMap<Type, AMQPSerializer<Any>> = DefaultCacheProvider.createCache()
carpenterClassLoader: ClassLoader, override val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>> = DefaultCacheProvider.createCache()
lenientCarpenter: Boolean = false, private var customSerializers: List<SerializerFor> = emptyList()
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider, private val customSerializersCache: MutableMap<CustomSerializersCacheKey, AMQPSerializer<Any>?> = DefaultCacheProvider.createCache()
fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter, override val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>> = DefaultCacheProvider.createCache()
onlyCustomSerializers: Boolean = false
) : this(
whitelist,
ClassCarpenterImpl(whitelist, carpenterClassLoader, lenientCarpenter),
evolutionSerializerProvider,
fingerPrinterConstructor,
onlyCustomSerializers)
val fingerPrinter by lazy { fingerPrinterConstructor(this) } override val fingerPrinter by lazy { fingerPrinterConstructor(this) }
val classloader: ClassLoader get() = classCarpenter.classloader override val classloader: ClassLoader get() = classCarpenter.classloader
// Used to short circuit any computation for a given input, for performance. // Used to short circuit any computation for a given input, for performance.
private data class MemoType(val actualClass: Class<*>?, val declaredType: Type) : Type private data class MemoType(val actualClass: Class<*>?, val declaredType: Type) : Type
@ -108,7 +174,7 @@ open class SerializerFactory(
* restricted type processing). * restricted type processing).
*/ */
@Throws(NotSerializableException::class) @Throws(NotSerializableException::class)
fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer<Any> { override fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer<Any> {
// can be useful to enable but will be *extremely* chatty if you do // can be useful to enable but will be *extremely* chatty if you do
logger.trace { "Get Serializer for $actualClass ${declaredType.typeName}" } logger.trace { "Get Serializer for $actualClass ${declaredType.typeName}" }
@ -169,7 +235,7 @@ open class SerializerFactory(
* contained in the [Schema]. * contained in the [Schema].
*/ */
@Throws(NotSerializableException::class) @Throws(NotSerializableException::class)
fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer<Any> { override fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer<Any> {
return serializersByDescriptor[typeDescriptor] ?: { return serializersByDescriptor[typeDescriptor] ?: {
logger.trace("get Serializer descriptor=${typeDescriptor}") logger.trace("get Serializer descriptor=${typeDescriptor}")
processSchema(FactorySchemaAndDescriptor(schema, typeDescriptor)) processSchema(FactorySchemaAndDescriptor(schema, typeDescriptor))
@ -182,7 +248,7 @@ open class SerializerFactory(
* Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer * Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer
* that expects to find getters and a constructor with a parameter for each property. * that expects to find getters and a constructor with a parameter for each property.
*/ */
open fun register(customSerializer: CustomSerializer<out Any>) { override fun register(customSerializer: CustomSerializer<out Any>) {
logger.trace("action=\"Registering custom serializer\", class=\"${customSerializer.type}\"") logger.trace("action=\"Registering custom serializer\", class=\"${customSerializer.type}\"")
if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) { if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) {
customSerializers += customSerializer customSerializers += customSerializer
@ -193,7 +259,7 @@ open class SerializerFactory(
} }
} }
fun registerExternal(customSerializer: CorDappCustomSerializer) { override fun registerExternal(customSerializer: CorDappCustomSerializer) {
logger.trace("action=\"Registering external serializer\", class=\"${customSerializer.type}\"") logger.trace("action=\"Registering external serializer\", class=\"${customSerializer.type}\"")
if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) { if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) {
customSerializers += customSerializer customSerializers += customSerializer
@ -319,7 +385,7 @@ open class SerializerFactory(
throw AMQPNotSerializableException( throw AMQPNotSerializableException(
type, type,
"Serializer does not support synthetic classes") "Serializer does not support synthetic classes")
} else if (isPrimitive(clazz)) { } else if (SerializerFactory.isPrimitive(clazz)) {
AMQPPrimitiveSerializer(clazz) AMQPPrimitiveSerializer(clazz)
} else { } else {
findCustomSerializer(clazz, declaredType) ?: run { findCustomSerializer(clazz, declaredType) ?: run {
@ -344,7 +410,7 @@ open class SerializerFactory(
} }
} }
internal fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer<Any>? { override fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer<Any>? {
return customSerializersCache.computeIfAbsent(CustomSerializersCacheKey(clazz, declaredType), ::doFindCustomSerializer) return customSerializersCache.computeIfAbsent(CustomSerializersCacheKey(clazz, declaredType), ::doFindCustomSerializer)
} }
@ -383,69 +449,11 @@ open class SerializerFactory(
return MapSerializer(declaredType, this) return MapSerializer(declaredType, this)
} }
fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer<Any>): AMQPSerializer<Any> = override fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer<Any>): AMQPSerializer<Any> =
serializersByDescriptor.computeIfAbsent(name) { _ -> serializerCreator() } serializersByDescriptor.computeIfAbsent(name) { _ -> serializerCreator() }
companion object { companion object {
private val logger = contextLogger() private val logger = contextLogger()
fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null
fun primitiveTypeName(type: Type): String? {
val clazz = type as? Class<*> ?: return null
return primitiveTypeNames[Primitives.unwrap(clazz)]
}
fun primitiveType(type: String): Class<*>? {
return namesOfPrimitiveTypes[type]
}
private val primitiveTypeNames: Map<Class<*>, String> = mapOf(
Character::class.java to "char",
Char::class.java to "char",
Boolean::class.java to "boolean",
Byte::class.java to "byte",
UnsignedByte::class.java to "ubyte",
Short::class.java to "short",
UnsignedShort::class.java to "ushort",
Int::class.java to "int",
UnsignedInteger::class.java to "uint",
Long::class.java to "long",
UnsignedLong::class.java to "ulong",
Float::class.java to "float",
Double::class.java to "double",
Decimal32::class.java to "decimal32",
Decimal64::class.java to "decimal62",
Decimal128::class.java to "decimal128",
Date::class.java to "timestamp",
UUID::class.java to "uuid",
ByteArray::class.java to "binary",
String::class.java to "string",
Symbol::class.java to "symbol")
private val namesOfPrimitiveTypes: Map<String, Class<*>> = primitiveTypeNames.map { it.value to it.key }.toMap()
fun nameForType(type: Type): String = when (type) {
is Class<*> -> {
primitiveTypeName(type) ?: if (type.isArray) {
"${nameForType(type.componentType)}${if (type.componentType.isPrimitive) "[p]" else "[]"}"
} else type.name
}
is ParameterizedType -> {
"${nameForType(type.rawType)}<${type.actualTypeArguments.joinToString { nameForType(it) }}>"
}
is GenericArrayType -> "${nameForType(type.genericComponentType)}[]"
is WildcardType -> "?"
is TypeVariable<*> -> "?"
else -> throw AMQPNotSerializableException(type, "Unable to render type $type to a string.")
}
} }
object AnyType : WildcardType {
override fun getUpperBounds(): Array<Type> = arrayOf(Object::class.java)
override fun getLowerBounds(): Array<Type> = emptyArray()
override fun toString(): String = "?"
}
} }

View File

@ -0,0 +1,53 @@
package net.corda.serialization.internal.amqp
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.ClassWhitelist
import net.corda.serialization.internal.carpenter.ClassCarpenter
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
@KeepForDJVM
object SerializerFactoryBuilder {
@JvmStatic
@JvmOverloads
fun build(
whitelist: ClassWhitelist,
classCarpenter: ClassCarpenter,
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
fingerPrinterProvider: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
onlyCustomSerializers: Boolean = false): SerializerFactory {
return makeFactory(
whitelist,
classCarpenter,
evolutionSerializerProvider,
fingerPrinterProvider,
onlyCustomSerializers)
}
@JvmStatic
@JvmOverloads
@DeleteForDJVM
fun build(
whitelist: ClassWhitelist,
carpenterClassLoader: ClassLoader,
lenientCarpenterEnabled: Boolean = false,
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
fingerPrinterProvider: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
onlyCustomSerializers: Boolean = false): SerializerFactory {
return makeFactory(
whitelist,
ClassCarpenterImpl(whitelist, carpenterClassLoader, lenientCarpenterEnabled),
evolutionSerializerProvider,
fingerPrinterProvider,
onlyCustomSerializers)
}
private fun makeFactory(whitelist: ClassWhitelist,
classCarpenter: ClassCarpenter,
evolutionSerializerProvider: EvolutionSerializerProvider,
fingerPrinterProvider: (SerializerFactory) -> FingerPrinter,
onlyCustomSerializers: Boolean) =
DefaultSerializerFactory(whitelist, classCarpenter, evolutionSerializerProvider, fingerPrinterProvider,
onlyCustomSerializers)
}

View File

@ -0,0 +1,11 @@
package net.corda.serialization.internal.model
import java.util.concurrent.ConcurrentHashMap
/**
* We can't have [ConcurrentHashMap]s in the DJVM, so it must supply its own version of this object which returns
* plain old [MutableMap]s instead.
*/
object DefaultCacheProvider {
fun <K, V> createCache(): MutableMap<K, V> = ConcurrentHashMap()
}

View File

@ -147,10 +147,7 @@ public class JavaPrivatePropertyTests {
// //
// Now ensure we actually got a private property serializer // Now ensure we actually got a private property serializer
// //
Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor"); Map<Object, AMQPSerializer<Object>> serializersByDescriptor = factory.getSerializersByDescriptor();
f.setAccessible(true);
Map<?, AMQPSerializer<?>> serializersByDescriptor = uncheckedCast(f.get(factory));
assertEquals(1, serializersByDescriptor.size()); assertEquals(1, serializersByDescriptor.size());
ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]); ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]);
@ -175,9 +172,7 @@ public class JavaPrivatePropertyTests {
// //
// Now ensure we actually got a private property serializer // Now ensure we actually got a private property serializer
// //
Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor"); Map<Object, AMQPSerializer<Object>> serializersByDescriptor = factory.getSerializersByDescriptor();
f.setAccessible(true);
Map<?, AMQPSerializer<?>> serializersByDescriptor = uncheckedCast(f.get(factory));
assertEquals(1, serializersByDescriptor.size()); assertEquals(1, serializersByDescriptor.size());
ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]); ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]);

View File

@ -7,7 +7,7 @@ import net.corda.node.serialization.kryo.kryoMagic
import net.corda.node.services.statemachine.DataSessionMessage import net.corda.node.services.statemachine.DataSessionMessage
import net.corda.serialization.internal.amqp.DeserializationInput import net.corda.serialization.internal.amqp.DeserializationInput
import net.corda.serialization.internal.amqp.Envelope import net.corda.serialization.internal.amqp.Envelope
import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.internal.amqpSpecific import net.corda.testing.internal.amqpSpecific
import net.corda.testing.internal.kryoSpecific import net.corda.testing.internal.kryoSpecific
@ -28,7 +28,7 @@ class ListsSerializationTest {
fun <T : Any> verifyEnvelope(serBytes: SerializedBytes<T>, envVerBody: (Envelope) -> Unit) = fun <T : Any> verifyEnvelope(serBytes: SerializedBytes<T>, envVerBody: (Envelope) -> Unit) =
amqpSpecific("AMQP specific envelope verification") { amqpSpecific("AMQP specific envelope verification") {
val context = SerializationFactory.defaultFactory.defaultContext val context = SerializationFactory.defaultFactory.defaultContext
val envelope = DeserializationInput(SerializerFactory(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes, context) val envelope = DeserializationInput(SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes, context)
envVerBody(envelope) envVerBody(envelope)
} }
} }

View File

@ -4,6 +4,7 @@ import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.testutils.* import net.corda.serialization.internal.amqp.testutils.*
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.junit.Test import org.junit.Test
import java.io.NotSerializableException import java.io.NotSerializableException
@ -12,16 +13,16 @@ import kotlin.test.assertEquals
class CorDappSerializerTests { class CorDappSerializerTests {
data class NeedsProxy(val a: String) data class NeedsProxy(val a: String)
private fun proxyFactory( private fun proxyFactory(serializers: List<SerializationCustomSerializer<*, *>>): SerializerFactory {
serializers: List<SerializationCustomSerializer<*, *>> val factory = SerializerFactoryBuilder.build(AllWhitelist,
) = SerializerFactory( ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
AllWhitelist, DefaultEvolutionSerializerProvider)
ClassLoader.getSystemClassLoader(),
onlyCustomSerializers = true
).apply {
serializers.forEach { serializers.forEach {
registerExternal(CorDappCustomSerializer(it, this)) factory.registerExternal(CorDappCustomSerializer(it, factory))
} }
return factory
} }
class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> { class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> {
@ -101,7 +102,10 @@ class CorDappSerializerTests {
override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses
} }
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory)) factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory))
val tv1 = 100 val tv1 = 100
@ -123,7 +127,10 @@ class CorDappSerializerTests {
override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses
} }
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory)) factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory))
val tv1 = 100 val tv1 = 100
@ -148,7 +155,10 @@ class CorDappSerializerTests {
override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses
} }
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory)) factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory))
val tv1 = 100 val tv1 = 100

View File

@ -94,7 +94,9 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase(AllWhitelist) {
// won't already exist and it will be carpented a second time showing that when A and B are the // 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 // same underlying class that we didn't create a second instance of the class with the
// second deserialisation // second deserialisation
val lfactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val lfactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val deserialisedC = DeserializationInput(lfactory).deserialize( val deserialisedC = DeserializationInput(lfactory).deserialize(
TestSerializationOutput(VERBOSE, lfactory).serialize(concreteC)) TestSerializationOutput(VERBOSE, lfactory).serialize(concreteC))

View File

@ -9,6 +9,7 @@ import net.corda.serialization.internal.amqp.testutils.deserializeAndReturnEnvel
import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema
import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution
import net.corda.serialization.internal.amqp.testutils.testName import net.corda.serialization.internal.amqp.testutils.testName
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.junit.Test import org.junit.Test
import java.io.NotSerializableException import java.io.NotSerializableException
@ -205,7 +206,10 @@ class EnumTests {
} }
} }
val factory = SerializerFactory(WL(classTestName("C")), ClassLoader.getSystemClassLoader()) val whitelist = WL(classTestName("C"))
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
Assertions.assertThatThrownBy { Assertions.assertThatThrownBy {
TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE)) TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE))
@ -223,7 +227,10 @@ class EnumTests {
} }
} }
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
// if it all works, this won't explode // if it all works, this won't explode
TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE)) TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE))
@ -237,7 +244,10 @@ class EnumTests {
override fun hasListed(type: Class<*>) = false override fun hasListed(type: Class<*>) = false
} }
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
// if it all works, this won't explode // if it all works, this won't explode
TestSerializationOutput(VERBOSE, factory).serialize(C(AnnotatedBras.UNDERWIRE)) TestSerializationOutput(VERBOSE, factory).serialize(C(AnnotatedBras.UNDERWIRE))
@ -252,14 +262,19 @@ class EnumTests {
} }
// first serialise the class using a context in which Bras are whitelisted // first serialise the class using a context in which Bras are whitelisted
val factory = SerializerFactory(WL(listOf(classTestName("C"), val whitelist = WL(listOf(classTestName("C"),
"net.corda.serialization.internal.amqp.EnumTests\$Bras")), "net.corda.serialization.internal.amqp.EnumTests\$Bras"))
ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
val bytes = TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE)) val bytes = TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE))
// then take that serialised object and attempt to deserialize it in a context that // then take that serialised object and attempt to deserialize it in a context that
// disallows the Bras enum // disallows the Bras enum
val factory2 = SerializerFactory(WL(listOf(classTestName("C"))), ClassLoader.getSystemClassLoader()) val whitelist1 = WL(listOf(classTestName("C")))
val factory2 = SerializerFactoryBuilder.build(whitelist1,
ClassCarpenterImpl(whitelist1, ClassLoader.getSystemClassLoader())
)
Assertions.assertThatThrownBy { Assertions.assertThatThrownBy {
DeserializationInput(factory2).deserialize(bytes) DeserializationInput(factory2).deserialize(bytes)
}.isInstanceOf(NotSerializableException::class.java) }.isInstanceOf(NotSerializableException::class.java)

View File

@ -6,6 +6,7 @@ import kotlin.test.assertEquals
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
class FingerPrinterTesting : FingerPrinter { class FingerPrinterTesting : FingerPrinter {
private var index = 0 private var index = 0
@ -39,11 +40,9 @@ class FingerPrinterTestingTests {
fun worksAsReplacement() { fun worksAsReplacement() {
data class C(val a: Int, val b: Long) data class C(val a: Int, val b: Long)
val factory = SerializerFactory( val factory = SerializerFactoryBuilder.build(AllWhitelist,
AllWhitelist, ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
ClassLoader.getSystemClassLoader(), fingerPrinterProvider = { _ -> FingerPrinterTesting() })
evolutionSerializerProvider = FailIfEvolutionAttempted,
fingerPrinterConstructor = { _ -> FingerPrinterTesting() })
val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L)) val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L))

View File

@ -9,6 +9,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.serialization.internal.amqp.testutils.* import net.corda.serialization.internal.amqp.testutils.*
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import net.corda.testing.common.internal.ProjectStructure.projectRootDir import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import org.junit.Test import org.junit.Test
@ -120,8 +121,12 @@ class GenericsTests {
data class G(val a: Int) data class G(val a: Int)
data class Wrapper<T : Any>(val a: Int, val b: SerializedBytes<T>) data class Wrapper<T : Any>(val a: Int, val b: SerializedBytes<T>)
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val ser = SerializationOutput(factory) val ser = SerializationOutput(factory)
val gBytes = ser.serialize(G(1)) val gBytes = ser.serialize(G(1))
@ -145,8 +150,12 @@ class GenericsTests {
data class Container<T>(val b: T) data class Container<T>(val b: T)
data class Wrapper<T : Any>(val c: Container<T>) data class Wrapper<T : Any>(val c: Container<T>)
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
val factories = listOf(factory, SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factories = listOf(factory, SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val ser = SerializationOutput(factory) val ser = SerializationOutput(factory)
ser.serialize(Wrapper(Container(InnerA(1)))).apply { ser.serialize(Wrapper(Container(InnerA(1)))).apply {
@ -178,8 +187,12 @@ class GenericsTests {
data class Wrapper<T : Any>(val c: Container<T>) data class Wrapper<T : Any>(val c: Container<T>)
val factorys = listOf( val factorys = listOf(
SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()), SerializerFactoryBuilder.build(AllWhitelist,
SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
),
SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val ser = SerializationOutput(factorys[0]) val ser = SerializationOutput(factorys[0])
@ -200,7 +213,9 @@ class GenericsTests {
private fun forceWildcardSerialize( private fun forceWildcardSerialize(
a: ForceWildcard<*>, a: ForceWildcard<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())): SerializedBytes<*> { factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)): SerializedBytes<*> {
val bytes = SerializationOutput(factory).serializeAndReturnSchema(a) val bytes = SerializationOutput(factory).serializeAndReturnSchema(a)
factory.serializersByDescriptor.printKeyToType() factory.serializersByDescriptor.printKeyToType()
bytes.printSchema() bytes.printSchema()
@ -210,21 +225,27 @@ class GenericsTests {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private fun forceWildcardDeserializeString( private fun forceWildcardDeserializeString(
bytes: SerializedBytes<*>, bytes: SerializedBytes<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) { factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)) {
DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<String>>) DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<String>>)
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private fun forceWildcardDeserializeDouble( private fun forceWildcardDeserializeDouble(
bytes: SerializedBytes<*>, bytes: SerializedBytes<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) { factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)) {
DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<Double>>) DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<Double>>)
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private fun forceWildcardDeserialize( private fun forceWildcardDeserialize(
bytes: SerializedBytes<*>, bytes: SerializedBytes<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) { factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)) {
DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<*>>) DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<*>>)
} }
@ -236,7 +257,9 @@ class GenericsTests {
@Test @Test
fun forceWildcardSharedFactory() { fun forceWildcardSharedFactory() {
val f = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val f = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
forceWildcardDeserializeString(forceWildcardSerialize(ForceWildcard("hello"), f), f) forceWildcardDeserializeString(forceWildcardSerialize(ForceWildcard("hello"), f), f)
forceWildcardDeserializeDouble(forceWildcardSerialize(ForceWildcard(3.0), f), f) forceWildcardDeserializeDouble(forceWildcardSerialize(ForceWildcard(3.0), f), f)
} }
@ -250,7 +273,9 @@ class GenericsTests {
@Test @Test
fun forceWildcardDeserializeSharedFactory() { fun forceWildcardDeserializeSharedFactory() {
val f = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val f = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard("hello"), f), f) forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard("hello"), f), f)
forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(10), f), f) forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(10), f), f)
forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(20.0), f), f) forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(20.0), f), f)
@ -288,7 +313,9 @@ class GenericsTests {
// possibly altering how we serialise things // possibly altering how we serialise things
val altClassLoader = cl() val altClassLoader = cl()
val factory2 = SerializerFactory(AllWhitelist, altClassLoader) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, altClassLoader)
)
factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val ser2 = TestSerializationOutput(VERBOSE, factory2).serializeAndReturnSchema(state) val ser2 = TestSerializationOutput(VERBOSE, factory2).serializeAndReturnSchema(state)
@ -297,7 +324,9 @@ class GenericsTests {
factory3.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) factory3.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
DeserializationInput(factory3).deserializeAndReturnEnvelope(ser1.obj) DeserializationInput(factory3).deserializeAndReturnEnvelope(ser1.obj)
val factory4 = SerializerFactory(AllWhitelist, cl()) val factory4 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, cl())
)
factory4.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) factory4.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
DeserializationInput(factory4).deserializeAndReturnEnvelope(ser2.obj) DeserializationInput(factory4).deserializeAndReturnEnvelope(ser2.obj)
} }

View File

@ -5,6 +5,7 @@ import net.corda.serialization.internal.amqp.custom.OptionalSerializer
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.hamcrest.Matchers.`is` import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.equalTo import org.hamcrest.Matchers.equalTo
import org.junit.Assert import org.junit.Assert
@ -17,7 +18,9 @@ class OptionalSerializationTests {
fun setupEnclosedSerializationTest() { fun setupEnclosedSerializationTest() {
@Test @Test
fun `java optionals should serialize`() { fun `java optionals should serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(OptionalSerializer(factory)) factory.register(OptionalSerializer(factory))
val obj = Optional.ofNullable("YES") val obj = Optional.ofNullable("YES")
val bytes = TestSerializationOutput(true, factory).serialize(obj) val bytes = TestSerializationOutput(true, factory).serialize(obj)

View File

@ -17,15 +17,6 @@ import java.util.*
class PrivatePropertyTests { class PrivatePropertyTests {
private val factory = testDefaultFactoryNoEvolution() private val factory = testDefaultFactoryNoEvolution()
companion object {
val fields : Map<String, java.lang.reflect.Field> = mapOf (
"serializersByDesc" to SerializerFactory::class.java.getDeclaredField("serializersByDescriptor")).apply {
this.values.forEach {
it.isAccessible = true
}
}
}
@Test @Test
fun testWithOnePrivateProperty() { fun testWithOnePrivateProperty() {
data class C(private val b: String) data class C(private val b: String)
@ -134,8 +125,7 @@ class PrivatePropertyTests {
val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1) val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1)
assertEquals(1, schemaAndBlob.schema.types.size) assertEquals(1, schemaAndBlob.schema.types.size)
@Suppress("UNCHECKED_CAST") val serializersByDescriptor = factory.serializersByDescriptor
val serializersByDescriptor = fields["serializersByDesc"]?.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>>
val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name
serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply { serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply {
@ -163,8 +153,7 @@ class PrivatePropertyTests {
val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1) val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1)
assertEquals(1, schemaAndBlob.schema.types.size) assertEquals(1, schemaAndBlob.schema.types.size)
@Suppress("UNCHECKED_CAST") val serializersByDescriptor = factory.serializersByDescriptor
val serializersByDescriptor = fields["serializersByDesc"]?.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>>
val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name
serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply { serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply {
@ -192,7 +181,7 @@ class PrivatePropertyTests {
val output = SerializationOutput(factory).serializeAndReturnSchema(c1) val output = SerializationOutput(factory).serializeAndReturnSchema(c1)
println (output.schema) println (output.schema)
val serializersByDescriptor = fields["serializersByDesc"]!!.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>> val serializersByDescriptor = factory.serializersByDescriptor
// Inner and Outer // Inner and Outer
assertEquals(2, serializersByDescriptor.size) assertEquals(2, serializersByDescriptor.size)
@ -212,7 +201,7 @@ class PrivatePropertyTests {
val output = SerializationOutput(factory).serializeAndReturnSchema(C("this is nice")) val output = SerializationOutput(factory).serializeAndReturnSchema(C("this is nice"))
val serializersByDescriptor = fields["serializersByDesc"]!!.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>> val serializersByDescriptor = factory.serializersByDescriptor
val schemaDescriptor = output.schema.types.first().descriptor.name val schemaDescriptor = output.schema.types.first().descriptor.name
serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply { serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply {

View File

@ -23,6 +23,7 @@ import net.corda.nodeapi.internal.crypto.ContentSignerBuilder
import net.corda.serialization.internal.* import net.corda.serialization.internal.*
import net.corda.serialization.internal.amqp.SerializerFactory.Companion.isPrimitive import net.corda.serialization.internal.amqp.SerializerFactory.Companion.isPrimitive
import net.corda.serialization.internal.amqp.testutils.* import net.corda.serialization.internal.amqp.testutils.*
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.BOB_NAME import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
@ -207,9 +208,8 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
} }
private fun defaultFactory(): SerializerFactory { private fun defaultFactory(): SerializerFactory {
return SerializerFactory( return SerializerFactoryBuilder.build(AllWhitelist,
AllWhitelist, ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
ClassLoader.getSystemClassLoader(),
evolutionSerializerProvider = FailIfEvolutionAttempted evolutionSerializerProvider = FailIfEvolutionAttempted
) )
} }
@ -368,13 +368,17 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test(expected = NotSerializableException::class) @Test(expected = NotSerializableException::class)
fun `test whitelist`() { fun `test whitelist`() {
val obj = Woo2(4) val obj = Woo2(4)
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
} }
@Test @Test
fun `test annotation whitelisting`() { fun `test annotation whitelisting`() {
val obj = AnnotatedWoo(5) val obj = AnnotatedWoo(5)
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
} }
@Test(expected = NotSerializableException::class) @Test(expected = NotSerializableException::class)
@ -471,7 +475,9 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `class constructor is invoked on deserialisation`() { fun `class constructor is invoked on deserialisation`() {
compression == null || return // Manipulation of serialized bytes is invalid if they're compressed. compression == null || return // Manipulation of serialized bytes is invalid if they're compressed.
val ser = SerializationOutput(SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) val ser = SerializationOutput(SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val des = DeserializationInput(ser.serializerFactory) val des = DeserializationInput(ser.serializerFactory)
val serialisedOne = ser.serialize(NonZeroByte(1), compression).bytes val serialisedOne = ser.serialize(NonZeroByte(1), compression).bytes
val serialisedTwo = ser.serialize(NonZeroByte(2), compression).bytes val serialisedTwo = ser.serialize(NonZeroByte(2), compression).bytes
@ -496,9 +502,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test custom serializers on public key`() { fun `test custom serializers on public key`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) factory.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val obj = MEGA_CORP_PUBKEY val obj = MEGA_CORP_PUBKEY
serdes(obj, factory, factory2) serdes(obj, factory, factory2)
@ -507,21 +517,29 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test annotation is inherited`() { fun `test annotation is inherited`() {
val obj = InheritAnnotation("blah") val obj = InheritAnnotation("blah")
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
} }
@Test @Test
fun `generics from java are supported`() { fun `generics from java are supported`() {
val obj = DummyOptional<String>("YES") val obj = DummyOptional<String>("YES")
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
} }
@Test @Test
fun `test throwables serialize`() { fun `test throwables serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
val t = IllegalAccessException("message").fillInStackTrace() val t = IllegalAccessException("message").fillInStackTrace()
@ -537,10 +555,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test complex throwables serialize`() { fun `test complex throwables serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
try { try {
@ -567,10 +589,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test suppressed throwables serialize`() { fun `test suppressed throwables serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
try { try {
@ -589,10 +615,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test flow corda exception subclasses serialize`() { fun `test flow corda exception subclasses serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
val obj = FlowException("message").fillInStackTrace() val obj = FlowException("message").fillInStackTrace()
@ -601,10 +631,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test RPC corda exception subclasses serialize`() { fun `test RPC corda exception subclasses serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
val obj = RPCException("message").fillInStackTrace() val obj = RPCException("message").fillInStackTrace()
@ -666,10 +700,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
SerializerFactory::class.java) SerializerFactory::class.java)
func.isAccessible = true func.isAccessible = true
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
func.invoke(scheme, testSerializationContext, factory) func.invoke(scheme, testSerializationContext, factory)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
func.invoke(scheme, testSerializationContext, factory2) func.invoke(scheme, testSerializationContext, factory2)
val desState = serdes(state, factory, factory2, expectedEqual = false, expectDeserializedEqual = false) val desState = serdes(state, factory, factory2, expectedEqual = false, expectDeserializedEqual = false)
@ -680,10 +718,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test currencies serialize`() { fun `test currencies serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer) factory.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer) factory2.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer)
val obj = Currency.getInstance("USD") val obj = Currency.getInstance("USD")
@ -692,10 +734,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test big decimals serialize`() { fun `test big decimals serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val obj = BigDecimal("100000000000000000000000000000.00") val obj = BigDecimal("100000000000000000000000000000.00")
@ -704,10 +750,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test instants serialize`() { fun `test instants serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory2))
val obj = Instant.now() val obj = Instant.now()
@ -716,10 +766,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test durations serialize`() { fun `test durations serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory2))
val obj = Duration.of(1000000L, ChronoUnit.MILLIS) val obj = Duration.of(1000000L, ChronoUnit.MILLIS)
@ -728,10 +782,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test local date serialize`() { fun `test local date serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory2))
val obj = LocalDate.now() val obj = LocalDate.now()
@ -740,10 +798,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test local time serialize`() { fun `test local time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory2))
val obj = LocalTime.now() val obj = LocalTime.now()
@ -752,10 +814,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test local date time serialize`() { fun `test local date time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory2))
val obj = LocalDateTime.now() val obj = LocalDateTime.now()
@ -764,10 +830,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test zoned date time serialize`() { fun `test zoned date time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory2))
val obj = ZonedDateTime.now() val obj = ZonedDateTime.now()
@ -776,10 +846,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test offset time serialize`() { fun `test offset time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory2))
val obj = OffsetTime.now() val obj = OffsetTime.now()
@ -788,10 +862,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test offset date time serialize`() { fun `test offset date time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory2))
val obj = OffsetDateTime.now() val obj = OffsetDateTime.now()
@ -800,10 +878,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test year serialize`() { fun `test year serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory2))
val obj = Year.now() val obj = Year.now()
@ -812,10 +894,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test year month serialize`() { fun `test year month serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory2))
val obj = YearMonth.now() val obj = YearMonth.now()
@ -824,10 +910,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test month day serialize`() { fun `test month day serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory2))
val obj = MonthDay.now() val obj = MonthDay.now()
@ -836,10 +926,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test period serialize`() { fun `test period serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory2))
val obj = Period.of(99, 98, 97) val obj = Period.of(99, 98, 97)
@ -866,10 +960,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test X509 certificate serialize`() { fun `test X509 certificate serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer) factory.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer)
val obj = BOB_IDENTITY.certificate val obj = BOB_IDENTITY.certificate
@ -878,10 +976,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test cert path serialize`() { fun `test cert path serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory2))
val obj = BOB_IDENTITY.certPath val obj = BOB_IDENTITY.certPath
@ -905,9 +1007,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test StateRef serialize`() { fun `test StateRef serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val obj = StateRef(SecureHash.randomSHA256(), 0) val obj = StateRef(SecureHash.randomSHA256(), 0)
serdes(obj, factory, factory2) serdes(obj, factory, factory2)
@ -953,8 +1059,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
val b = ByteArray(2) val b = ByteArray(2)
val obj = Bob(listOf(a, b, a)) val obj = Bob(listOf(a, b, a))
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val obj2 = serdes(obj, factory, factory2, false, false) val obj2 = serdes(obj, factory, factory2, false, false)
assertNotSame(obj2.byteArrays[0], obj2.byteArrays[2]) assertNotSame(obj2.byteArrays[0], obj2.byteArrays[2])
@ -967,8 +1077,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
val a = listOf("a", "b") val a = listOf("a", "b")
val obj = Vic(a, a) val obj = Vic(a, a)
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val objCopy = serdes(obj, factory, factory2) val objCopy = serdes(obj, factory, factory2)
assertSame(objCopy.a, objCopy.b) assertSame(objCopy.a, objCopy.b)
} }
@ -984,8 +1098,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
fun `test private constructor`() { fun `test private constructor`() {
val obj = Spike() val obj = Spike()
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
serdes(obj, factory, factory2) serdes(obj, factory, factory2)
} }
@ -993,10 +1111,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test toString custom serializer`() { fun `test toString custom serializer`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val obj = BigDecimals(BigDecimal.TEN, BigDecimal.TEN) val obj = BigDecimals(BigDecimal.TEN, BigDecimal.TEN)
@ -1008,10 +1130,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test BigInteger custom serializer`() { fun `test BigInteger custom serializer`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer) factory.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer)
val obj = BigIntegers(BigInteger.TEN, BigInteger.TEN) val obj = BigIntegers(BigInteger.TEN, BigInteger.TEN)
@ -1028,10 +1154,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test X509CRL custom serializer`() { fun `test X509CRL custom serializer`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer) factory.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer)
val obj = emptyCrl() val obj = emptyCrl()
@ -1042,10 +1172,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test byte arrays not reference counted`() { fun `test byte arrays not reference counted`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val bytes = ByteArray(1) val bytes = ByteArray(1)
@ -1056,10 +1190,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test StringBuffer serialize`() { fun `test StringBuffer serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer) factory.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer)
val obj = StringBuffer("Bob") val obj = StringBuffer("Bob")
@ -1069,10 +1207,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test SimpleString serialize`() { fun `test SimpleString serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer) factory.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer)
val obj = SimpleString("Bob") val obj = SimpleString("Bob")
@ -1093,10 +1235,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test InputStream serialize`() { fun `test InputStream serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer) factory.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer) factory2.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer)
val bytes = ByteArray(10) { it.toByte() } val bytes = ByteArray(10) { it.toByte() }
val obj = bytes.inputStream() val obj = bytes.inputStream()
@ -1108,10 +1254,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test EnumSet serialize`() { fun `test EnumSet serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory2))
val obj = EnumSet.of(Month.APRIL, Month.AUGUST) val obj = EnumSet.of(Month.APRIL, Month.AUGUST)
@ -1120,10 +1270,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test BitSet serialize`() { fun `test BitSet serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory2))
val obj = BitSet.valueOf(kotlin.ByteArray(16) { it.toByte() }).get(0, 123) val obj = BitSet.valueOf(kotlin.ByteArray(16) { it.toByte() }).get(0, 123)
@ -1140,10 +1294,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test contract attachment serialize`() { fun `test contract attachment serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2))
val obj = ContractAttachment(GeneratedAttachment("test".toByteArray()), DummyContract.PROGRAM_ID) val obj = ContractAttachment(GeneratedAttachment("test".toByteArray()), DummyContract.PROGRAM_ID)
@ -1156,10 +1314,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `test contract attachment throws if missing attachment`() { fun `test contract attachment throws if missing attachment`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory)) factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2))
val obj = ContractAttachment(object : AbstractAttachment({ throw Exception() }) { val obj = ContractAttachment(object : AbstractAttachment({ throw Exception() }) {
@ -1351,7 +1513,9 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test @Test
fun `compression reduces number of bytes significantly`() { fun `compression reduces number of bytes significantly`() {
val ser = SerializationOutput(SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) val ser = SerializationOutput(SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val obj = ByteArray(20000) val obj = ByteArray(20000)
val uncompressedSize = ser.serialize(obj).bytes.size val uncompressedSize = ser.serialize(obj).bytes.size
val compressedSize = ser.serialize(obj, CordaSerializationEncoding.SNAPPY).bytes.size val compressedSize = ser.serialize(obj, CordaSerializationEncoding.SNAPPY).bytes.size

View File

@ -102,14 +102,13 @@ class SerializationPropertyOrdering {
// Test needs to look at a bunch of private variables, change the access semantics for them // Test needs to look at a bunch of private variables, change the access semantics for them
val fields : Map<String, java.lang.reflect.Field> = mapOf ( val fields : Map<String, java.lang.reflect.Field> = mapOf (
"serializersByDesc" to SerializerFactory::class.java.getDeclaredField("serializersByDescriptor"),
"setter" to PropertyAccessorGetterSetter::class.java.getDeclaredField("setter")).apply { "setter" to PropertyAccessorGetterSetter::class.java.getDeclaredField("setter")).apply {
this.values.forEach { this.values.forEach {
it.isAccessible = true it.isAccessible = true
} }
} }
val serializersByDescriptor = fields["serializersByDesc"]!!.get(sf) as ConcurrentHashMap<Any, AMQPSerializer<Any>> val serializersByDescriptor = sf.serializersByDescriptor
val schemaDescriptor = output.schema.types.first().descriptor.name val schemaDescriptor = output.schema.types.first().descriptor.name
// make sure that each property accessor has a setter to ensure we're using getter / setter instantiation // make sure that each property accessor has a setter to ensure we're using getter / setter instantiation

View File

@ -6,6 +6,7 @@ import net.corda.serialization.internal.BuiltInExceptionsWhitelist
import net.corda.serialization.internal.CordaSerializationMagic import net.corda.serialization.internal.CordaSerializationMagic
import net.corda.serialization.internal.GlobalTransientClassWhiteList import net.corda.serialization.internal.GlobalTransientClassWhiteList
import net.corda.serialization.internal.SerializationContextImpl import net.corda.serialization.internal.SerializationContextImpl
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -22,7 +23,7 @@ val TESTING_CONTEXT = SerializationContextImpl(amqpMagic,
class TestSerializerFactory( class TestSerializerFactory(
wl: ClassWhitelist, wl: ClassWhitelist,
cl: ClassLoader cl: ClassLoader
) : SerializerFactory(wl, cl) { ) : DefaultSerializerFactory(wl, ClassCarpenterImpl(wl, cl, false), DefaultEvolutionSerializerProvider, ::SerializerFingerPrinter) {
var registerCount = 0 var registerCount = 0
override fun register(customSerializer: CustomSerializer<out Any>) { override fun register(customSerializer: CustomSerializer<out Any>) {

View File

@ -48,7 +48,9 @@ class StaticInitialisationOfSerializedObjectTest {
fun kotlinObjectWithCompanionObject() { fun kotlinObjectWithCompanionObject() {
data class D(val c: C) data class D(val c: C)
val sf = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) val sf = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val typeMap = sf::class.java.getDeclaredField("serializersByType") val typeMap = sf::class.java.getDeclaredField("serializersByType")
typeMap.isAccessible = true typeMap.isAccessible = true
@ -87,7 +89,10 @@ class StaticInitialisationOfSerializedObjectTest {
".StaticInitialisationOfSerializedObjectTest\$deserializeTest\$D" ".StaticInitialisationOfSerializedObjectTest\$deserializeTest\$D"
} }
val sf2 = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) val whitelist = WL()
val sf2 = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
val bytes = url.readBytes() val bytes = url.readBytes()
assertThatThrownBy { assertThatThrownBy {
@ -97,8 +102,8 @@ class StaticInitialisationOfSerializedObjectTest {
// Version of a serializer factory that will allow the class carpenter living on the // Version of a serializer factory that will allow the class carpenter living on the
// factory to have a different whitelist applied to it than the factory // factory to have a different whitelist applied to it than the factory
class TestSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) : private fun testSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) =
SerializerFactory(wl1, ClassCarpenterImpl(wl2, ClassLoader.getSystemClassLoader())) SerializerFactoryBuilder.build(wl1, ClassCarpenterImpl(wl2, ClassLoader.getSystemClassLoader()))
// This time have the serialization factory and the carpenter use different whitelists // This time have the serialization factory and the carpenter use different whitelists
@Test @Test
@ -126,7 +131,7 @@ class StaticInitialisationOfSerializedObjectTest {
override fun hasListed(type: Class<*>) = true override fun hasListed(type: Class<*>) = true
} }
val sf2 = TestSerializerFactory(WL1(), WL2()) val sf2 = testSerializerFactory(WL1(), WL2())
val bytes = url.readBytes() val bytes = url.readBytes()
// Deserializing should throw because C is not on the whitelist NOT because // Deserializing should throw because C is not on the whitelist NOT because

View File

@ -10,6 +10,7 @@ import net.corda.core.utilities.OpaqueBytes
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.EmptyWhitelist import net.corda.serialization.internal.EmptyWhitelist
import net.corda.serialization.internal.amqp.* import net.corda.serialization.internal.amqp.*
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import net.corda.testing.common.internal.ProjectStructure import net.corda.testing.common.internal.ProjectStructure
import org.apache.qpid.proton.codec.Data import org.apache.qpid.proton.codec.Data
import org.junit.Test import org.junit.Test
@ -17,16 +18,20 @@ import java.io.File.separatorChar
import java.io.NotSerializableException import java.io.NotSerializableException
import java.nio.file.StandardCopyOption.REPLACE_EXISTING import java.nio.file.StandardCopyOption.REPLACE_EXISTING
fun testDefaultFactory() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) fun testDefaultFactory() = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
fun testDefaultFactoryNoEvolution(): SerializerFactory { fun testDefaultFactoryNoEvolution(): SerializerFactory {
return SerializerFactory( return SerializerFactoryBuilder.build(
AllWhitelist, AllWhitelist,
ClassLoader.getSystemClassLoader(), ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
evolutionSerializerProvider = FailIfEvolutionAttempted) FailIfEvolutionAttempted)
} }
fun testDefaultFactoryWithWhitelist() = SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()) fun testDefaultFactoryWithWhitelist() = SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
)
class TestSerializationOutput( class TestSerializationOutput(
private val verbose: Boolean, private val verbose: Boolean,

View File

@ -5,7 +5,6 @@ import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.* import net.corda.serialization.internal.amqp.*
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.serialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.junit.Test import org.junit.Test
@ -33,8 +32,8 @@ interface TestInterface {
// Create a custom serialization factory where we need to be able to both specify a carpenter // Create a custom serialization factory where we need to be able to both specify a carpenter
// but also have the class loader used by the carpenter be substantially different from the // but also have the class loader used by the carpenter be substantially different from the
// one used by the factory so as to ensure we can control their behaviour independently. // one used by the factory so as to ensure we can control their behaviour independently.
class TestFactory(classCarpenter: ClassCarpenter) private fun testFactory(classCarpenter: ClassCarpenter)
: SerializerFactory(classCarpenter.whitelist, classCarpenter) = SerializerFactoryBuilder.build(classCarpenter.whitelist, classCarpenter)
class CarpenterExceptionTests { class CarpenterExceptionTests {
companion object { companion object {
@ -90,7 +89,7 @@ class CarpenterExceptionTests {
// we set the class loader of the ClassCarpenter to reject one of them, resulting in a CarpentryError // we set the class loader of the ClassCarpenter to reject one of them, resulting in a CarpentryError
// which we then want the code to wrap in a NotSerializeableException // which we then want the code to wrap in a NotSerializeableException
val cc = ClassCarpenterImpl(AllWhitelist, TestClassLoader(listOf(C2::class.jvmName))) val cc = ClassCarpenterImpl(AllWhitelist, TestClassLoader(listOf(C2::class.jvmName)))
val factory = TestFactory(cc) val factory = testFactory(cc)
Assertions.assertThatThrownBy { Assertions.assertThatThrownBy {
DeserializationInput(factory).deserialize(ser) DeserializationInput(factory).deserialize(ser)

View File

@ -41,12 +41,12 @@ fun Schema.mangleNames(names: List<String>): Schema {
* Custom implementation of a [SerializerFactory] where we need to give it a class carpenter * Custom implementation of a [SerializerFactory] where we need to give it a class carpenter
* rather than have it create its own * rather than have it create its own
*/ */
class SerializerFactoryExternalCarpenter(classCarpenter: ClassCarpenter) private fun serializerFactoryExternalCarpenter(classCarpenter: ClassCarpenter)
: SerializerFactory(classCarpenter.whitelist, classCarpenter) = SerializerFactoryBuilder.build(classCarpenter.whitelist, classCarpenter)
open class AmqpCarpenterBase(whitelist: ClassWhitelist) { open class AmqpCarpenterBase(whitelist: ClassWhitelist) {
var cc = ClassCarpenterImpl(whitelist = whitelist) var cc = ClassCarpenterImpl(whitelist = whitelist)
var factory = SerializerFactoryExternalCarpenter(cc) var factory = serializerFactoryExternalCarpenter(cc)
fun <T: Any> serialise(obj: T): SerializedBytes<T> = SerializationOutput(factory).serialize(obj) fun <T: Any> serialise(obj: T): SerializedBytes<T> = SerializationOutput(factory).serialize(obj)
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")