From c1909722f606fc64174e17afad8ccf864a105bcf Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Thu, 23 Jan 2020 09:21:01 +0000 Subject: [PATCH] CORDA-3552: Reuse a single SerializerFactory when deserialising a LedgerTransaction into the DJVM sandbox. (#5874) --- .../djvm/AMQPSerializationScheme.kt | 146 +--------------- .../djvm/SandboxSerializationSchemeBuilder.kt | 148 ++++++++++++++++ .../corda/serialization/djvm/Serialization.kt | 17 +- .../serialization/djvm/LocalTypeModelTest.kt | 161 ++++++++++++++++++ 4 files changed, 325 insertions(+), 147 deletions(-) create mode 100644 serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/SandboxSerializationSchemeBuilder.kt create mode 100644 serialization-djvm/src/test/kotlin/net/corda/serialization/djvm/LocalTypeModelTest.kt diff --git a/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/AMQPSerializationScheme.kt b/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/AMQPSerializationScheme.kt index 948be91685..91250fee68 100644 --- a/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/AMQPSerializationScheme.kt +++ b/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/AMQPSerializationScheme.kt @@ -1,162 +1,30 @@ package net.corda.serialization.djvm -import net.corda.core.internal.objectOrNewInstance import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.SerializationContext.UseCase -import net.corda.core.serialization.SerializationWhitelist import net.corda.core.serialization.SerializedBytes import net.corda.core.utilities.ByteSequence -import net.corda.djvm.rewiring.SandboxClassLoader -import net.corda.serialization.djvm.deserializers.MergeWhitelists -import net.corda.serialization.djvm.serializers.SandboxBitSetSerializer -import net.corda.serialization.djvm.serializers.SandboxCertPathSerializer -import net.corda.serialization.djvm.serializers.SandboxCharacterSerializer -import net.corda.serialization.djvm.serializers.SandboxCollectionSerializer -import net.corda.serialization.djvm.serializers.SandboxCorDappCustomSerializer -import net.corda.serialization.djvm.serializers.SandboxCurrencySerializer -import net.corda.serialization.djvm.serializers.SandboxDecimal128Serializer -import net.corda.serialization.djvm.serializers.SandboxDecimal32Serializer -import net.corda.serialization.djvm.serializers.SandboxDecimal64Serializer -import net.corda.serialization.djvm.serializers.SandboxDurationSerializer -import net.corda.serialization.djvm.serializers.SandboxEnumSerializer -import net.corda.serialization.djvm.serializers.SandboxEnumSetSerializer -import net.corda.serialization.djvm.serializers.SandboxInputStreamSerializer -import net.corda.serialization.djvm.serializers.SandboxInstantSerializer -import net.corda.serialization.djvm.serializers.SandboxLocalDateSerializer -import net.corda.serialization.djvm.serializers.SandboxLocalDateTimeSerializer -import net.corda.serialization.djvm.serializers.SandboxLocalTimeSerializer -import net.corda.serialization.djvm.serializers.SandboxMapSerializer -import net.corda.serialization.djvm.serializers.SandboxMonthDaySerializer -import net.corda.serialization.djvm.serializers.SandboxOffsetDateTimeSerializer -import net.corda.serialization.djvm.serializers.SandboxOffsetTimeSerializer -import net.corda.serialization.djvm.serializers.SandboxOpaqueBytesSubSequenceSerializer -import net.corda.serialization.djvm.serializers.SandboxOptionalSerializer -import net.corda.serialization.djvm.serializers.SandboxPeriodSerializer -import net.corda.serialization.djvm.serializers.SandboxPrimitiveSerializer -import net.corda.serialization.djvm.serializers.SandboxPublicKeySerializer -import net.corda.serialization.djvm.serializers.SandboxSymbolSerializer -import net.corda.serialization.djvm.serializers.SandboxToStringSerializer -import net.corda.serialization.djvm.serializers.SandboxUnsignedByteSerializer -import net.corda.serialization.djvm.serializers.SandboxUnsignedIntegerSerializer -import net.corda.serialization.djvm.serializers.SandboxUnsignedLongSerializer -import net.corda.serialization.djvm.serializers.SandboxUnsignedShortSerializer -import net.corda.serialization.djvm.serializers.SandboxX509CRLSerializer -import net.corda.serialization.djvm.serializers.SandboxX509CertificateSerializer -import net.corda.serialization.djvm.serializers.SandboxYearMonthSerializer -import net.corda.serialization.djvm.serializers.SandboxYearSerializer -import net.corda.serialization.djvm.serializers.SandboxZoneIdSerializer -import net.corda.serialization.djvm.serializers.SandboxZonedDateTimeSerializer import net.corda.serialization.internal.CordaSerializationMagic import net.corda.serialization.internal.SerializationScheme import net.corda.serialization.internal.amqp.DeserializationInput import net.corda.serialization.internal.amqp.SerializationOutput import net.corda.serialization.internal.amqp.SerializerFactory -import net.corda.serialization.internal.amqp.SerializerFactoryFactory -import net.corda.serialization.internal.amqp.addToWhitelist import net.corda.serialization.internal.amqp.amqpMagic -import java.math.BigDecimal -import java.math.BigInteger -import java.util.Date -import java.util.UUID -import java.util.function.Function +/** + * This is an ephemeral [SerializationScheme] that will only ever + * support a single [SerializerFactory]. The [ClassLoader] that + * underpins everything this scheme is deserializing is not expected + * to be long-lived either. + */ class AMQPSerializationScheme( - private val classLoader: SandboxClassLoader, - private val sandboxBasicInput: Function, - private val rawTaskFactory: Function>, - private val customSerializerClassNames: Set, - private val serializationWhitelistNames: Set, - private val serializerFactoryFactory: SerializerFactoryFactory + val serializerFactory: SerializerFactory ) : SerializationScheme { - - private fun getSerializerFactory(context: SerializationContext): SerializerFactory { - val taskFactory = rawTaskFactory.compose(classLoader.createSandboxFunction()) - return serializerFactoryFactory.make(context).apply { - register(SandboxBitSetSerializer(classLoader, taskFactory, this)) - register(SandboxCertPathSerializer(classLoader, taskFactory, this)) - register(SandboxDurationSerializer(classLoader, taskFactory, this)) - register(SandboxEnumSetSerializer(classLoader, taskFactory, this)) - register(SandboxInputStreamSerializer(classLoader, taskFactory)) - register(SandboxInstantSerializer(classLoader, taskFactory, this)) - register(SandboxLocalDateSerializer(classLoader, taskFactory, this)) - register(SandboxLocalDateTimeSerializer(classLoader, taskFactory, this)) - register(SandboxLocalTimeSerializer(classLoader, taskFactory, this)) - register(SandboxMonthDaySerializer(classLoader, taskFactory, this)) - register(SandboxOffsetDateTimeSerializer(classLoader, taskFactory, this)) - register(SandboxOffsetTimeSerializer(classLoader, taskFactory, this)) - register(SandboxPeriodSerializer(classLoader, taskFactory, this)) - register(SandboxYearMonthSerializer(classLoader, taskFactory, this)) - register(SandboxYearSerializer(classLoader, taskFactory, this)) - register(SandboxZonedDateTimeSerializer(classLoader, taskFactory, this)) - register(SandboxZoneIdSerializer(classLoader, taskFactory, this)) - register(SandboxOpaqueBytesSubSequenceSerializer(classLoader, taskFactory, this)) - register(SandboxOptionalSerializer(classLoader, taskFactory, this)) - register(SandboxPrimitiveSerializer(UUID::class.java, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(String::class.java, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Byte::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Short::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Int::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Long::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Float::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Double::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Boolean::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxPrimitiveSerializer(Date::class.javaObjectType, classLoader, sandboxBasicInput)) - register(SandboxCharacterSerializer(classLoader, sandboxBasicInput)) - register(SandboxCollectionSerializer(classLoader, taskFactory, this)) - register(SandboxMapSerializer(classLoader, taskFactory, this)) - register(SandboxEnumSerializer(classLoader, taskFactory, this)) - register(SandboxPublicKeySerializer(classLoader, taskFactory)) - register(SandboxToStringSerializer(BigDecimal::class.java, classLoader, rawTaskFactory, sandboxBasicInput)) - register(SandboxToStringSerializer(BigInteger::class.java, classLoader, rawTaskFactory, sandboxBasicInput)) - register(SandboxToStringSerializer(StringBuffer::class.java, classLoader, rawTaskFactory, sandboxBasicInput)) - register(SandboxCurrencySerializer(classLoader, taskFactory, sandboxBasicInput)) - register(SandboxX509CertificateSerializer(classLoader, taskFactory)) - register(SandboxX509CRLSerializer(classLoader, taskFactory)) - register(SandboxUnsignedLongSerializer(classLoader, taskFactory)) - register(SandboxUnsignedIntegerSerializer(classLoader, taskFactory)) - register(SandboxUnsignedShortSerializer(classLoader, taskFactory)) - register(SandboxUnsignedByteSerializer(classLoader, taskFactory)) - register(SandboxDecimal128Serializer(classLoader, taskFactory)) - register(SandboxDecimal64Serializer(classLoader, taskFactory)) - register(SandboxDecimal32Serializer(classLoader, taskFactory)) - register(SandboxSymbolSerializer(classLoader, taskFactory, sandboxBasicInput)) - - for (customSerializerName in customSerializerClassNames) { - register(SandboxCorDappCustomSerializer(customSerializerName, classLoader, rawTaskFactory, this)) - } - registerWhitelists(taskFactory, this) - } - } - - private fun registerWhitelists( - taskFactory: Function>, out Function>, - factory: SerializerFactory - ) { - if (serializationWhitelistNames.isEmpty()) { - return - } - - val serializationWhitelists = serializationWhitelistNames.map { whitelistClass -> - classLoader.toSandboxClass(whitelistClass).kotlin.objectOrNewInstance() - }.toArrayOf(classLoader.toSandboxClass(SerializationWhitelist::class.java)) - @Suppress("unchecked_cast") - val mergeTask = taskFactory.apply(MergeWhitelists::class.java) as Function, out Array>> - factory.addToWhitelist(mergeTask.apply(serializationWhitelists).toSet()) - } - - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") - private fun Collection<*>.toArrayOf(type: Class<*>): Array<*> { - val typedArray = java.lang.reflect.Array.newInstance(type, 0) as Array<*> - return (this as java.util.Collection<*>).toArray(typedArray) - } - override fun deserialize(byteSequence: ByteSequence, clazz: Class, context: SerializationContext): T { - val serializerFactory = getSerializerFactory(context) return DeserializationInput(serializerFactory).deserialize(byteSequence, clazz, context) } override fun serialize(obj: T, context: SerializationContext): SerializedBytes { - val serializerFactory = getSerializerFactory(context) return SerializationOutput(serializerFactory).serialize(obj, context) } diff --git a/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/SandboxSerializationSchemeBuilder.kt b/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/SandboxSerializationSchemeBuilder.kt new file mode 100644 index 0000000000..8f4f9e7474 --- /dev/null +++ b/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/SandboxSerializationSchemeBuilder.kt @@ -0,0 +1,148 @@ +package net.corda.serialization.djvm + +import net.corda.core.internal.objectOrNewInstance +import net.corda.core.serialization.SerializationContext +import net.corda.core.serialization.SerializationWhitelist +import net.corda.djvm.rewiring.SandboxClassLoader +import net.corda.serialization.djvm.deserializers.MergeWhitelists +import net.corda.serialization.djvm.serializers.SandboxBitSetSerializer +import net.corda.serialization.djvm.serializers.SandboxCertPathSerializer +import net.corda.serialization.djvm.serializers.SandboxCharacterSerializer +import net.corda.serialization.djvm.serializers.SandboxCollectionSerializer +import net.corda.serialization.djvm.serializers.SandboxCorDappCustomSerializer +import net.corda.serialization.djvm.serializers.SandboxCurrencySerializer +import net.corda.serialization.djvm.serializers.SandboxDecimal128Serializer +import net.corda.serialization.djvm.serializers.SandboxDecimal32Serializer +import net.corda.serialization.djvm.serializers.SandboxDecimal64Serializer +import net.corda.serialization.djvm.serializers.SandboxDurationSerializer +import net.corda.serialization.djvm.serializers.SandboxEnumSerializer +import net.corda.serialization.djvm.serializers.SandboxEnumSetSerializer +import net.corda.serialization.djvm.serializers.SandboxInputStreamSerializer +import net.corda.serialization.djvm.serializers.SandboxInstantSerializer +import net.corda.serialization.djvm.serializers.SandboxLocalDateSerializer +import net.corda.serialization.djvm.serializers.SandboxLocalDateTimeSerializer +import net.corda.serialization.djvm.serializers.SandboxLocalTimeSerializer +import net.corda.serialization.djvm.serializers.SandboxMapSerializer +import net.corda.serialization.djvm.serializers.SandboxMonthDaySerializer +import net.corda.serialization.djvm.serializers.SandboxOffsetDateTimeSerializer +import net.corda.serialization.djvm.serializers.SandboxOffsetTimeSerializer +import net.corda.serialization.djvm.serializers.SandboxOpaqueBytesSubSequenceSerializer +import net.corda.serialization.djvm.serializers.SandboxOptionalSerializer +import net.corda.serialization.djvm.serializers.SandboxPeriodSerializer +import net.corda.serialization.djvm.serializers.SandboxPrimitiveSerializer +import net.corda.serialization.djvm.serializers.SandboxPublicKeySerializer +import net.corda.serialization.djvm.serializers.SandboxSymbolSerializer +import net.corda.serialization.djvm.serializers.SandboxToStringSerializer +import net.corda.serialization.djvm.serializers.SandboxUnsignedByteSerializer +import net.corda.serialization.djvm.serializers.SandboxUnsignedIntegerSerializer +import net.corda.serialization.djvm.serializers.SandboxUnsignedLongSerializer +import net.corda.serialization.djvm.serializers.SandboxUnsignedShortSerializer +import net.corda.serialization.djvm.serializers.SandboxX509CRLSerializer +import net.corda.serialization.djvm.serializers.SandboxX509CertificateSerializer +import net.corda.serialization.djvm.serializers.SandboxYearMonthSerializer +import net.corda.serialization.djvm.serializers.SandboxYearSerializer +import net.corda.serialization.djvm.serializers.SandboxZoneIdSerializer +import net.corda.serialization.djvm.serializers.SandboxZonedDateTimeSerializer +import net.corda.serialization.internal.SerializationScheme +import net.corda.serialization.internal.amqp.SerializerFactory +import net.corda.serialization.internal.amqp.SerializerFactoryFactory +import net.corda.serialization.internal.amqp.addToWhitelist +import java.math.BigDecimal +import java.math.BigInteger +import java.util.Date +import java.util.UUID +import java.util.function.Function + +class SandboxSerializationSchemeBuilder( + private val classLoader: SandboxClassLoader, + private val sandboxBasicInput: Function, + private val rawTaskFactory: Function>, + private val customSerializerClassNames: Set, + private val serializationWhitelistNames: Set, + private val serializerFactoryFactory: SerializerFactoryFactory +) { + fun buildFor(context: SerializationContext): SerializationScheme { + return AMQPSerializationScheme(getSerializerFactory(context)) + } + + private fun getSerializerFactory(context: SerializationContext): SerializerFactory { + val taskFactory = rawTaskFactory.compose(classLoader.createSandboxFunction()) + return serializerFactoryFactory.make(context).apply { + register(SandboxBitSetSerializer(classLoader, taskFactory, this)) + register(SandboxCertPathSerializer(classLoader, taskFactory, this)) + register(SandboxDurationSerializer(classLoader, taskFactory, this)) + register(SandboxEnumSetSerializer(classLoader, taskFactory, this)) + register(SandboxInputStreamSerializer(classLoader, taskFactory)) + register(SandboxInstantSerializer(classLoader, taskFactory, this)) + register(SandboxLocalDateSerializer(classLoader, taskFactory, this)) + register(SandboxLocalDateTimeSerializer(classLoader, taskFactory, this)) + register(SandboxLocalTimeSerializer(classLoader, taskFactory, this)) + register(SandboxMonthDaySerializer(classLoader, taskFactory, this)) + register(SandboxOffsetDateTimeSerializer(classLoader, taskFactory, this)) + register(SandboxOffsetTimeSerializer(classLoader, taskFactory, this)) + register(SandboxPeriodSerializer(classLoader, taskFactory, this)) + register(SandboxYearMonthSerializer(classLoader, taskFactory, this)) + register(SandboxYearSerializer(classLoader, taskFactory, this)) + register(SandboxZonedDateTimeSerializer(classLoader, taskFactory, this)) + register(SandboxZoneIdSerializer(classLoader, taskFactory, this)) + register(SandboxOpaqueBytesSubSequenceSerializer(classLoader, taskFactory, this)) + register(SandboxOptionalSerializer(classLoader, taskFactory, this)) + register(SandboxPrimitiveSerializer(UUID::class.java, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(String::class.java, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Byte::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Short::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Int::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Long::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Float::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Double::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Boolean::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxPrimitiveSerializer(Date::class.javaObjectType, classLoader, sandboxBasicInput)) + register(SandboxCharacterSerializer(classLoader, sandboxBasicInput)) + register(SandboxCollectionSerializer(classLoader, taskFactory, this)) + register(SandboxMapSerializer(classLoader, taskFactory, this)) + register(SandboxEnumSerializer(classLoader, taskFactory, this)) + register(SandboxPublicKeySerializer(classLoader, taskFactory)) + register(SandboxToStringSerializer(BigDecimal::class.java, classLoader, rawTaskFactory, sandboxBasicInput)) + register(SandboxToStringSerializer(BigInteger::class.java, classLoader, rawTaskFactory, sandboxBasicInput)) + register(SandboxToStringSerializer(StringBuffer::class.java, classLoader, rawTaskFactory, sandboxBasicInput)) + register(SandboxCurrencySerializer(classLoader, taskFactory, sandboxBasicInput)) + register(SandboxX509CertificateSerializer(classLoader, taskFactory)) + register(SandboxX509CRLSerializer(classLoader, taskFactory)) + register(SandboxUnsignedLongSerializer(classLoader, taskFactory)) + register(SandboxUnsignedIntegerSerializer(classLoader, taskFactory)) + register(SandboxUnsignedShortSerializer(classLoader, taskFactory)) + register(SandboxUnsignedByteSerializer(classLoader, taskFactory)) + register(SandboxDecimal128Serializer(classLoader, taskFactory)) + register(SandboxDecimal64Serializer(classLoader, taskFactory)) + register(SandboxDecimal32Serializer(classLoader, taskFactory)) + register(SandboxSymbolSerializer(classLoader, taskFactory, sandboxBasicInput)) + + for (customSerializerName in customSerializerClassNames) { + register(SandboxCorDappCustomSerializer(customSerializerName, classLoader, rawTaskFactory, this)) + } + registerWhitelists(taskFactory, this) + } + } + + private fun registerWhitelists( + taskFactory: Function>, out Function>, + factory: SerializerFactory + ) { + if (serializationWhitelistNames.isEmpty()) { + return + } + + val serializationWhitelists = serializationWhitelistNames.map { whitelistClass -> + classLoader.toSandboxClass(whitelistClass).kotlin.objectOrNewInstance() + }.toArrayOf(classLoader.toSandboxClass(SerializationWhitelist::class.java)) + @Suppress("unchecked_cast") + val mergeTask = taskFactory.apply(MergeWhitelists::class.java) as Function, out Array>> + factory.addToWhitelist(mergeTask.apply(serializationWhitelists).toSet()) + } + + @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") + private fun Collection<*>.toArrayOf(type: Class<*>): Array<*> { + val typedArray = java.lang.reflect.Array.newInstance(type, 0) as Array<*> + return (this as java.util.Collection<*>).toArray(typedArray) + } +} diff --git a/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/Serialization.kt b/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/Serialization.kt index 2f89fb1317..7c8a107201 100644 --- a/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/Serialization.kt +++ b/serialization-djvm/src/main/kotlin/net/corda/serialization/djvm/Serialization.kt @@ -49,15 +49,16 @@ fun createSandboxSerializationEnv( PrimitiveSerializer(clazz, sandboxBasicInput) } + val schemeBuilder = SandboxSerializationSchemeBuilder( + classLoader = classLoader, + sandboxBasicInput = sandboxBasicInput, + rawTaskFactory = rawTaskFactory, + customSerializerClassNames = customSerializerClassNames, + serializationWhitelistNames = serializationWhitelistNames, + serializerFactoryFactory = SandboxSerializerFactoryFactory(primitiveSerializerFactory) + ) val factory = SerializationFactoryImpl(mutableMapOf()).apply { - registerScheme(AMQPSerializationScheme( - classLoader = classLoader, - sandboxBasicInput = sandboxBasicInput, - rawTaskFactory = rawTaskFactory, - customSerializerClassNames = customSerializerClassNames, - serializationWhitelistNames = serializationWhitelistNames, - serializerFactoryFactory = SandboxSerializerFactoryFactory(primitiveSerializerFactory) - )) + registerScheme(schemeBuilder.buildFor(p2pContext)) } return SerializationEnvironment.with(factory, p2pContext = p2pContext) } diff --git a/serialization-djvm/src/test/kotlin/net/corda/serialization/djvm/LocalTypeModelTest.kt b/serialization-djvm/src/test/kotlin/net/corda/serialization/djvm/LocalTypeModelTest.kt new file mode 100644 index 0000000000..2a3c45bda6 --- /dev/null +++ b/serialization-djvm/src/test/kotlin/net/corda/serialization/djvm/LocalTypeModelTest.kt @@ -0,0 +1,161 @@ +package net.corda.serialization.djvm + +import net.corda.core.serialization.SerializationFactory +import net.corda.core.serialization.internal._contextSerializationEnv +import net.corda.djvm.rewiring.SandboxClassLoader +import net.corda.serialization.djvm.SandboxType.KOTLIN +import net.corda.serialization.internal.SerializationFactoryImpl +import net.corda.serialization.internal.amqp.SerializerFactory +import net.corda.serialization.internal.model.LocalTypeInformation +import net.corda.serialization.internal.model.LocalTypeInformation.Atomic +import net.corda.serialization.internal.model.LocalTypeInformation.Opaque +import org.apache.qpid.proton.amqp.Decimal128 +import org.apache.qpid.proton.amqp.Decimal32 +import org.apache.qpid.proton.amqp.Decimal64 +import org.apache.qpid.proton.amqp.Symbol +import org.apache.qpid.proton.amqp.UnsignedByte +import org.apache.qpid.proton.amqp.UnsignedInteger +import org.apache.qpid.proton.amqp.UnsignedLong +import org.apache.qpid.proton.amqp.UnsignedShort +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import java.util.Date +import java.util.UUID + +@ExtendWith(LocalSerialization::class) +class LocalTypeModelTest : TestBase(KOTLIN) { + private val serializerFactory: SerializerFactory get() { + val factory = SerializationFactory.defaultFactory as SerializationFactoryImpl + val scheme = factory.getRegisteredSchemes().single() as AMQPSerializationScheme + return scheme.serializerFactory + } + + private inline fun sandbox(classLoader: SandboxClassLoader): Class<*> { + return classLoader.toSandboxClass(T::class.java) + } + + private inline fun assertLocalType(type: Class<*>) { + assertLocalType(LOCAL::class.java, type) + } + + private fun assertLocalType(localType: Class, type: Class<*>) { + val typeData = serializerFactory.getTypeInformation(type) + assertThat(typeData).isInstanceOf(localType) + } + + @Test + fun testString() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testLong() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + assertLocalType(Long::class.javaPrimitiveType!!) + } + + @Test + fun testInteger() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + assertLocalType(Int::class.javaPrimitiveType!!) + } + + @Test + fun testShort() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + assertLocalType(Short::class.javaPrimitiveType!!) + } + + @Test + fun testByte() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + assertLocalType(Byte::class.javaPrimitiveType!!) + } + + @Test + fun testDouble() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + assertLocalType(Double::class.javaPrimitiveType!!) + } + + @Test + fun testFloat() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + assertLocalType(Float::class.javaPrimitiveType!!) + } + + @Test + fun testChar() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + assertLocalType(Char::class.javaPrimitiveType!!) + } + + @Test + fun testUnsignedLong() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testUnsignedInteger() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testUnsignedShort() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testUnsignedByte() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testDecimal32() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testDecimal64() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testDecimal128() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testSymbol() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testUUID() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } + + @Test + fun testDate() = sandbox { + _contextSerializationEnv.set(createSandboxSerializationEnv(classLoader)) + assertLocalType(sandbox(classLoader)) + } +} \ No newline at end of file