CORDA-786 - Use reflection to infer proxy and proxied types in CorDapp custom serializers

This removes any need for the user implement and override types from the
super class

    * CORDA-786 - Docs update
    * CORDA-786 - Remove unneeded second annotation on the proxy objects
    * Fix merge conflicts
This commit is contained in:
Katelyn Baker 2017-12-04 13:10:02 +00:00
parent d25b7f560c
commit fcec60e232
18 changed files with 80 additions and 110 deletions

View File

@ -38,7 +38,6 @@ interface Cordapp {
val schedulableFlows: List<Class<out FlowLogic<*>>> val schedulableFlows: List<Class<out FlowLogic<*>>>
val services: List<Class<out SerializeAsToken>> val services: List<Class<out SerializeAsToken>>
val serializationWhitelists: List<SerializationWhitelist> val serializationWhitelists: List<SerializationWhitelist>
val serializationCustomSerializerProxies: List<Class<*>>
val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>> val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>>
val customSchemas: Set<MappedSchema> val customSchemas: Set<MappedSchema>
val jarPath: URL val jarPath: URL

View File

@ -17,7 +17,6 @@ data class CordappImpl(
override val schedulableFlows: List<Class<out FlowLogic<*>>>, override val schedulableFlows: List<Class<out FlowLogic<*>>>,
override val services: List<Class<out SerializeAsToken>>, override val services: List<Class<out SerializeAsToken>>,
override val serializationWhitelists: List<SerializationWhitelist>, override val serializationWhitelists: List<SerializationWhitelist>,
override val serializationCustomSerializerProxies: List<Class<*>>,
override val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>>, override val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>>,
override val customSchemas: Set<MappedSchema>, override val customSchemas: Set<MappedSchema>,
override val jarPath: URL) : Cordapp { override val jarPath: URL) : Cordapp {

View File

@ -8,11 +8,3 @@ package net.corda.core.serialization
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
annotation class CordaCustomSerializer annotation class CordaCustomSerializer
/**
* This annotation marks a class as being a proxy for some third party class and used by some
* implementation of [SerializationCustomSerializer]. Such classes must be annotated to allow
* them to be discovered in a CorDapp jar and loaded
*/
@Target(AnnotationTarget.CLASS)
annotation class CordaCustomSerializerProxy

View File

@ -17,9 +17,6 @@ import java.lang.reflect.Type
* *
* Failing to apply either annotation will result in the class not being loaded by Corda and thus serialization * Failing to apply either annotation will result in the class not being loaded by Corda and thus serialization
* failing * failing
*
* @property type the type of the object that this class is proxying
* @property ptype the type of the proxy object used as an intermediate representation of [type]
*/ */
interface SerializationCustomSerializer<OBJ, PROXY> { interface SerializationCustomSerializer<OBJ, PROXY> {
/** /**
@ -33,14 +30,4 @@ interface SerializationCustomSerializer<OBJ, PROXY> {
* unserializable type * unserializable type
*/ */
fun fromProxy(proxy: PROXY) : OBJ fun fromProxy(proxy: PROXY) : OBJ
/**
* Should be set to the type of the object being proxied
*/
val type: Type
/**
* Should be set to the proxy objects type
*/
val ptype: Type
} }

View File

@ -1,16 +1,18 @@
Pluggable Serializers for CorDapps Pluggable Serializers for CorDapps
================================== ==================================
To be serializable by Corda Java classes must be compiled with the -parameter switch to enable matching of it's properties
to constructor parameters. This is important because Corda's internal AMQP serialization scheme will only constuct .. contents::
To be serializable by Corda Java classes must be compiled with the -parameters switch to enable matching of it's properties
to constructor parameters. This is important because Corda's internal AMQP serialization scheme will only construct
objects using their constructors. However, when recompilation isn't possible, or classes are built in such a way that objects using their constructors. However, when recompilation isn't possible, or classes are built in such a way that
they cannot be easily modified for simple serailization, CorDapps can provide custom proxy serializers that Corda they cannot be easily modified for simple serailization, CorDapps can provide custom proxy serializers that Corda
can use to move from types it cannot serializer to an interim representation that it can with the transformation to and can use to move from types it cannot serialize to an interim representation that it can with the transformation to and
from this proxy object being handled by the supplied serializer. from this proxy object being handled by the supplied serializer.
Serializer Location Serializer Location
------------------- -------------------
Custom serializers should be placed in the plugins directory of a CorDapp or a sub directory thereof. These Custom serializer classes should follow the rules for including classes found in :doc:`cordapp-build-systems`
classes will be scanned and loaded by the CorDapp loading process.
Writing a Custom Serializer Writing a Custom Serializer
--------------------------- ---------------------------
@ -26,7 +28,9 @@ Example
------- -------
Consider this example class Consider this example class
.. sourcecode:: java .. sourcecode:: java
public final class Example { public final class Example {
private final Int a private final Int a
private final Int b private final Int b
@ -42,33 +46,31 @@ Consider this example class
public int getB() { return b; } public int getB() { return b; }
} }
Without a custom serializer we cannot serialise this class as there is no public constructor that facilitates the Without a custom serializer we cannot serialize this class as there is no public constructor that facilitates the
initialisation of al of its's properties. initialisation of all of its's properties.
To be serializable by Corda this would require a custom serializer as follows To be serializable by Corda this would require a custom serializer as follows
.. sourcecode:: kotlin .. sourcecode:: kotlin
@CordaCustomSerializer @CordaCustomSerializer
class ExampleSerializer : SerializationCustomSerializer { class ExampleSerializer : SerializationCustomSerializer<Example, ExampleSerializer.Proxy> {
@CordaCustomSerializerProxy @CordaCustomSerializerProxy
data class Proxy(val a: Int, val b: Int) data class Proxy(val a: Int, val b: Int)
override fun toProxy(obj: Any): Any = Proxy((obj as Example).a, obj.b) override fun toProxy(obj: Example) = Proxy(obj.a, obj.b)
override fun fromProxy(proxy: Any): Any { override fun fromProxy(proxy: Proxy) : Example {
val constructorArg = IntArray(2); val constructorArg = IntArray(2);
constructorArg[0] = (proxy as Proxy).a constructorArg[0] = proxy.a
constructorArg[1] = proxy.b constructorArg[1] = proxy.b
return Example.create(constructorArg) return Example.create(constructorArg)
} }
override val type: Type get() = Example::class.java
override val ptype: Type get() = Proxy::class.java
} }
Whitelisting Whitelisting
------------ ------------
By writing a custom serializer for a class it has the effect of adding that class to the whitelist, meaning such By writing a custom serializer for a class it has the effect of adding that class to the whitelist, meaning such
classes don't need explicitly adding to the CorDapp's whitelist classes don't need explicitly adding to the CorDapp's whitelist.

View File

@ -5,24 +5,70 @@ import net.corda.core.serialization.SerializationCustomSerializer
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.nameForType import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.nameForType
import org.apache.qpid.proton.amqp.Symbol import org.apache.qpid.proton.amqp.Symbol
import org.apache.qpid.proton.codec.Data import org.apache.qpid.proton.codec.Data
import java.io.NotSerializableException
import java.lang.reflect.Type import java.lang.reflect.Type
import kotlin.reflect.jvm.javaType
import kotlin.reflect.jvm.jvmErasure
/**
* Index into the types list of the parent type of the serializer object, should be the
* type that this object proxies for
*/
const val CORDAPP_TYPE = 0
/**
* Index into the types list of the parent type of the serializer object, should be the
* type of the proxy object that we're using to represent the object we're proxying for
*/
const val PROXY_TYPE = 1
/**
* Wrapper class for user provided serializers
*
* Through the CorDapp JAR scanner we will have a list of custom serializer types that implement
* the toProxy and fromProxy methods. This class takes an instance of one of those objects and
* embeds it within a serialization context associated with a serializer factory by creating
* and instance of this class and registering that with a [SerializerFactory]
*
* Proxy serializers should transform an unserializable class into a representation that we can serialize
*
* @property serializer in instance of a user written serialization proxy, normally scanned and loaded
* automatically
* @property type the Java [Type] of the class which this serializes, inferred via reflection of the
* [serializer]'s super type
* @property proxyType the Java [Type] of the class into which instances of [type] are proxied for use byt
* the underlying serialisation engine
*
* @param factory a [SerializerFactory] belonging to the context this serializer is being instantiated
* for
*/
class CorDappCustomSerializer( class CorDappCustomSerializer(
private val serialiser: SerializationCustomSerializer<*, *>, private val serializer: SerializationCustomSerializer<*, *>,
factory: SerializerFactory) factory: SerializerFactory) : AMQPSerializer<Any>, SerializerFor {
: AMQPSerializer<Any>, SerializerFor {
override val revealSubclassesInSchema: Boolean get() = false override val revealSubclassesInSchema: Boolean get() = false
override val type: Type get() = serialiser.type private val types = serializer::class.supertypes.filter { it.jvmErasure == SerializationCustomSerializer::class }
.flatMap { it.arguments }
.map { it.type!!.javaType }
init {
if (types.size != 2) {
throw NotSerializableException("Unable to determine serializer parent types")
}
}
override val type = types[CORDAPP_TYPE]
val proxyType = types[PROXY_TYPE]
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${nameForType(type)}") override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${nameForType(type)}")
val descriptor: Descriptor = Descriptor(typeDescriptor) val descriptor: Descriptor = Descriptor(typeDescriptor)
private val proxySerializer: ObjectSerializer by lazy { ObjectSerializer(serialiser.ptype, factory) } private val proxySerializer: ObjectSerializer by lazy { ObjectSerializer(proxyType, factory) }
override fun writeClassInfo(output: SerializationOutput) {} override fun writeClassInfo(output: SerializationOutput) {}
override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) { override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) {
@Suppress("UNCHECKED_CAST") val proxy = uncheckedCast<SerializationCustomSerializer<*, *>,
val proxy = (serialiser as SerializationCustomSerializer<Any?,Any?>).toProxy(obj) SerializationCustomSerializer<Any?,Any?>> (serializer).toProxy(obj)
data.withDescribed(descriptor) { data.withDescribed(descriptor) {
data.withList { data.withList {
@ -33,11 +79,10 @@ class CorDappCustomSerializer(
} }
} }
override fun readObject(obj: Any, schema: Schema, input: DeserializationInput) = override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput) =
@Suppress("UNCHECKED_CAST") uncheckedCast<SerializationCustomSerializer<*, *>, SerializationCustomSerializer<Any?,Any?>> (
(serialiser as SerializationCustomSerializer<Any?,Any?>).fromProxy( serializer).fromProxy(uncheckedCast(proxySerializer.readObject(obj, schemas, input)))!!
uncheckedCast(proxySerializer.readObject(obj, schema, input)))!!
override fun isSerializerFor(clazz: Class<*>): Boolean = clazz == type override fun isSerializerFor(clazz: Class<*>) = clazz == type
} }

View File

@ -204,8 +204,8 @@ open class SerializerFactory(val whitelist: ClassWhitelist, cl: ClassLoader) {
} }
/** /**
* Iterate over an AMQP schema, for each type ascertain weather it's on ClassPath of [classloader] amd * Iterate over an AMQP schema, for each type ascertain whether it's on ClassPath of [classloader] and,
* if not use the [ClassCarpenter] to generate a class to use in it's place * if not, use the [ClassCarpenter] to generate a class to use in it's place.
*/ */
private fun processSchema(schemaAndDescriptor: FactorySchemaAndDescriptor, sentinel: Boolean = false) { private fun processSchema(schemaAndDescriptor: FactorySchemaAndDescriptor, sentinel: Boolean = false) {
val metaSchema = CarpenterMetaSchema.newInstance() val metaSchema = CarpenterMetaSchema.newInstance()

View File

@ -2,27 +2,21 @@ package net.corda.nodeapi.internal.serialization.amqp
import org.junit.Test import org.junit.Test
import net.corda.core.serialization.CordaCustomSerializer import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.CordaCustomSerializerProxy
import net.corda.core.serialization.ClassWhitelist import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import java.io.NotSerializableException import java.io.NotSerializableException
import java.lang.reflect.Type
import kotlin.test.assertEquals import kotlin.test.assertEquals
class CorDappSerializerTests { class CorDappSerializerTests {
data class NeedsProxy (val a: String) data class NeedsProxy (val a: String)
@CordaCustomSerializer @CordaCustomSerializer
class NeedsProxyProxySerializer : SerializationCustomSerializer { class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val proxy_a_: String) data class Proxy(val proxy_a_: String)
override val type: Type get() = NeedsProxy::class.java override fun fromProxy(proxy: Proxy) = NeedsProxy(proxy.proxy_a_)
override val ptype: Type get() = Proxy::class.java override fun toProxy(obj: NeedsProxy) = Proxy(obj.a)
override fun fromProxy(proxy: Any) : Any = NeedsProxy((proxy as Proxy).proxy_a_)
override fun toProxy(obj: Any) : Any = Proxy((obj as NeedsProxy).a)
} }
// Standard proxy serializer used internally, here for comparison purposes // Standard proxy serializer used internally, here for comparison purposes
@ -34,12 +28,10 @@ class CorDappSerializerTests {
data class Proxy(val proxy_a_: String) data class Proxy(val proxy_a_: String)
override fun toProxy(obj: NeedsProxy): Proxy { override fun toProxy(obj: NeedsProxy): Proxy {
println ("InternalProxySerializer - toProxy")
return Proxy(obj.a) return Proxy(obj.a)
} }
override fun fromProxy(proxy: Proxy): NeedsProxy { override fun fromProxy(proxy: Proxy): NeedsProxy {
println ("InternalProxySerializer - fromProxy")
return NeedsProxy(proxy.proxy_a_) return NeedsProxy(proxy.proxy_a_)
} }
} }

View File

@ -181,7 +181,6 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
schedulableFlows = listOf(), schedulableFlows = listOf(),
services = listOf(), services = listOf(),
serializationWhitelists = listOf(), serializationWhitelists = listOf(),
serializationCustomSerializerProxies = listOf(),
serializationCustomSerializers = listOf(), serializationCustomSerializers = listOf(),
customSchemas = setOf(), customSchemas = setOf(),
jarPath = ContractUpgradeFlow.javaClass.protectionDomain.codeSource.location // Core JAR location jarPath = ContractUpgradeFlow.javaClass.protectionDomain.codeSource.location // Core JAR location
@ -198,7 +197,6 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
findSchedulableFlows(scanResult), findSchedulableFlows(scanResult),
findServices(scanResult), findServices(scanResult),
findPlugins(it), findPlugins(it),
findSerialiserProxies(scanResult),
findSerialzers(scanResult), findSerialzers(scanResult),
findCustomSchemas(scanResult), findCustomSchemas(scanResult),
it.url) it.url)
@ -250,10 +248,6 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
} + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app. } + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app.
} }
private fun findSerialiserProxies(scanResult: RestrictedScanResult) : List<Class<*>> {
return scanResult.getClassesWithAnnotation(Class::class, CordaCustomSerializerProxy::class)
}
private fun findSerialzers(scanResult: RestrictedScanResult) : List<Class<out SerializationCustomSerializer<*, *>>> { private fun findSerialzers(scanResult: RestrictedScanResult) : List<Class<out SerializationCustomSerializer<*, *>>> {
return scanResult.getClassesWithAnnotation(SerializationCustomSerializer::class, CordaCustomSerializer::class) return scanResult.getClassesWithAnnotation(SerializationCustomSerializer::class, CordaCustomSerializer::class)
} }

