mirror of
https://github.com/corda/corda.git
synced 2024-12-19 13:08:04 +00:00
Merge pull request #2028 from corda/cburlinchon-amqp-contract-attachment-serializer
ENT-1031 AMQP serializer for ContractAttachment, evaluate lazy attachment
This commit is contained in:
commit
83857950fe
@ -61,6 +61,7 @@ abstract class AbstractAMQPSerializationScheme : SerializationScheme {
|
||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.InputStreamSerializer)
|
||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.BitSetSerializer(this))
|
||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.EnumSetSerializer(this))
|
||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.ContractAttachmentSerializer(this))
|
||||
}
|
||||
for (whitelistProvider in serializationWhitelists)
|
||||
factory.addToWhitelist(*whitelistProvider.whitelist.toTypedArray())
|
||||
|
@ -0,0 +1,32 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp.custom
|
||||
|
||||
import net.corda.core.contracts.Attachment
|
||||
import net.corda.core.contracts.ContractAttachment
|
||||
import net.corda.core.contracts.ContractClassName
|
||||
import net.corda.core.serialization.MissingAttachmentsException
|
||||
import net.corda.nodeapi.internal.serialization.GeneratedAttachment
|
||||
import net.corda.nodeapi.internal.serialization.amqp.CustomSerializer
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory
|
||||
|
||||
/**
|
||||
* A serializer for [ContractAttachment] that uses a proxy object to write out the full attachment eagerly.
|
||||
* @param factory the serializerFactory
|
||||
*/
|
||||
class ContractAttachmentSerializer(factory: SerializerFactory) : CustomSerializer.Proxy<ContractAttachment,
|
||||
ContractAttachmentSerializer.ContractAttachmentProxy>(ContractAttachment::class.java,
|
||||
ContractAttachmentProxy::class.java, factory) {
|
||||
override fun toProxy(obj: ContractAttachment): ContractAttachmentProxy {
|
||||
val bytes = try {
|
||||
obj.attachment.open().readBytes()
|
||||
} catch (e: Exception) {
|
||||
throw MissingAttachmentsException(listOf(obj.id))
|
||||
}
|
||||
return ContractAttachmentProxy(GeneratedAttachment(bytes), obj.contract)
|
||||
}
|
||||
|
||||
override fun fromProxy(proxy: ContractAttachmentProxy): ContractAttachment {
|
||||
return ContractAttachment(proxy.attachment, proxy.contract)
|
||||
}
|
||||
|
||||
data class ContractAttachmentProxy(val attachment: Attachment, val contract: ContractClassName)
|
||||
}
|
@ -1,10 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.core.CordaRuntimeException
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionState
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.FlowException
|
||||
import net.corda.core.identity.AbstractParty
|
||||
@ -13,19 +9,26 @@ import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.SerializationFactory
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.client.rpc.RPCException
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.internal.AbstractAttachment
|
||||
import net.corda.core.serialization.MissingAttachmentsException
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.EmptyWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.GeneratedAttachment
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.isPrimitive
|
||||
import net.corda.testing.BOB_IDENTITY
|
||||
import net.corda.testing.MEGA_CORP
|
||||
import net.corda.testing.MEGA_CORP_PUBKEY
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.withTestSerialization
|
||||
import org.apache.activemq.artemis.api.core.SimpleString
|
||||
import org.apache.qpid.proton.amqp.*
|
||||
import org.apache.qpid.proton.codec.DecoderImpl
|
||||
import org.apache.qpid.proton.codec.EncoderImpl
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
import org.junit.Assert.assertNotSame
|
||||
import org.junit.Assert.assertSame
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
@ -993,4 +996,36 @@ class SerializationOutputTests {
|
||||
obj[Month.AUGUST] = Month.AUGUST.value
|
||||
serdes(obj)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test contract attachment serialize`() {
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.ContractAttachmentSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ContractAttachmentSerializer(factory2))
|
||||
|
||||
val obj = ContractAttachment(GeneratedAttachment("test".toByteArray()), DummyContract.PROGRAM_ID)
|
||||
val obj2 = serdes(obj, factory, factory2, expectedEqual = false, expectDeserializedEqual = false)
|
||||
assertEquals(obj.id, obj2.attachment.id)
|
||||
assertEquals(obj.contract, obj2.contract)
|
||||
assertArrayEquals(obj.open().readBytes(), obj2.open().readBytes())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test contract attachment throws if missing attachment`() {
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.ContractAttachmentSerializer(factory))
|
||||
|
||||
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ContractAttachmentSerializer(factory2))
|
||||
|
||||
val obj = ContractAttachment(object : AbstractAttachment({ throw Exception() }) {
|
||||
override val id = SecureHash.zeroHash
|
||||
}, DummyContract.PROGRAM_ID)
|
||||
|
||||
assertThatThrownBy {
|
||||
serdes(obj, factory, factory2, expectedEqual = false, expectDeserializedEqual = false)
|
||||
}.isInstanceOf(MissingAttachmentsException::class.java)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user