CORDA-553 - Remove CordaCustomSerializer annotation

It isn't actually needed as we can scan the jar for classes implementing
the interface.
This commit is contained in:
Katelyn Baker 2017-12-04 17:56:27 +00:00
parent c4d5d3817c
commit 8878fa99a0
16 changed files with 28 additions and 53 deletions

View File

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

View File

@ -17,7 +17,7 @@ data class CordappImpl(
override val schedulableFlows: List<Class<out FlowLogic<*>>>,
override val services: List<Class<out SerializeAsToken>>,
override val serializationWhitelists: List<SerializationWhitelist>,
override val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>>,
override val serializationCustomSerializers: List<SerializationCustomSerializer<*, *>>,
override val customSchemas: Set<MappedSchema>,
override val jarPath: URL) : Cordapp {
override val name: String = File(jarPath.toURI()).name.removeSuffix(".jar")

View File

@ -1,10 +0,0 @@
package net.corda.core.serialization
/**
* This annotation marks a class as being a serializer provided by a CorDapp to proxy some third party
* class Corda couldn't otherwise serialize. It should be applied to classes that implement the
* [SerializationCustomSerializer] interface
*/
@Target(AnnotationTarget.CLASS)
annotation class CordaCustomSerializer

View File

@ -1,27 +1,18 @@
package net.corda.core.serialization
import java.lang.reflect.Type
/**
* Allows CorDapps to provide custom serializers for third party libraries where those libraries cannot
* be recompiled with the -parmater flag rendering their classes natively serializable by Corda. In this case
* be recompiled with the -parameters flag rendering their classes natively serializable by Corda. In this case
* a proxy serializer can be written that extends this type whose purpose is to move between those an
* unserializable types and an intermediate representation
* unserializable types and an intermediate representation.
*
* NOTE: The proxy object must be specified as a seperate class. However, this can be defined within the
* scope of the serializer. Also, that class must be annotated with the [CordaCustomSerializerProxy]
* annotation
*
* For instances of this class to be discoverable they must be annotated with the [CordaCustomSerializer]
* annotation.
*
* Failing to apply either annotation will result in the class not being loaded by Corda and thus serialization
* failing
* NOTE: The proxy object must should be specified as a seperate class. However, this can be defined within the
* scope of the custom serializer.
*/
interface SerializationCustomSerializer<OBJ, PROXY> {
/**
* Should facilitate the conversion of the third party object into the serializable
* local class specified by [ptype]
* local class specified by [PROXY]
*/
fun toProxy(obj: OBJ) : PROXY

View File

@ -3,7 +3,7 @@ Pluggable Serializers for CorDapps
.. contents::
To be serializable by Corda Java classes must be compiled with the -parameters switch to enable matching of it's properties
To be serializable by Corda Java classes must be compiled with the -parameters switch to enable matching of its 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
they cannot be easily modified for simple serialization, CorDapps can provide custom proxy serializers that Corda
@ -18,11 +18,10 @@ Writing a Custom Serializer
---------------------------
Serializers must
* Inherit from net.corda.core.serialization.SerializationCustomSerializer
* Be annotated with the @CordaCustomSerializer annotation
* Provide a proxy class to transform the object to and from
* Implmenet the ``toProxy`` and ``fromProxy`` methods
* Implement the ``toProxy`` and ``fromProxy`` methods
Serializers inheriting from SerializationCustomSerializer have to implement two methods and two types
Serializers inheriting from SerializationCustomSerializer have to implement two methods and two types.
Example
-------
@ -47,13 +46,12 @@ Consider this example class
}
Without a custom serializer we cannot serialize this class as there is no public constructor that facilitates the
initialisation of all of it's properties.
initialisation of all of its 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
@CordaCustomSerializer
class ExampleSerializer : SerializationCustomSerializer<Example, ExampleSerializer.Proxy> {
data class Proxy(val a: Int, val b: Int)

View File

@ -18,11 +18,11 @@ AMQP Serialization is now enabled for both peer to peer communication and writin
brings a stable format Corda can support internally throughout it's lifetime that meets the needs of Corda and our
users.
* **CorDapp Custom Serializers**
* **Custom Serializers**
To allow interop with third party libraries that cannot be recompiled we add functionality that allows custom serialises
to be written for those classes provided. If needed, a proxy object can be created as an interim step that allows Corda's internal
serialisers to operate on those types.
To allow interop with third party libraries that cannot be recompiled we add functionality that allows custom serializers
to be written for those classes. If needed, a proxy object can be created as an interim step that allows Corda's internal
serializers to operate on those types.
A good example of this is the SIMM valuation demo which has a number of such serializers defined in the plugin/customserializers package

View File

@ -70,7 +70,7 @@ abstract class AbstractAMQPSerializationScheme(val cordappLoader: List<Cordapp>)
cordappLoader.forEach { ca ->
ca.serializationCustomSerializers.forEach {
factory.registerExternal(CorDappCustomSerializer(it.newInstance(), factory))
factory.registerExternal(CorDappCustomSerializer(it, factory))
}
}
}

View File

@ -1,7 +1,6 @@
package net.corda.nodeapi.internal.serialization.amqp
import org.junit.Test
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.SerializationCustomSerializer
import org.assertj.core.api.Assertions
@ -11,7 +10,6 @@ import kotlin.test.assertEquals
class CorDappSerializerTests {
data class NeedsProxy (val a: String)
@CordaCustomSerializer
class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> {
data class Proxy(val proxy_a_: String)

View File

@ -248,8 +248,9 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
} + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app.
}
private fun findSerialzers(scanResult: RestrictedScanResult) : List<Class<out SerializationCustomSerializer<*, *>>> {
return scanResult.getClassesWithAnnotation(SerializationCustomSerializer::class, CordaCustomSerializer::class)
private fun findSerialzers(scanResult: RestrictedScanResult) : List<SerializationCustomSerializer<*, *>> {
// return scanResult.getClassesWithAnnotation(SerializationCustomSerializer::class, CordaCustomSerializer::class)
return scanResult.getClassesImplementing(SerializationCustomSerializer::class)
}
private fun findCustomSchemas(scanResult: RestrictedScanResult): Set<MappedSchema> {
@ -308,6 +309,14 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
.map { it.kotlin.objectOrNewInstance() }
}
fun <T : Any> getClassesImplementing(type: KClass<T>): List<T> {
return scanResult.getNamesOfClassesImplementing(type.java)
.filter { it.startsWith(qualifiedNamePrefix) }
.mapNotNull { loadClass(it, type) }
.filterNot { Modifier.isAbstract(it.modifiers) }
.map { it.kotlin.objectOrNewInstance() }
}
fun <T : Any> getClassesWithAnnotation(type: KClass<T>, annotation: KClass<out Annotation>): List<Class<out T>> {
return scanResult.getNamesOfClassesWithAnnotation(annotation.java)
.filter { it.startsWith(qualifiedNamePrefix) }

View File

@ -2,10 +2,8 @@ package net.corda.vega.plugin.customserializers
import com.opengamma.strata.market.param.CurrencyParameterSensitivities
import com.opengamma.strata.market.param.CurrencyParameterSensitivity
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer
@CordaCustomSerializer
@Suppress("UNUSED")
class CurrencyParameterSensitivitiesSerializer :
SerializationCustomSerializer<CurrencyParameterSensitivities, CurrencyParameterSensitivitiesSerializer.Proxy> {

View File

@ -5,10 +5,8 @@ import com.opengamma.strata.market.param.ParameterMetadata
import com.opengamma.strata.data.MarketDataName
import com.opengamma.strata.collect.array.DoubleArray
import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer
@CordaCustomSerializer
@Suppress("UNUSED")
class CurrencyParameterSensitivitySerializer :
SerializationCustomSerializer<CurrencyParameterSensitivity, CurrencyParameterSensitivitySerializer.Proxy> {

View File

@ -1,10 +1,8 @@
package net.corda.vega.plugin.customserializers
import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer
@CordaCustomSerializer
@Suppress("UNUSED")
class CurrencySerializer : SerializationCustomSerializer<Currency, CurrencySerializer.Proxy> {
data class Proxy(val currency: String)

View File

@ -1,10 +1,8 @@
package net.corda.vega.plugin.customserializers
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer
import com.opengamma.strata.collect.array.DoubleArray
@CordaCustomSerializer
@Suppress("UNUSED")
class DoubleArraySerializer : SerializationCustomSerializer<DoubleArray, DoubleArraySerializer.Proxy> {
data class Proxy(val amount: kotlin.DoubleArray)

View File

@ -4,7 +4,6 @@ import com.opengamma.strata.basics.currency.MultiCurrencyAmount
import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.*
@CordaCustomSerializer
@Suppress("UNUSED")
class MultiCurrencyAmountSerializer :
SerializationCustomSerializer<MultiCurrencyAmount, MultiCurrencyAmountSerializer.Proxy> {

View File

@ -5,7 +5,6 @@ import com.opengamma.strata.market.param.TenorDateParameterMetadata
import net.corda.core.serialization.*
import java.time.LocalDate
@CordaCustomSerializer
@Suppress("UNUSED")
class TenorDateParameterMetadataSerializer :
SerializationCustomSerializer<TenorDateParameterMetadata, TenorDateParameterMetadataSerializer.Proxy> {

View File

@ -4,7 +4,6 @@ import com.opengamma.strata.basics.date.Tenor
import net.corda.core.serialization.*
import java.time.Period
@CordaCustomSerializer
@Suppress("UNUSED")
class TenorSerializer : SerializationCustomSerializer<Tenor, TenorSerializer.Proxy> {
data class Proxy(val years: Int, val months: Int, val days: Int, val name: String)