View File

@ -3,20 +3,14 @@ package net.corda.vega.plugin.customserializers
import com.opengamma.strata.market.param.CurrencyParameterSensitivities import com.opengamma.strata.market.param.CurrencyParameterSensitivities
import com.opengamma.strata.market.param.CurrencyParameterSensitivity import com.opengamma.strata.market.param.CurrencyParameterSensitivity
import net.corda.core.serialization.CordaCustomSerializer import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.CordaCustomSerializerProxy
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import java.lang.reflect.Type
@CordaCustomSerializer @CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class CurrencyParameterSensitivitiesSerializer : class CurrencyParameterSensitivitiesSerializer :
SerializationCustomSerializer<CurrencyParameterSensitivities, CurrencyParameterSensitivitiesSerializer.Proxy> { SerializationCustomSerializer<CurrencyParameterSensitivities, CurrencyParameterSensitivitiesSerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val sensitivities: List<CurrencyParameterSensitivity>) data class Proxy(val sensitivities: List<CurrencyParameterSensitivity>)
override val type: Type get() = CurrencyParameterSensitivities::class.java
override val ptype: Type get() = Proxy::class.java
override fun fromProxy(proxy: Proxy) = CurrencyParameterSensitivities.of(proxy.sensitivities) override fun fromProxy(proxy: Proxy) = CurrencyParameterSensitivities.of(proxy.sensitivities)
override fun toProxy(obj: CurrencyParameterSensitivities) = Proxy(obj.sensitivities) override fun toProxy(obj: CurrencyParameterSensitivities) = Proxy(obj.sensitivities)
} }

