mirror of
https://github.com/corda/corda.git
synced 2025-01-20 03:36:29 +00:00
Merge pull request #1622 from corda/feature/kat/carpenterRespectWhitelist
CORDA-601 - Start adding whitelist support to the carpenter
This commit is contained in:
commit
7c63597937
@ -34,7 +34,7 @@ class SerializerFactory(val whitelist: ClassWhitelist, cl: ClassLoader) {
|
||||
private val serializersByType = ConcurrentHashMap<Type, AMQPSerializer<Any>>()
|
||||
private val serializersByDescriptor = ConcurrentHashMap<Any, AMQPSerializer<Any>>()
|
||||
private val customSerializers = CopyOnWriteArrayList<CustomSerializer<out Any>>()
|
||||
val classCarpenter = ClassCarpenter(cl)
|
||||
val classCarpenter = ClassCarpenter(cl, whitelist)
|
||||
val classloader: ClassLoader
|
||||
get() = classCarpenter.classloader
|
||||
|
||||
@ -61,24 +61,24 @@ class SerializerFactory(val whitelist: ClassWhitelist, cl: ClassLoader) {
|
||||
val actualType: Type = inferTypeVariables(actualClass, declaredClass, declaredType) ?: declaredType
|
||||
|
||||
val serializer = when {
|
||||
// Declared class may not be set to Collection, but actual class could be a collection.
|
||||
// In this case use of CollectionSerializer is perfectly appropriate.
|
||||
// Declared class may not be set to Collection, but actual class could be a collection.
|
||||
// In this case use of CollectionSerializer is perfectly appropriate.
|
||||
(Collection::class.java.isAssignableFrom(declaredClass) ||
|
||||
(actualClass != null && Collection::class.java.isAssignableFrom(actualClass))) &&
|
||||
!EnumSet::class.java.isAssignableFrom(actualClass ?: declaredClass) -> {
|
||||
val declaredTypeAmended= CollectionSerializer.deriveParameterizedType(declaredType, declaredClass, actualClass)
|
||||
serializersByType.computeIfAbsent(declaredTypeAmended) {
|
||||
CollectionSerializer(declaredTypeAmended, this)
|
||||
}
|
||||
val declaredTypeAmended = CollectionSerializer.deriveParameterizedType(declaredType, declaredClass, actualClass)
|
||||
serializersByType.computeIfAbsent(declaredTypeAmended) {
|
||||
CollectionSerializer(declaredTypeAmended, this)
|
||||
}
|
||||
}
|
||||
// Declared class may not be set to Map, but actual class could be a map.
|
||||
// In this case use of MapSerializer is perfectly appropriate.
|
||||
// Declared class may not be set to Map, but actual class could be a map.
|
||||
// In this case use of MapSerializer is perfectly appropriate.
|
||||
(Map::class.java.isAssignableFrom(declaredClass) ||
|
||||
(actualClass != null && Map::class.java.isAssignableFrom(actualClass))) -> {
|
||||
val declaredTypeAmended= MapSerializer.deriveParameterizedType(declaredType, declaredClass, actualClass)
|
||||
serializersByType.computeIfAbsent(declaredTypeAmended) {
|
||||
makeMapSerializer(declaredTypeAmended)
|
||||
}
|
||||
(actualClass != null && Map::class.java.isAssignableFrom(actualClass))) -> {
|
||||
val declaredTypeAmended = MapSerializer.deriveParameterizedType(declaredType, declaredClass, actualClass)
|
||||
serializersByType.computeIfAbsent(declaredTypeAmended) {
|
||||
makeMapSerializer(declaredTypeAmended)
|
||||
}
|
||||
}
|
||||
Enum::class.java.isAssignableFrom(actualClass ?: declaredClass) -> serializersByType.computeIfAbsent(actualClass ?: declaredClass) {
|
||||
EnumSerializer(actualType, actualClass ?: declaredClass, this)
|
||||
@ -99,7 +99,7 @@ class SerializerFactory(val whitelist: ClassWhitelist, cl: ClassLoader) {
|
||||
private fun inferTypeVariables(actualClass: Class<*>?, declaredClass: Class<*>, declaredType: Type): Type? =
|
||||
when (declaredType) {
|
||||
is ParameterizedType -> inferTypeVariables(actualClass, declaredClass, declaredType)
|
||||
// Nothing to infer, otherwise we'd have ParameterizedType
|
||||
// Nothing to infer, otherwise we'd have ParameterizedType
|
||||
is Class<*> -> actualClass
|
||||
is GenericArrayType -> {
|
||||
val declaredComponent = declaredType.genericComponentType
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.core.serialization.ClassWhitelist
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import org.objectweb.asm.ClassWriter
|
||||
import org.objectweb.asm.MethodVisitor
|
||||
@ -79,7 +80,8 @@ private val jlClass get() = Type.getInternalName(Class::class.java)
|
||||
*
|
||||
* Equals/hashCode methods are not yet supported.
|
||||
*/
|
||||
class ClassCarpenter(cl: ClassLoader = Thread.currentThread().contextClassLoader) {
|
||||
class ClassCarpenter(cl: ClassLoader = Thread.currentThread().contextClassLoader,
|
||||
val whitelist: ClassWhitelist) {
|
||||
// TODO: Generics.
|
||||
// TODO: Sandbox the generated code when a security manager is in use.
|
||||
// TODO: Generate equals/hashCode.
|
||||
|
@ -62,7 +62,7 @@ data class CarpenterMetaSchema(
|
||||
* @property cc a reference to the actual class carpenter we're using to constuct classes
|
||||
* @property objects a list of carpented classes loaded into the carpenters class loader
|
||||
*/
|
||||
abstract class MetaCarpenterBase(val schemas: CarpenterMetaSchema, val cc: ClassCarpenter = ClassCarpenter()) {
|
||||
abstract class MetaCarpenterBase(val schemas: CarpenterMetaSchema, val cc: ClassCarpenter) {
|
||||
val objects = mutableMapOf<String, Class<*>>()
|
||||
|
||||
fun step(newObject: Schema) {
|
||||
@ -91,8 +91,7 @@ abstract class MetaCarpenterBase(val schemas: CarpenterMetaSchema, val cc: Class
|
||||
get() = cc.classloader
|
||||
}
|
||||
|
||||
class MetaCarpenter(schemas: CarpenterMetaSchema,
|
||||
cc: ClassCarpenter = ClassCarpenter()) : MetaCarpenterBase(schemas, cc) {
|
||||
class MetaCarpenter(schemas: CarpenterMetaSchema, cc: ClassCarpenter) : MetaCarpenterBase(schemas, cc) {
|
||||
override fun build() {
|
||||
while (schemas.carpenterSchemas.isNotEmpty()) {
|
||||
val newObject = schemas.carpenterSchemas.removeAt(0)
|
||||
@ -101,8 +100,7 @@ class MetaCarpenter(schemas: CarpenterMetaSchema,
|
||||
}
|
||||
}
|
||||
|
||||
class TestMetaCarpenter(schemas: CarpenterMetaSchema,
|
||||
cc: ClassCarpenter = ClassCarpenter()) : MetaCarpenterBase(schemas, cc) {
|
||||
class TestMetaCarpenter(schemas: CarpenterMetaSchema, cc: ClassCarpenter) : MetaCarpenterBase(schemas, cc) {
|
||||
override fun build() {
|
||||
if (schemas.carpenterSchemas.isEmpty()) return
|
||||
step(schemas.carpenterSchemas.removeAt(0))
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import org.junit.Test
|
||||
import kotlin.test.*
|
||||
import net.corda.nodeapi.internal.serialization.carpenter.*
|
||||
|
||||
class DeserializeNeedingCarpentryOfEnumsTest : AmqpCarpenterBase() {
|
||||
class DeserializeNeedingCarpentryOfEnumsTest : AmqpCarpenterBase(AllWhitelist) {
|
||||
companion object {
|
||||
/**
|
||||
* If you want to see the schema encoded into the envelope after serialisation change this to true
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import org.junit.Test
|
||||
import kotlin.test.*
|
||||
import net.corda.nodeapi.internal.serialization.carpenter.*
|
||||
@ -8,7 +9,7 @@ import net.corda.nodeapi.internal.serialization.carpenter.*
|
||||
// those classes don't exist within the system's Class Loader the deserialiser will be forced to carpent
|
||||
// versions of them up using its own internal class carpenter (each carpenter houses it's own loader). This
|
||||
// replicates the situation where a receiver doesn't have some or all elements of a schema present on it's classpath
|
||||
class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase(AllWhitelist) {
|
||||
companion object {
|
||||
/**
|
||||
* If you want to see the schema encoded into the envelope after serialisation change this to true
|
||||
@ -16,12 +17,12 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
private const val VERBOSE = false
|
||||
}
|
||||
|
||||
private val sf = testDefaultFactory()
|
||||
private val sf = testDefaultFactory()
|
||||
private val sf2 = testDefaultFactory()
|
||||
|
||||
@Test
|
||||
fun singleInt() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"int" to NonNullableField(Integer::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -31,9 +32,9 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
// despite being carpented, and thus not on the class path, we should've cached clazz
|
||||
// inside the serialiser object and thus we should have created the same type
|
||||
assertEquals (db::class.java, clazz)
|
||||
assertNotEquals (db2::class.java, clazz)
|
||||
assertNotEquals (db::class.java, db2::class.java)
|
||||
assertEquals(db::class.java, clazz)
|
||||
assertNotEquals(db2::class.java, clazz)
|
||||
assertNotEquals(db::class.java, db2::class.java)
|
||||
|
||||
assertEquals(1, db::class.java.getMethod("getInt").invoke(db))
|
||||
assertEquals(1, db2::class.java.getMethod("getInt").invoke(db2))
|
||||
@ -41,7 +42,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleIntNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"int" to NullableField(Integer::class.java)
|
||||
)))
|
||||
|
||||
@ -57,7 +58,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleIntNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"int" to NullableField(Integer::class.java)
|
||||
)))
|
||||
|
||||
@ -73,7 +74,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleChar() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"char" to NonNullableField(Character::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -86,7 +87,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleCharNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"char" to NullableField(Character::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -99,7 +100,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleCharNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"char" to NullableField(java.lang.Character::class.java)
|
||||
)))
|
||||
|
||||
@ -112,11 +113,11 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleLong() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"long" to NonNullableField(Long::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
val l : Long = 1
|
||||
val l: Long = 1
|
||||
val sb = TestSerializationOutput(VERBOSE, sf).serialize(clazz.constructors.first().newInstance(l))
|
||||
val db = DeserializationInput(sf2).deserialize(sb)
|
||||
|
||||
@ -126,11 +127,11 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleLongNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"long" to NullableField(Long::class.javaObjectType)
|
||||
)))
|
||||
|
||||
val l : Long = 1
|
||||
val l: Long = 1
|
||||
val sb = TestSerializationOutput(VERBOSE, sf).serialize(clazz.constructors.first().newInstance(l))
|
||||
val db = DeserializationInput(sf2).deserialize(sb)
|
||||
|
||||
@ -140,7 +141,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleLongNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"long" to NullableField(Long::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -153,7 +154,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleBoolean() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"boolean" to NonNullableField(Boolean::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -166,7 +167,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleBooleanNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"boolean" to NullableField(Boolean::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -179,7 +180,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleBooleanNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"boolean" to NullableField(Boolean::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -192,7 +193,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleDouble() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"double" to NonNullableField(Double::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -205,7 +206,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleDoubleNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"double" to NullableField(Double::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -218,7 +219,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleDoubleNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"double" to NullableField(Double::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -231,7 +232,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleShort() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"short" to NonNullableField(Short::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -244,7 +245,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleShortNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"short" to NullableField(Short::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -257,7 +258,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleShortNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"short" to NullableField(Short::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -270,7 +271,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleFloat() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"float" to NonNullableField(Float::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
@ -283,7 +284,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleFloatNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"float" to NullableField(Float::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -296,7 +297,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleFloatNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"float" to NullableField(Float::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -309,11 +310,11 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleByte() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"byte" to NonNullableField(Byte::class.javaPrimitiveType!!)
|
||||
)))
|
||||
|
||||
val b : Byte = 0b0101
|
||||
val b: Byte = 0b0101
|
||||
val sb = TestSerializationOutput(VERBOSE, sf).serialize(clazz.constructors.first().newInstance(b))
|
||||
val db = DeserializationInput(sf2).deserialize(sb)
|
||||
|
||||
@ -324,11 +325,11 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleByteNullable() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"byte" to NullableField(Byte::class.javaObjectType)
|
||||
)))
|
||||
|
||||
val b : Byte = 0b0101
|
||||
val b: Byte = 0b0101
|
||||
val sb = TestSerializationOutput(VERBOSE, sf).serialize(clazz.constructors.first().newInstance(b))
|
||||
val db = DeserializationInput(sf2).deserialize(sb)
|
||||
|
||||
@ -339,7 +340,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun singleByteNullableNull() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"byte" to NullableField(Byte::class.javaObjectType)
|
||||
)))
|
||||
|
||||
@ -352,9 +353,9 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun simpleTypeKnownInterface() {
|
||||
val clazz = ClassCarpenter().build (ClassSchema(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(
|
||||
testName(), mapOf("name" to NonNullableField(String::class.java)),
|
||||
interfaces = listOf (I::class.java)))
|
||||
interfaces = listOf(I::class.java)))
|
||||
val testVal = "Some Person"
|
||||
val classInstance = clazz.constructors[0].newInstance(testVal)
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(classInstance)
|
||||
@ -367,34 +368,34 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun manyTypes() {
|
||||
val manyClass = ClassCarpenter().build (ClassSchema(testName(), mapOf(
|
||||
"intA" to NonNullableField (Int::class.java),
|
||||
"intB" to NullableField (Integer::class.java),
|
||||
"intC" to NullableField (Integer::class.java),
|
||||
"strA" to NonNullableField (String::class.java),
|
||||
"strB" to NullableField (String::class.java),
|
||||
"strC" to NullableField (String::class.java),
|
||||
"charA" to NonNullableField (Char::class.java),
|
||||
"charB" to NullableField (Character::class.javaObjectType),
|
||||
"charC" to NullableField (Character::class.javaObjectType),
|
||||
"shortA" to NonNullableField (Short::class.javaPrimitiveType!!),
|
||||
"shortB" to NullableField (Short::class.javaObjectType),
|
||||
"shortC" to NullableField (Short::class.javaObjectType),
|
||||
"longA" to NonNullableField (Long::class.javaPrimitiveType!!),
|
||||
val manyClass = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"intA" to NonNullableField(Int::class.java),
|
||||
"intB" to NullableField(Integer::class.java),
|
||||
"intC" to NullableField(Integer::class.java),
|
||||
"strA" to NonNullableField(String::class.java),
|
||||
"strB" to NullableField(String::class.java),
|
||||
"strC" to NullableField(String::class.java),
|
||||
"charA" to NonNullableField(Char::class.java),
|
||||
"charB" to NullableField(Character::class.javaObjectType),
|
||||
"charC" to NullableField(Character::class.javaObjectType),
|
||||
"shortA" to NonNullableField(Short::class.javaPrimitiveType!!),
|
||||
"shortB" to NullableField(Short::class.javaObjectType),
|
||||
"shortC" to NullableField(Short::class.javaObjectType),
|
||||
"longA" to NonNullableField(Long::class.javaPrimitiveType!!),
|
||||
"longB" to NullableField(Long::class.javaObjectType),
|
||||
"longC" to NullableField(Long::class.javaObjectType),
|
||||
"booleanA" to NonNullableField (Boolean::class.javaPrimitiveType!!),
|
||||
"booleanB" to NullableField (Boolean::class.javaObjectType),
|
||||
"booleanC" to NullableField (Boolean::class.javaObjectType),
|
||||
"doubleA" to NonNullableField (Double::class.javaPrimitiveType!!),
|
||||
"doubleB" to NullableField (Double::class.javaObjectType),
|
||||
"doubleC" to NullableField (Double::class.javaObjectType),
|
||||
"floatA" to NonNullableField (Float::class.javaPrimitiveType!!),
|
||||
"floatB" to NullableField (Float::class.javaObjectType),
|
||||
"floatC" to NullableField (Float::class.javaObjectType),
|
||||
"byteA" to NonNullableField (Byte::class.javaPrimitiveType!!),
|
||||
"byteB" to NullableField (Byte::class.javaObjectType),
|
||||
"byteC" to NullableField (Byte::class.javaObjectType))))
|
||||
"booleanA" to NonNullableField(Boolean::class.javaPrimitiveType!!),
|
||||
"booleanB" to NullableField(Boolean::class.javaObjectType),
|
||||
"booleanC" to NullableField(Boolean::class.javaObjectType),
|
||||
"doubleA" to NonNullableField(Double::class.javaPrimitiveType!!),
|
||||
"doubleB" to NullableField(Double::class.javaObjectType),
|
||||
"doubleC" to NullableField(Double::class.javaObjectType),
|
||||
"floatA" to NonNullableField(Float::class.javaPrimitiveType!!),
|
||||
"floatB" to NullableField(Float::class.javaObjectType),
|
||||
"floatC" to NullableField(Float::class.javaObjectType),
|
||||
"byteA" to NonNullableField(Byte::class.javaPrimitiveType!!),
|
||||
"byteB" to NullableField(Byte::class.javaObjectType),
|
||||
"byteC" to NullableField(Byte::class.javaObjectType))))
|
||||
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, factory).serialize(
|
||||
manyClass.constructors.first().newInstance(
|
||||
@ -411,33 +412,33 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase() {
|
||||
val deserializedObj = DeserializationInput(sf2).deserialize(serialisedBytes)
|
||||
|
||||
assertNotEquals(manyClass, deserializedObj::class.java)
|
||||
assertEquals(1, deserializedObj::class.java.getMethod("getIntA").invoke(deserializedObj))
|
||||
assertEquals(2, deserializedObj::class.java.getMethod("getIntB").invoke(deserializedObj))
|
||||
assertEquals(1, deserializedObj::class.java.getMethod("getIntA").invoke(deserializedObj))
|
||||
assertEquals(2, deserializedObj::class.java.getMethod("getIntB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getIntC").invoke(deserializedObj))
|
||||
assertEquals("a", deserializedObj::class.java.getMethod("getStrA").invoke(deserializedObj))
|
||||
assertEquals("b", deserializedObj::class.java.getMethod("getStrB").invoke(deserializedObj))
|
||||
assertEquals("a", deserializedObj::class.java.getMethod("getStrA").invoke(deserializedObj))
|
||||
assertEquals("b", deserializedObj::class.java.getMethod("getStrB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getStrC").invoke(deserializedObj))
|
||||
assertEquals('c', deserializedObj::class.java.getMethod("getCharA").invoke(deserializedObj))
|
||||
assertEquals('d', deserializedObj::class.java.getMethod("getCharB").invoke(deserializedObj))
|
||||
assertEquals('c', deserializedObj::class.java.getMethod("getCharA").invoke(deserializedObj))
|
||||
assertEquals('d', deserializedObj::class.java.getMethod("getCharB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getCharC").invoke(deserializedObj))
|
||||
assertEquals(3.toShort(), deserializedObj::class.java.getMethod("getShortA").invoke(deserializedObj))
|
||||
assertEquals(4.toShort(), deserializedObj::class.java.getMethod("getShortB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getShortC").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getShortC").invoke(deserializedObj))
|
||||
assertEquals(100.toLong(), deserializedObj::class.java.getMethod("getLongA").invoke(deserializedObj))
|
||||
assertEquals(200.toLong(), deserializedObj::class.java.getMethod("getLongB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getLongC").invoke(deserializedObj))
|
||||
assertEquals(true, deserializedObj::class.java.getMethod("getBooleanA").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getLongC").invoke(deserializedObj))
|
||||
assertEquals(true, deserializedObj::class.java.getMethod("getBooleanA").invoke(deserializedObj))
|
||||
assertEquals(false, deserializedObj::class.java.getMethod("getBooleanB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getBooleanC").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getBooleanC").invoke(deserializedObj))
|
||||
assertEquals(10.0, deserializedObj::class.java.getMethod("getDoubleA").invoke(deserializedObj))
|
||||
assertEquals(20.0, deserializedObj::class.java.getMethod("getDoubleB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getDoubleC").invoke(deserializedObj))
|
||||
assertEquals(10.0F, deserializedObj::class.java.getMethod("getFloatA").invoke(deserializedObj))
|
||||
assertEquals(20.0F, deserializedObj::class.java.getMethod("getFloatB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getFloatC").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getFloatC").invoke(deserializedObj))
|
||||
assertEquals(0b0101.toByte(), deserializedObj::class.java.getMethod("getByteA").invoke(deserializedObj))
|
||||
assertEquals(0b1010.toByte(), deserializedObj::class.java.getMethod("getByteB").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getByteC").invoke(deserializedObj))
|
||||
assertEquals(null, deserializedObj::class.java.getMethod("getByteC").invoke(deserializedObj))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
|
||||
@CordaSerializable
|
||||
interface I {
|
||||
fun getName() : String
|
||||
fun getName(): String
|
||||
}
|
||||
|
||||
// These tests work by having the class carpenter build the classes we serialise and then deserialise them
|
||||
@ -19,7 +19,7 @@ interface I {
|
||||
// However, those classes don't exist within the system's Class Loader and thus the deserialiser will be forced
|
||||
// to carpent versions of them up using its own internal class carpenter (each carpenter houses it's own loader). This
|
||||
// replicates the situation where a receiver doesn't have some or all elements of a schema present on it's classpath
|
||||
class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
class DeserializeNeedingCarpentryTests : AmqpCarpenterBase(AllWhitelist) {
|
||||
companion object {
|
||||
/**
|
||||
* If you want to see the schema encoded into the envelope after serialisation change this to true
|
||||
@ -27,38 +27,40 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
private const val VERBOSE = false
|
||||
}
|
||||
|
||||
val sf1 = testDefaultFactory()
|
||||
val sf2 = testDefaultFactoryWithWhitelist() // Deserialize with whitelisting on to check that `CordaSerializable` annotation present.
|
||||
private val sf1 = testDefaultFactory()
|
||||
|
||||
// Deserialize with whitelisting on to check that `CordaSerializable` annotation present.
|
||||
private val sf2 = testDefaultFactoryWithWhitelist()
|
||||
|
||||
@Test
|
||||
fun verySimpleType() {
|
||||
val testVal = 10
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(),
|
||||
mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val classInstance = clazz.constructors[0].newInstance(testVal)
|
||||
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf1).serialize(classInstance)
|
||||
|
||||
val deserializedObj1 = DeserializationInput(sf1).deserialize(serialisedBytes)
|
||||
|
||||
assertEquals(clazz, deserializedObj1::class.java)
|
||||
assertEquals (testVal, deserializedObj1::class.java.getMethod("getA").invoke(deserializedObj1))
|
||||
assertEquals(testVal, deserializedObj1::class.java.getMethod("getA").invoke(deserializedObj1))
|
||||
|
||||
val deserializedObj2 = DeserializationInput(sf1).deserialize(serialisedBytes)
|
||||
assertEquals(clazz, deserializedObj2::class.java)
|
||||
assertEquals(deserializedObj1::class.java, deserializedObj2::class.java)
|
||||
assertEquals (testVal, deserializedObj2::class.java.getMethod("getA").invoke(deserializedObj2))
|
||||
assertEquals(testVal, deserializedObj2::class.java.getMethod("getA").invoke(deserializedObj2))
|
||||
|
||||
val deserializedObj3 = DeserializationInput(sf2).deserialize(serialisedBytes)
|
||||
assertNotEquals(clazz, deserializedObj3::class.java)
|
||||
assertNotEquals(deserializedObj1::class.java, deserializedObj3::class.java)
|
||||
assertNotEquals(deserializedObj2::class.java, deserializedObj3::class.java)
|
||||
assertEquals (testVal, deserializedObj3::class.java.getMethod("getA").invoke(deserializedObj3))
|
||||
assertEquals(testVal, deserializedObj3::class.java.getMethod("getA").invoke(deserializedObj3))
|
||||
|
||||
val deserializedObj4 = DeserializationInput(sf2).deserialize(serialisedBytes)
|
||||
assertNotEquals(clazz, deserializedObj4::class.java)
|
||||
assertNotEquals(deserializedObj1::class.java, deserializedObj4::class.java)
|
||||
assertNotEquals(deserializedObj2::class.java, deserializedObj4::class.java)
|
||||
assertEquals(deserializedObj3::class.java, deserializedObj4::class.java)
|
||||
assertEquals (testVal, deserializedObj4::class.java.getMethod("getA").invoke(deserializedObj4))
|
||||
assertEquals(testVal, deserializedObj4::class.java.getMethod("getA").invoke(deserializedObj4))
|
||||
|
||||
}
|
||||
|
||||
@ -67,7 +69,7 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
val testValA = 10
|
||||
val testValB = 20
|
||||
val testValC = 20
|
||||
val clazz = ClassCarpenter().build(ClassSchema("${testName()}_clazz",
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema("${testName()}_clazz",
|
||||
mapOf("a" to NonNullableField(Int::class.java))))
|
||||
|
||||
val concreteA = clazz.constructors[0].newInstance(testValA)
|
||||
@ -77,13 +79,13 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
val deserialisedA = DeserializationInput(sf2).deserialize(
|
||||
TestSerializationOutput(VERBOSE, sf1).serialize(concreteA))
|
||||
|
||||
assertEquals (testValA, deserialisedA::class.java.getMethod("getA").invoke(deserialisedA))
|
||||
assertEquals(testValA, deserialisedA::class.java.getMethod("getA").invoke(deserialisedA))
|
||||
|
||||
val deserialisedB = DeserializationInput(sf2).deserialize(
|
||||
TestSerializationOutput(VERBOSE, sf1).serialize(concreteB))
|
||||
|
||||
assertEquals (testValB, deserialisedA::class.java.getMethod("getA").invoke(deserialisedB))
|
||||
assertEquals (deserialisedA::class.java, deserialisedB::class.java)
|
||||
assertEquals(testValB, deserialisedA::class.java.getMethod("getA").invoke(deserialisedB))
|
||||
assertEquals(deserialisedA::class.java, deserialisedB::class.java)
|
||||
|
||||
// C is deseriliased with a different factory, meaning a different class carpenter, so the type
|
||||
// won't already exist and it will be carpented a second time showing that when A and B are the
|
||||
@ -93,16 +95,16 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
val deserialisedC = DeserializationInput(lfactory).deserialize(
|
||||
TestSerializationOutput(VERBOSE, lfactory).serialize(concreteC))
|
||||
|
||||
assertEquals (testValC, deserialisedC::class.java.getMethod("getA").invoke(deserialisedC))
|
||||
assertNotEquals (deserialisedA::class.java, deserialisedC::class.java)
|
||||
assertNotEquals (deserialisedB::class.java, deserialisedC::class.java)
|
||||
assertEquals(testValC, deserialisedC::class.java.getMethod("getA").invoke(deserialisedC))
|
||||
assertNotEquals(deserialisedA::class.java, deserialisedC::class.java)
|
||||
assertNotEquals(deserialisedB::class.java, deserialisedC::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun simpleTypeKnownInterface() {
|
||||
val clazz = ClassCarpenter().build (ClassSchema(
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(
|
||||
testName(), mapOf("name" to NonNullableField(String::class.java)),
|
||||
interfaces = listOf (I::class.java)))
|
||||
interfaces = listOf(I::class.java)))
|
||||
val testVal = "Some Person"
|
||||
val classInstance = clazz.constructors[0].newInstance(testVal)
|
||||
|
||||
@ -115,12 +117,13 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun arrayOfTypes() {
|
||||
val clazz = ClassCarpenter().build(ClassSchema(testName(), mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val clazz = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(),
|
||||
mapOf("a" to NonNullableField(Int::class.java))))
|
||||
|
||||
@CordaSerializable
|
||||
data class Outer (val a : Array<Any>)
|
||||
data class Outer(val a: Array<Any>)
|
||||
|
||||
val outer = Outer (arrayOf (
|
||||
val outer = Outer(arrayOf(
|
||||
clazz.constructors[0].newInstance(1),
|
||||
clazz.constructors[0].newInstance(2),
|
||||
clazz.constructors[0].newInstance(3)))
|
||||
@ -148,7 +151,7 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun reusedClasses() {
|
||||
val cc = ClassCarpenter()
|
||||
val cc = ClassCarpenter(whitelist = AllWhitelist)
|
||||
|
||||
val innerType = cc.build(ClassSchema("${testName()}.inner", mapOf("a" to NonNullableField(Int::class.java))))
|
||||
val outerType = cc.build(ClassSchema("${testName()}.outer", mapOf("a" to NonNullableField(innerType))))
|
||||
@ -157,21 +160,21 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
|
||||
val serializedI = TestSerializationOutput(VERBOSE, sf1).serialize(inner)
|
||||
val deserialisedI = DeserializationInput(sf2).deserialize(serializedI)
|
||||
val serialisedO = TestSerializationOutput(VERBOSE, sf1).serialize(outer)
|
||||
val serialisedO = TestSerializationOutput(VERBOSE, sf1).serialize(outer)
|
||||
val deserialisedO = DeserializationInput(sf2).deserialize(serialisedO)
|
||||
|
||||
// ensure out carpented version of inner is reused
|
||||
assertEquals (deserialisedI::class.java,
|
||||
assertEquals(deserialisedI::class.java,
|
||||
(deserialisedO::class.java.getMethod("getA").invoke(deserialisedO))::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nestedTypes() {
|
||||
val cc = ClassCarpenter()
|
||||
val nestedClass = cc.build (ClassSchema("nestedType",
|
||||
val cc = ClassCarpenter(whitelist = AllWhitelist)
|
||||
val nestedClass = cc.build(ClassSchema("nestedType",
|
||||
mapOf("name" to NonNullableField(String::class.java))))
|
||||
|
||||
val outerClass = cc.build (ClassSchema("outerType",
|
||||
val outerClass = cc.build(ClassSchema("outerType",
|
||||
mapOf("inner" to NonNullableField(nestedClass))))
|
||||
|
||||
val classInstance = outerClass.constructors.first().newInstance(nestedClass.constructors.first().newInstance("name"))
|
||||
@ -184,33 +187,34 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun repeatedNestedTypes() {
|
||||
val cc = ClassCarpenter()
|
||||
val nestedClass = cc.build (ClassSchema("nestedType",
|
||||
val cc = ClassCarpenter(whitelist = AllWhitelist)
|
||||
val nestedClass = cc.build(ClassSchema("nestedType",
|
||||
mapOf("name" to NonNullableField(String::class.java))))
|
||||
|
||||
@CordaSerializable
|
||||
data class outer(val a: Any, val b: Any)
|
||||
|
||||
val classInstance = outer (
|
||||
val classInstance = outer(
|
||||
nestedClass.constructors.first().newInstance("foo"),
|
||||
nestedClass.constructors.first().newInstance("bar"))
|
||||
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf1).serialize(classInstance)
|
||||
val deserializedObj = DeserializationInput(sf2).deserialize(serialisedBytes)
|
||||
|
||||
assertEquals ("foo", deserializedObj.a::class.java.getMethod("getName").invoke(deserializedObj.a))
|
||||
assertEquals ("bar", deserializedObj.b::class.java.getMethod("getName").invoke(deserializedObj.b))
|
||||
assertEquals("foo", deserializedObj.a::class.java.getMethod("getName").invoke(deserializedObj.a))
|
||||
assertEquals("bar", deserializedObj.b::class.java.getMethod("getName").invoke(deserializedObj.b))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listOfType() {
|
||||
val unknownClass = ClassCarpenter().build (ClassSchema(testName(), mapOf(
|
||||
val unknownClass = ClassCarpenter(whitelist = AllWhitelist).build(ClassSchema(testName(), mapOf(
|
||||
"v1" to NonNullableField(Int::class.java),
|
||||
"v2" to NonNullableField(Int::class.java))))
|
||||
|
||||
@CordaSerializable
|
||||
data class outer (val l : List<Any>)
|
||||
val toSerialise = outer (listOf (
|
||||
data class outer(val l: List<Any>)
|
||||
|
||||
val toSerialise = outer(listOf(
|
||||
unknownClass.constructors.first().newInstance(1, 2),
|
||||
unknownClass.constructors.first().newInstance(3, 4),
|
||||
unknownClass.constructors.first().newInstance(5, 6),
|
||||
@ -227,16 +231,16 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase() {
|
||||
|
||||
@Test
|
||||
fun unknownInterface() {
|
||||
val cc = ClassCarpenter()
|
||||
val cc = ClassCarpenter(whitelist = AllWhitelist)
|
||||
|
||||
val interfaceClass = cc.build (InterfaceSchema(
|
||||
val interfaceClass = cc.build(InterfaceSchema(
|
||||
"gen.Interface",
|
||||
mapOf("age" to NonNullableField (Int::class.java))))
|
||||
mapOf("age" to NonNullableField(Int::class.java))))
|
||||
|
||||
val concreteClass = cc.build (ClassSchema (testName(), mapOf(
|
||||
"age" to NonNullableField (Int::class.java),
|
||||
val concreteClass = cc.build(ClassSchema(testName(), mapOf(
|
||||
"age" to NonNullableField(Int::class.java),
|
||||
"name" to NonNullableField(String::class.java)),
|
||||
interfaces = listOf (I::class.java, interfaceClass)))
|
||||
interfaces = listOf(I::class.java, interfaceClass)))
|
||||
|
||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf1).serialize(
|
||||
concreteClass.constructors.first().newInstance(12, "timmy"))
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import org.junit.Test
|
||||
import java.beans.Introspector
|
||||
import java.lang.reflect.Field
|
||||
@ -15,7 +16,7 @@ class ClassCarpenterTest {
|
||||
val b: Int
|
||||
}
|
||||
|
||||
private val cc = ClassCarpenter()
|
||||
private val cc = ClassCarpenter(whitelist = AllWhitelist)
|
||||
|
||||
// We have to ignore synthetic fields even though ClassCarpenter doesn't create any because the JaCoCo
|
||||
// coverage framework auto-magically injects one method and one field into every class loaded into the JVM.
|
||||
@ -266,7 +267,7 @@ class ClassCarpenterTest {
|
||||
mapOf("a" to NonNullableField(Int::class.java)))
|
||||
|
||||
val clazz = cc.build(schema)
|
||||
val a : Int? = null
|
||||
val a: Int? = null
|
||||
clazz.constructors[0].newInstance(a)
|
||||
}
|
||||
|
||||
@ -288,10 +289,10 @@ class ClassCarpenterTest {
|
||||
mapOf("a" to NullableField(Integer::class.java)))
|
||||
|
||||
val clazz = cc.build(schema)
|
||||
val a1 : Int? = null
|
||||
val a1: Int? = null
|
||||
clazz.constructors[0].newInstance(a1)
|
||||
|
||||
val a2 : Int? = 10
|
||||
val a2: Int? = 10
|
||||
clazz.constructors[0].newInstance(a2)
|
||||
}
|
||||
|
||||
@ -304,7 +305,7 @@ class ClassCarpenterTest {
|
||||
|
||||
val clazz = cc.build(schema)
|
||||
|
||||
val a : Int? = 10
|
||||
val a: Int? = 10
|
||||
clazz.constructors[0].newInstance(a)
|
||||
}
|
||||
|
||||
@ -317,7 +318,7 @@ class ClassCarpenterTest {
|
||||
|
||||
val clazz = cc.build(schema)
|
||||
|
||||
val a : Int? = null
|
||||
val a: Int? = null
|
||||
clazz.constructors[0].newInstance(a)
|
||||
}
|
||||
|
||||
@ -350,7 +351,7 @@ class ClassCarpenterTest {
|
||||
|
||||
val clazz = cc.build(schema)
|
||||
|
||||
val a : IntArray? = null
|
||||
val a: IntArray? = null
|
||||
clazz.constructors[0].newInstance(a)
|
||||
}
|
||||
|
||||
@ -472,14 +473,14 @@ class ClassCarpenterTest {
|
||||
|
||||
val clazz = cc.build(schema)
|
||||
|
||||
assertEquals (2, clazz.declaredFields.size)
|
||||
assertEquals (1, clazz.getDeclaredField("a").annotations.size)
|
||||
assertEquals(2, clazz.declaredFields.size)
|
||||
assertEquals(1, clazz.getDeclaredField("a").annotations.size)
|
||||
assertEquals(Nullable::class.java, clazz.getDeclaredField("a").annotations[0].annotationClass.java)
|
||||
assertEquals (1, clazz.getDeclaredField("b").annotations.size)
|
||||
assertEquals(1, clazz.getDeclaredField("b").annotations.size)
|
||||
assertEquals(Nonnull::class.java, clazz.getDeclaredField("b").annotations[0].annotationClass.java)
|
||||
assertEquals (1, clazz.getMethod("getA").annotations.size)
|
||||
assertEquals(1, clazz.getMethod("getA").annotations.size)
|
||||
assertEquals(Nullable::class.java, clazz.getMethod("getA").annotations[0].annotationClass.java)
|
||||
assertEquals (1, clazz.getMethod("getB").annotations.size)
|
||||
assertEquals(1, clazz.getMethod("getB").annotations.size)
|
||||
assertEquals(Nonnull::class.java, clazz.getMethod("getB").annotations[0].annotationClass.java)
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.core.serialization.ClassWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.amqp.*
|
||||
import net.corda.nodeapi.internal.serialization.amqp.Field
|
||||
import net.corda.nodeapi.internal.serialization.amqp.Schema
|
||||
@ -34,9 +35,9 @@ fun Schema.mangleNames(names: List<String>): Schema {
|
||||
return Schema(types = newTypes)
|
||||
}
|
||||
|
||||
open class AmqpCarpenterBase {
|
||||
var cc = ClassCarpenter()
|
||||
var factory = SerializerFactory(AllWhitelist, cc.classloader)
|
||||
open class AmqpCarpenterBase(whitelist: ClassWhitelist) {
|
||||
var cc = ClassCarpenter(whitelist = whitelist)
|
||||
var factory = SerializerFactory(AllWhitelist, cc.classloader)
|
||||
|
||||
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
||||
fun testName(): String = Thread.currentThread().stackTrace[2].methodName
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
|
||||
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
|
||||
import org.junit.Test
|
||||
@ -13,7 +14,7 @@ interface I_ {
|
||||
val a: Int
|
||||
}
|
||||
|
||||
class CompositeMembers : AmqpCarpenterBase() {
|
||||
class CompositeMembers : AmqpCarpenterBase(AllWhitelist) {
|
||||
@Test
|
||||
fun bothKnown() {
|
||||
val testA = 10
|
||||
@ -42,7 +43,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
var amqpSchemaB: CompositeType? = null
|
||||
|
||||
for (type in obj.envelope.schema.types) {
|
||||
when (type.name.split ("$").last()) {
|
||||
when (type.name.split("$").last()) {
|
||||
"A" -> amqpSchemaA = type as CompositeType
|
||||
"B" -> amqpSchemaB = type as CompositeType
|
||||
}
|
||||
@ -88,7 +89,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
val b = B(A(testA), testB)
|
||||
|
||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||
val amqpSchema = obj.envelope.schema.mangleNames(listOf (classTestName ("A")))
|
||||
val amqpSchema = obj.envelope.schema.mangleNames(listOf(classTestName("A")))
|
||||
|
||||
assert(obj.obj is B)
|
||||
|
||||
@ -116,7 +117,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
|
||||
assertEquals(1, carpenterSchema.size)
|
||||
|
||||
val metaCarpenter = MetaCarpenter(carpenterSchema)
|
||||
val metaCarpenter = MetaCarpenter(carpenterSchema, ClassCarpenter(whitelist = AllWhitelist))
|
||||
|
||||
metaCarpenter.build()
|
||||
|
||||
@ -151,7 +152,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
assertEquals(1, carpenterSchema.dependsOn.size)
|
||||
assert(mangleName(classTestName("A")) in carpenterSchema.dependsOn)
|
||||
|
||||
val metaCarpenter = TestMetaCarpenter(carpenterSchema)
|
||||
val metaCarpenter = TestMetaCarpenter(carpenterSchema, ClassCarpenter(whitelist = AllWhitelist))
|
||||
|
||||
assertEquals(0, metaCarpenter.objects.size)
|
||||
|
||||
@ -251,7 +252,8 @@ class CompositeMembers : AmqpCarpenterBase() {
|
||||
assert(obj.obj is C)
|
||||
|
||||
val carpenterSchema = obj.envelope.schema.mangleNames(listOf(classTestName("A"), classTestName("B")))
|
||||
TestMetaCarpenter(carpenterSchema.carpenterSchema(ClassLoader.getSystemClassLoader()))
|
||||
TestMetaCarpenter(carpenterSchema.carpenterSchema(
|
||||
ClassLoader.getSystemClassLoader()), ClassCarpenter(whitelist = AllWhitelist))
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class EnumClassTests : AmqpCarpenterBase() {
|
||||
class EnumClassTests : AmqpCarpenterBase(AllWhitelist) {
|
||||
|
||||
@Test
|
||||
fun oneValue() {
|
||||
@ -84,7 +85,7 @@ class EnumClassTests : AmqpCarpenterBase() {
|
||||
// exception, hence the lack of asserts
|
||||
@Test
|
||||
fun assignAndTest() {
|
||||
val cc2 = ClassCarpenter()
|
||||
val cc2 = ClassCarpenter(whitelist = AllWhitelist)
|
||||
|
||||
val schema1 = EnumSchema("gen.enum",
|
||||
listOf("AAA", "BBB", "CCC", "DDD", "EEE", "FFF").associateBy({ it }, { EnumField() }))
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
|
||||
import org.junit.Test
|
||||
import kotlin.test.*
|
||||
@ -32,7 +33,7 @@ interface IIII {
|
||||
val i: I
|
||||
}
|
||||
|
||||
class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase(AllWhitelist) {
|
||||
@Test
|
||||
fun interfaceParent1() {
|
||||
class A(override val j: Int) : J
|
||||
@ -61,7 +62,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals(1, aSchema.interfaces.size)
|
||||
assertEquals(J::class.java, aSchema.interfaces[0])
|
||||
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val objJ = aBuilder.constructors[0].newInstance(testJ)
|
||||
val j = objJ as J
|
||||
|
||||
@ -106,7 +107,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals(1, aSchema.interfaces.size)
|
||||
assertEquals(J::class.java, aSchema.interfaces[0])
|
||||
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val objJ = aBuilder.constructors[0].newInstance(testJ, testJJ)
|
||||
val j = objJ as J
|
||||
|
||||
@ -154,7 +155,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertTrue(I::class.java in aSchema.interfaces)
|
||||
assertTrue(II::class.java in aSchema.interfaces)
|
||||
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val objA = aBuilder.constructors[0].newInstance(testI, testII)
|
||||
val i = objA as I
|
||||
val ii = objA as II
|
||||
@ -200,7 +201,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertTrue(I::class.java in aSchema.interfaces)
|
||||
assertTrue(III::class.java in aSchema.interfaces)
|
||||
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val objA = aBuilder.constructors[0].newInstance(testI, testIII)
|
||||
val i = objA as I
|
||||
val iii = objA as III
|
||||
@ -247,8 +248,8 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertNotEquals(null, aCarpenterSchema)
|
||||
assertNotEquals(null, bCarpenterSchema)
|
||||
|
||||
val cc = ClassCarpenter()
|
||||
val cc2 = ClassCarpenter()
|
||||
val cc = ClassCarpenter(whitelist = AllWhitelist)
|
||||
val cc2 = ClassCarpenter(whitelist = AllWhitelist)
|
||||
val bBuilder = cc.build(bCarpenterSchema!!)
|
||||
bBuilder.constructors[0].newInstance(a, testIIII)
|
||||
|
||||
@ -332,7 +333,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertEquals(1, carpenterSchema.dependsOn[iName]!!.size)
|
||||
assertEquals(aName, carpenterSchema.dependsOn[iName]!![0])
|
||||
|
||||
val mc = MetaCarpenter(carpenterSchema)
|
||||
val mc = MetaCarpenter(carpenterSchema, ClassCarpenter(whitelist = AllWhitelist))
|
||||
mc.build()
|
||||
|
||||
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
||||
@ -385,7 +386,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iName })
|
||||
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiName })
|
||||
|
||||
val mc = MetaCarpenter(carpenterSchema)
|
||||
val mc = MetaCarpenter(carpenterSchema, ClassCarpenter(whitelist = AllWhitelist))
|
||||
mc.build()
|
||||
|
||||
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
||||
@ -445,7 +446,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiiName })
|
||||
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iName })
|
||||
|
||||
val mc = MetaCarpenter(carpenterSchema)
|
||||
val mc = MetaCarpenter(carpenterSchema, ClassCarpenter(whitelist = AllWhitelist))
|
||||
mc.build()
|
||||
|
||||
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
||||
|
@ -1,13 +1,14 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
|
||||
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase(AllWhitelist) {
|
||||
|
||||
@Test
|
||||
fun twoInts() {
|
||||
@ -46,7 +47,7 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
|
||||
assertNotEquals(null, aSchema)
|
||||
|
||||
val pinochio = ClassCarpenter().build(aSchema!!)
|
||||
val pinochio = ClassCarpenter(whitelist = AllWhitelist).build(aSchema!!)
|
||||
val p = pinochio.constructors[0].newInstance(testA, testB)
|
||||
|
||||
assertEquals(pinochio.getMethod("getA").invoke(p), amqpObj.a)
|
||||
@ -90,7 +91,7 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
|
||||
assertNotEquals(null, aSchema)
|
||||
|
||||
val pinochio = ClassCarpenter().build(aSchema!!)
|
||||
val pinochio = ClassCarpenter(whitelist = AllWhitelist).build(aSchema!!)
|
||||
val p = pinochio.constructors[0].newInstance(testA, testB)
|
||||
|
||||
assertEquals(pinochio.getMethod("getA").invoke(p), amqpObj.a)
|
||||
|
@ -1,12 +1,13 @@
|
||||
package net.corda.nodeapi.internal.serialization.carpenter
|
||||
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
|
||||
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase(AllWhitelist) {
|
||||
@Test
|
||||
fun singleInteger() {
|
||||
@CordaSerializable
|
||||
@ -36,7 +37,7 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val p = aBuilder.constructors[0].newInstance(test)
|
||||
|
||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||
@ -67,7 +68,7 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val p = aBuilder.constructors[0].newInstance(test)
|
||||
|
||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||
@ -102,7 +103,7 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val p = aBuilder.constructors[0].newInstance(test)
|
||||
|
||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||
@ -137,7 +138,7 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val p = aBuilder.constructors[0].newInstance(test)
|
||||
|
||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||
@ -172,7 +173,7 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val p = aBuilder.constructors[0].newInstance(test)
|
||||
|
||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||
@ -183,7 +184,7 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
@CordaSerializable
|
||||
data class A(val a: Float)
|
||||
|
||||
val test: Float = 10.0F
|
||||
val test = 10.0F
|
||||
val a = A(test)
|
||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||
|
||||
@ -207,7 +208,7 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||
force = true)
|
||||
|
||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||
val aBuilder = ClassCarpenter().build(aSchema)
|
||||
val aBuilder = ClassCarpenter(whitelist = AllWhitelist).build(aSchema)
|
||||
val p = aBuilder.constructors[0].newInstance(test)
|
||||
|
||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||
|
Loading…
Reference in New Issue
Block a user