mirror of
https://github.com/corda/corda.git
synced 2025-02-20 17:33:15 +00:00
Merge pull request #1349 from corda/feature/kat/serialiseWithEnvelopeReturn
Add alt serialise method that returns the schema and the bytes
This commit is contained in:
commit
76ffd485ac
@ -8,6 +8,7 @@ import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
import kotlin.collections.LinkedHashSet
|
||||
|
||||
|
||||
/**
|
||||
* Main entry point for serializing an object to AMQP.
|
||||
*
|
||||
@ -18,37 +19,46 @@ open class SerializationOutput(internal val serializerFactory: SerializerFactory
|
||||
// TODO: we're not supporting object refs yet
|
||||
private val objectHistory: MutableMap<Any, Int> = IdentityHashMap()
|
||||
private val serializerHistory: MutableSet<AMQPSerializer<*>> = LinkedHashSet()
|
||||
private val schemaHistory: MutableSet<TypeNotation> = LinkedHashSet()
|
||||
internal val schemaHistory: MutableSet<TypeNotation> = LinkedHashSet()
|
||||
|
||||
|
||||
/**
|
||||
* Serialize the given object to AMQP, wrapped in our [Envelope] wrapper which carries an AMQP 1.0 schema, and prefixed
|
||||
* with a header to indicate that this is serialized with AMQP and not [Kryo], and what version of the Corda implementation
|
||||
* of AMQP serialization contructed the serialized form.
|
||||
* of AMQP serialization constructed the serialized form.
|
||||
*/
|
||||
@Throws(NotSerializableException::class)
|
||||
fun <T : Any> serialize(obj: T): SerializedBytes<T> {
|
||||
try {
|
||||
val data = Data.Factory.create()
|
||||
data.withDescribed(Envelope.DESCRIPTOR_OBJECT) {
|
||||
withList {
|
||||
// Our object
|
||||
writeObject(obj, this)
|
||||
// The schema
|
||||
writeSchema(Schema(schemaHistory.toList()), this)
|
||||
}
|
||||
}
|
||||
val bytes = ByteArray(data.encodedSize().toInt() + 8)
|
||||
val buf = ByteBuffer.wrap(bytes)
|
||||
buf.put(AmqpHeaderV1_0.bytes)
|
||||
data.encode(buf)
|
||||
return SerializedBytes(bytes)
|
||||
return _serialize(obj)
|
||||
} finally {
|
||||
objectHistory.clear()
|
||||
serializerHistory.clear()
|
||||
schemaHistory.clear()
|
||||
andFinally()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun andFinally() {
|
||||
objectHistory.clear()
|
||||
serializerHistory.clear()
|
||||
schemaHistory.clear()
|
||||
}
|
||||
|
||||
internal fun <T : Any> _serialize(obj: T): SerializedBytes<T> {
|
||||
val data = Data.Factory.create()
|
||||
data.withDescribed(Envelope.DESCRIPTOR_OBJECT) {
|
||||
withList {
|
||||
// Our object
|
||||
writeObject(obj, this)
|
||||
// The schema
|
||||
writeSchema(Schema(schemaHistory.toList()), this)
|
||||
}
|
||||
}
|
||||
val bytes = ByteArray(data.encodedSize().toInt() + 8)
|
||||
val buf = ByteBuffer.wrap(bytes)
|
||||
buf.put(AmqpHeaderV1_0.bytes)
|
||||
data.encode(buf)
|
||||
return SerializedBytes(bytes)
|
||||
}
|
||||
|
||||
internal fun writeObject(obj: Any, data: Data) {
|
||||
writeObject(obj, data, obj.javaClass)
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import org.apache.qpid.proton.codec.Data
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.EmptyWhitelist
|
||||
import java.io.NotSerializableException
|
||||
|
||||
|
||||
fun testDefaultFactory() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
fun testDefaultFactoryWithWhitelist() = SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())
|
||||
@ -17,3 +20,18 @@ class TestSerializationOutput(
|
||||
super.writeSchema(schema, data)
|
||||
}
|
||||
}
|
||||
|
||||
fun testName(): String = Thread.currentThread().stackTrace[2].methodName
|
||||
|
||||
data class BytesAndSchema<T : Any>(val obj: SerializedBytes<T>, val schema: Schema)
|
||||
|
||||
// Extension for the serialize routine that returns the scheme encoded into the
|
||||
// bytes as well as the bytes for simple testing
|
||||
@Throws(NotSerializableException::class)
|
||||
fun <T : Any> SerializationOutput.serializeAndReturnSchema(obj: T): BytesAndSchema<T> {
|
||||
try {
|
||||
return BytesAndSchema(_serialize(obj), Schema(schemaHistory.toList()))
|
||||
} finally {
|
||||
andFinally()
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,9 @@ import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class DeserializeAndReturnEnvelopeTests {
|
||||
|
||||
fun testName(): String = Thread.currentThread().stackTrace[2].methodName
|
||||
|
||||
// the 'this' reference means we can't just move this to the common test utils
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun classTestName(clazz: String) = "${this.javaClass.name}\$${testName()}\$$clazz"
|
||||
inline private fun classTestName(clazz: String) = "${this.javaClass.name}\$${testName()}\$$clazz"
|
||||
|
||||
@Test
|
||||
fun oneType() {
|
||||
|
@ -0,0 +1,34 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class SerializeAndReturnSchemaTest {
|
||||
// the 'this' reference means we can't just move this to the common test utils
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline private fun classTestName(clazz: String) = "${this.javaClass.name}\$${testName()}\$$clazz"
|
||||
|
||||
val factory = testDefaultFactory()
|
||||
|
||||
// just a simple test to verify the internal test extension for serialize does
|
||||
// indeed give us the correct schema back. This is more useful in support of other
|
||||
// tests rather than by itself but for those to be reliable this also needs
|
||||
// testing
|
||||
@Test
|
||||
fun getSchema() {
|
||||
data class C(val a: Int, val b: Int)
|
||||
val a = 1
|
||||
val b = 2
|
||||
|
||||
val sc = SerializationOutput(factory).serializeAndReturnSchema(C(a, b))
|
||||
|
||||
assertEquals(1, sc.schema.types.size)
|
||||
assertEquals(classTestName("C"), sc.schema.types.first().name)
|
||||
assertTrue(sc.schema.types.first() is CompositeType)
|
||||
assertEquals(2, (sc.schema.types.first() as CompositeType).fields.size)
|
||||
assertNotNull((sc.schema.types.first() as CompositeType).fields.find { it.name == "a" })
|
||||
assertNotNull((sc.schema.types.first() as CompositeType).fields.find { it.name == "b" })
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user