View File

@ -6,22 +6,16 @@ import com.opengamma.strata.data.MarketDataName
import com.opengamma.strata.collect.array.DoubleArray import com.opengamma.strata.collect.array.DoubleArray
import com.opengamma.strata.basics.currency.Currency import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.CordaCustomSerializer import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.CordaCustomSerializerProxy
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import java.lang.reflect.Type
@CordaCustomSerializer @CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class CurrencyParameterSensitivitySerializer : class CurrencyParameterSensitivitySerializer :
SerializationCustomSerializer<CurrencyParameterSensitivity, CurrencyParameterSensitivitySerializer.Proxy> { SerializationCustomSerializer<CurrencyParameterSensitivity, CurrencyParameterSensitivitySerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val currency: Currency, val marketDataName: MarketDataName<*>, data class Proxy(val currency: Currency, val marketDataName: MarketDataName<*>,
val parameterMetadata: List<ParameterMetadata>, val parameterMetadata: List<ParameterMetadata>,
val sensitivity: DoubleArray) val sensitivity: DoubleArray)
override val type: Type get() = CurrencyParameterSensitivity::class.java
override val ptype: Type get() = Proxy::class.java
override fun fromProxy(proxy: CurrencyParameterSensitivitySerializer.Proxy) = override fun fromProxy(proxy: CurrencyParameterSensitivitySerializer.Proxy) =
CurrencyParameterSensitivity.of( CurrencyParameterSensitivity.of(
proxy.marketDataName, proxy.marketDataName,

View File

@ -2,19 +2,13 @@ package net.corda.vega.plugin.customserializers
import com.opengamma.strata.basics.currency.Currency import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.CordaCustomSerializer import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.CordaCustomSerializerProxy
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import java.lang.reflect.Type
@CordaCustomSerializer @CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class CurrencySerializer : SerializationCustomSerializer<Currency, CurrencySerializer.Proxy> { class CurrencySerializer : SerializationCustomSerializer<Currency, CurrencySerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val currency: String) data class Proxy(val currency: String)
override val type: Type get() = Currency::class.java
override val ptype: Type get() = Proxy::class.java
override fun fromProxy(proxy: Proxy) = Currency.parse(proxy.currency) override fun fromProxy(proxy: Proxy) = Currency.parse(proxy.currency)
override fun toProxy(obj: Currency) = Proxy(obj.toString()) override fun toProxy(obj: Currency) = Proxy(obj.toString())
} }

View File

@ -1,20 +1,14 @@
package net.corda.vega.plugin.customserializers package net.corda.vega.plugin.customserializers
import net.corda.core.serialization.CordaCustomSerializer import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.CordaCustomSerializerProxy
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import com.opengamma.strata.collect.array.DoubleArray import com.opengamma.strata.collect.array.DoubleArray
import java.lang.reflect.Type
@CordaCustomSerializer @CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class DoubleArraySerializer : SerializationCustomSerializer<DoubleArray, DoubleArraySerializer.Proxy> { class DoubleArraySerializer : SerializationCustomSerializer<DoubleArray, DoubleArraySerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val amount: kotlin.DoubleArray) data class Proxy(val amount: kotlin.DoubleArray)
override val type: Type get() = DoubleArray::class.java
override val ptype: Type get() = Proxy::class.java
override fun fromProxy(proxy: Proxy) = DoubleArray.copyOf(proxy.amount) override fun fromProxy(proxy: Proxy) = DoubleArray.copyOf(proxy.amount)
override fun toProxy(obj: DoubleArray) = Proxy(obj.toArray()) override fun toProxy(obj: DoubleArray) = Proxy(obj.toArray())
} }

View File

@ -3,20 +3,15 @@ package net.corda.vega.plugin.customserializers
import com.opengamma.strata.basics.currency.MultiCurrencyAmount import com.opengamma.strata.basics.currency.MultiCurrencyAmount
import com.opengamma.strata.basics.currency.Currency import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.* import net.corda.core.serialization.*
import java.lang.reflect.Type
@CordaCustomSerializer @CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class MultiCurrencyAmountSerializer : class MultiCurrencyAmountSerializer :
SerializationCustomSerializer<MultiCurrencyAmount, MultiCurrencyAmountSerializer.Proxy> { SerializationCustomSerializer<MultiCurrencyAmount, MultiCurrencyAmountSerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val curencies : Map<Currency, Double>) data class Proxy(val curencies : Map<Currency, Double>)
override fun toProxy(obj: MultiCurrencyAmount) = Proxy(obj.toMap()) override fun toProxy(obj: MultiCurrencyAmount) = Proxy(obj.toMap())
override fun fromProxy(proxy: Proxy) = MultiCurrencyAmount.of(proxy.curencies) override fun fromProxy(proxy: Proxy) = MultiCurrencyAmount.of(proxy.curencies)
override val type: Type get() = MultiCurrencyAmount::class.java
override val ptype: Type get() = Proxy::class.java
} }

View File

@ -3,20 +3,14 @@ package net.corda.vega.plugin.customserializers
import com.opengamma.strata.basics.date.Tenor import com.opengamma.strata.basics.date.Tenor
import com.opengamma.strata.market.param.TenorDateParameterMetadata import com.opengamma.strata.market.param.TenorDateParameterMetadata
import net.corda.core.serialization.* import net.corda.core.serialization.*
import java.lang.reflect.Type
import java.time.LocalDate import java.time.LocalDate
@CordaCustomSerializer @CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class TenorDateParameterMetadataSerializer : class TenorDateParameterMetadataSerializer :
SerializationCustomSerializer<TenorDateParameterMetadata, TenorDateParameterMetadataSerializer.Proxy> { SerializationCustomSerializer<TenorDateParameterMetadata, TenorDateParameterMetadataSerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val tenor: Tenor, val date: LocalDate, val identifier: Tenor, val label: String) data class Proxy(val tenor: Tenor, val date: LocalDate, val identifier: Tenor, val label: String)
override val type: Type get() = TenorDateParameterMetadata::class.java
override val ptype: Type get() = Proxy::class.java
override fun toProxy(obj: TenorDateParameterMetadata) = Proxy(obj.tenor, obj.date, obj.identifier, obj.label) override fun toProxy(obj: TenorDateParameterMetadata) = Proxy(obj.tenor, obj.date, obj.identifier, obj.label)
override fun fromProxy(proxy: Proxy) = TenorDateParameterMetadata.of(proxy.date, proxy.tenor, proxy.label) override fun fromProxy(proxy: Proxy) = TenorDateParameterMetadata.of(proxy.date, proxy.tenor, proxy.label)
} }

View File

@ -2,18 +2,13 @@ package net.corda.vega.plugin.customserializers
import com.opengamma.strata.basics.date.Tenor import com.opengamma.strata.basics.date.Tenor
import net.corda.core.serialization.* import net.corda.core.serialization.*
import java.lang.reflect.Type
import java.time.Period import java.time.Period
@CordaCustomSerializer @CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class TenorSerializer : SerializationCustomSerializer<Tenor, TenorSerializer.Proxy> { class TenorSerializer : SerializationCustomSerializer<Tenor, TenorSerializer.Proxy> {
@CordaCustomSerializerProxy
data class Proxy(val years: Int, val months: Int, val days: Int, val name: String) data class Proxy(val years: Int, val months: Int, val days: Int, val name: String)
override val type: Type get() = Tenor::class.java
override val ptype: Type get() = Proxy::class.java
override fun toProxy(obj: Tenor) = Proxy(obj.period.years, obj.period.months, obj.period.days, obj.toString()) override fun toProxy(obj: Tenor) = Proxy(obj.period.years, obj.period.months, obj.period.days, obj.toString())
override fun fromProxy(proxy: Proxy) = Tenor.of (Period.of(proxy.years, proxy.months, proxy.days)) override fun fromProxy(proxy: Proxy) = Tenor.of (Period.of(proxy.years, proxy.months, proxy.days))
} }

View File

@ -104,6 +104,7 @@ private fun createTestSerializationEnv(label: String) = object : SerializationEn
}, },
AMQP_P2P_CONTEXT, AMQP_P2P_CONTEXT,
KRYO_RPC_SERVER_CONTEXT, KRYO_RPC_SERVER_CONTEXT,
KRYO_RPC_CLIENT_CONTEXT,
AMQP_STORAGE_CONTEXT, AMQP_STORAGE_CONTEXT,
KRYO_CHECKPOINT_CONTEXT) { KRYO_CHECKPOINT_CONTEXT) {
override fun toString() = "testSerializationEnv($label)" override fun toString() = "testSerializationEnv($label)"

View File

@ -22,7 +22,6 @@ class MockCordappProvider(cordappLoader: CordappLoader, attachmentStorage: Attac
schedulableFlows = emptyList(), schedulableFlows = emptyList(),
services = emptyList(), services = emptyList(),
serializationWhitelists = emptyList(), serializationWhitelists = emptyList(),
serializationCustomSerializerProxies = emptyList(),
serializationCustomSerializers = emptyList(), serializationCustomSerializers = emptyList(),
customSchemas = emptySet(), customSchemas = emptySet(),
jarPath = Paths.get(".").toUri().toURL()) jarPath = Paths.get(".").toUri().toURL())