mirror of
https://github.com/corda/corda.git
synced 2025-06-23 01:19:00 +00:00
CORDA-1391: Separate out Checkpoint serialization (#3922)
* Separate out Checkpoint serialization * Update kdocs * Rename checkpoint serialization extension methods * Fix bungled rename * Limit API changes * Simplify CheckpointSerializationFactory * Add CheckpointSerializationScheme to API checker * CheckpointSerializationScheme should not be implemented * Move checkpoint serialisation to internal package * Remove CheckpointSerializationScheme from api-current * Quarantine internal classes * Remove checkpoint context from public API * Remove checkpoint context from public API * Fix test failures * Completely decouple SerializationTestHelpers and CheckpointSerializationTestHelpers * Remove CHECKPOINT use case * Remove stray reference to checkpoint use case * Fix broken test
This commit is contained in:
@ -4,7 +4,6 @@ import com.google.common.collect.Maps;
|
||||
import net.corda.core.serialization.SerializationContext;
|
||||
import net.corda.core.serialization.SerializationFactory;
|
||||
import net.corda.core.serialization.SerializedBytes;
|
||||
import net.corda.serialization.internal.amqp.AMQPNotSerializableException;
|
||||
import net.corda.serialization.internal.amqp.SchemaKt;
|
||||
import net.corda.testing.core.SerializationEnvironmentRule;
|
||||
import org.junit.Before;
|
||||
@ -20,8 +19,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.ThrowableAssert.catchThrowable;
|
||||
|
||||
public final class ForbiddenLambdaSerializationTests {
|
||||
|
||||
private EnumSet<SerializationContext.UseCase> contexts = EnumSet.complementOf(
|
||||
EnumSet.of(SerializationContext.UseCase.Checkpoint, SerializationContext.UseCase.Testing));
|
||||
EnumSet.of(SerializationContext.UseCase.Testing));
|
||||
|
||||
@Rule
|
||||
public final SerializationEnvironmentRule testSerialization = new SerializationEnvironmentRule();
|
||||
private SerializationFactory factory;
|
||||
|
@ -1,11 +1,11 @@
|
||||
package net.corda.serialization.internal;
|
||||
|
||||
import net.corda.core.serialization.SerializationContext;
|
||||
import net.corda.core.serialization.SerializationFactory;
|
||||
import net.corda.core.serialization.SerializedBytes;
|
||||
import net.corda.core.serialization.*;
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationContext;
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationFactory;
|
||||
import net.corda.node.serialization.kryo.CordaClosureSerializer;
|
||||
import net.corda.node.serialization.kryo.KryoSerializationSchemeKt;
|
||||
import net.corda.testing.core.SerializationEnvironmentRule;
|
||||
import net.corda.testing.core.internal.CheckpointSerializationEnvironmentRule;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@ -18,21 +18,22 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.ThrowableAssert.catchThrowable;
|
||||
|
||||
public final class LambdaCheckpointSerializationTest {
|
||||
|
||||
@Rule
|
||||
public final SerializationEnvironmentRule testSerialization = new SerializationEnvironmentRule();
|
||||
private SerializationFactory factory;
|
||||
private SerializationContext context;
|
||||
public final CheckpointSerializationEnvironmentRule testCheckpointSerialization =
|
||||
new CheckpointSerializationEnvironmentRule();
|
||||
|
||||
private CheckpointSerializationFactory factory;
|
||||
private CheckpointSerializationContext context;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
factory = testSerialization.getSerializationFactory();
|
||||
context = new SerializationContextImpl(
|
||||
KryoSerializationSchemeKt.getKryoMagic(),
|
||||
factory = testCheckpointSerialization.getCheckpointSerializationFactory();
|
||||
context = new CheckpointSerializationContextImpl(
|
||||
getClass().getClassLoader(),
|
||||
AllWhitelist.INSTANCE,
|
||||
Collections.emptyMap(),
|
||||
true,
|
||||
SerializationContext.UseCase.Checkpoint,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
@ -3,8 +3,13 @@ package net.corda.serialization.internal
|
||||
import net.corda.core.contracts.ContractAttachment
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationContext
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationFactory
|
||||
import net.corda.core.serialization.internal.checkpointDeserialize
|
||||
import net.corda.core.serialization.internal.checkpointSerialize
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import net.corda.testing.core.internal.CheckpointSerializationEnvironmentRule
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
import net.corda.testing.node.MockServices
|
||||
import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY
|
||||
@ -17,28 +22,29 @@ import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ContractAttachmentSerializerTest {
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val testSerialization = SerializationEnvironmentRule()
|
||||
val testCheckpointSerialization = CheckpointSerializationEnvironmentRule()
|
||||
|
||||
private lateinit var factory: SerializationFactory
|
||||
private lateinit var context: SerializationContext
|
||||
private lateinit var contextWithToken: SerializationContext
|
||||
private lateinit var factory: CheckpointSerializationFactory
|
||||
private lateinit var context: CheckpointSerializationContext
|
||||
private lateinit var contextWithToken: CheckpointSerializationContext
|
||||
private val mockServices = MockServices(emptyList(), CordaX500Name("MegaCorp", "London", "GB"), rigorousMock())
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
factory = testSerialization.serializationFactory
|
||||
context = testSerialization.checkpointContext
|
||||
contextWithToken = context.withTokenContext(SerializeAsTokenContextImpl(Any(), factory, context, mockServices))
|
||||
factory = testCheckpointSerialization.checkpointSerializationFactory
|
||||
context = testCheckpointSerialization.checkpointSerializationContext
|
||||
contextWithToken = context.withTokenContext(CheckpointSerializeAsTokenContextImpl(Any(), factory, context, mockServices))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `write contract attachment and read it back`() {
|
||||
val contractAttachment = ContractAttachment(GeneratedAttachment(EMPTY_BYTE_ARRAY), DummyContract.PROGRAM_ID)
|
||||
// no token context so will serialize the whole attachment
|
||||
val serialized = contractAttachment.serialize(factory, context)
|
||||
val deserialized = serialized.deserialize(factory, context)
|
||||
val serialized = contractAttachment.checkpointSerialize(factory, context)
|
||||
val deserialized = serialized.checkpointDeserialize(factory, context)
|
||||
|
||||
assertEquals(contractAttachment.id, deserialized.attachment.id)
|
||||
assertEquals(contractAttachment.contract, deserialized.contract)
|
||||
@ -53,8 +59,8 @@ class ContractAttachmentSerializerTest {
|
||||
mockServices.attachments.importAttachment(attachment.open(), "test", null)
|
||||
|
||||
val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID)
|
||||
val serialized = contractAttachment.serialize(factory, contextWithToken)
|
||||
val deserialized = serialized.deserialize(factory, contextWithToken)
|
||||
val serialized = contractAttachment.checkpointSerialize(factory, contextWithToken)
|
||||
val deserialized = serialized.checkpointDeserialize(factory, contextWithToken)
|
||||
|
||||
assertEquals(contractAttachment.id, deserialized.attachment.id)
|
||||
assertEquals(contractAttachment.contract, deserialized.contract)
|
||||
@ -70,7 +76,7 @@ class ContractAttachmentSerializerTest {
|
||||
mockServices.attachments.importAttachment(attachment.open(), "test", null)
|
||||
|
||||
val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID)
|
||||
val serialized = contractAttachment.serialize(factory, contextWithToken)
|
||||
val serialized = contractAttachment.checkpointSerialize(factory, contextWithToken)
|
||||
|
||||
assertThat(serialized.size).isLessThan(largeAttachmentSize)
|
||||
}
|
||||
@ -82,8 +88,8 @@ class ContractAttachmentSerializerTest {
|
||||
// don't importAttachment in mockService
|
||||
|
||||
val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID)
|
||||
val serialized = contractAttachment.serialize(factory, contextWithToken)
|
||||
val deserialized = serialized.deserialize(factory, contextWithToken)
|
||||
val serialized = contractAttachment.checkpointSerialize(factory, contextWithToken)
|
||||
val deserialized = serialized.checkpointDeserialize(factory, contextWithToken)
|
||||
|
||||
assertThatThrownBy { deserialized.attachment.open() }.isInstanceOf(MissingAttachmentsException::class.java)
|
||||
}
|
||||
@ -94,8 +100,8 @@ class ContractAttachmentSerializerTest {
|
||||
// don't importAttachment in mockService
|
||||
|
||||
val contractAttachment = ContractAttachment(attachment, DummyContract.PROGRAM_ID)
|
||||
val serialized = contractAttachment.serialize(factory, contextWithToken)
|
||||
serialized.deserialize(factory, contextWithToken)
|
||||
val serialized = contractAttachment.checkpointSerialize(factory, contextWithToken)
|
||||
serialized.checkpointDeserialize(factory, contextWithToken)
|
||||
|
||||
// MissingAttachmentsException thrown if we try to open attachment
|
||||
}
|
||||
|
@ -11,12 +11,11 @@ import com.nhaarman.mockito_kotlin.verify
|
||||
import com.nhaarman.mockito_kotlin.whenever
|
||||
import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER
|
||||
import net.corda.core.node.services.AttachmentStorage
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationContext
|
||||
import net.corda.core.serialization.ClassWhitelist
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.node.serialization.kryo.CordaClassResolver
|
||||
import net.corda.node.serialization.kryo.CordaKryo
|
||||
import net.corda.node.serialization.kryo.kryoMagic
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
import net.corda.testing.services.MockAttachmentStorage
|
||||
import org.junit.Rule
|
||||
@ -115,8 +114,8 @@ class CordaClassResolverTests {
|
||||
val emptyMapClass = mapOf<Any, Any>().javaClass
|
||||
}
|
||||
|
||||
private val emptyWhitelistContext: SerializationContext = SerializationContextImpl(kryoMagic, this.javaClass.classLoader, EmptyWhitelist, emptyMap(), true, SerializationContext.UseCase.P2P, null)
|
||||
private val allButBlacklistedContext: SerializationContext = SerializationContextImpl(kryoMagic, this.javaClass.classLoader, AllButBlacklisted, emptyMap(), true, SerializationContext.UseCase.P2P, null)
|
||||
private val emptyWhitelistContext: CheckpointSerializationContext = CheckpointSerializationContextImpl(this.javaClass.classLoader, EmptyWhitelist, emptyMap(), true, null)
|
||||
private val allButBlacklistedContext: CheckpointSerializationContext = CheckpointSerializationContextImpl(this.javaClass.classLoader, AllButBlacklisted, emptyMap(), true, null)
|
||||
@Test
|
||||
fun `Annotation on enum works for specialised entries`() {
|
||||
CordaClassResolver(emptyWhitelistContext).getRegistration(Foo.Bar::class.java)
|
||||
|
@ -3,6 +3,8 @@ package net.corda.serialization.internal
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.serialization.SerializationContext.UseCase.*
|
||||
import net.corda.core.serialization.SerializationDefaults
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationDefaults
|
||||
import net.corda.core.serialization.internal.checkpointSerialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
@ -33,13 +35,13 @@ class PrivateKeySerializationTest(private val privateKey: PrivateKey, private va
|
||||
@Test
|
||||
fun `passed with expected UseCases`() {
|
||||
assertTrue { privateKey.serialize(context = SerializationDefaults.STORAGE_CONTEXT).bytes.isNotEmpty() }
|
||||
assertTrue { privateKey.serialize(context = SerializationDefaults.CHECKPOINT_CONTEXT).bytes.isNotEmpty() }
|
||||
assertTrue { privateKey.checkpointSerialize(context = CheckpointSerializationDefaults.CHECKPOINT_CONTEXT).bytes.isNotEmpty() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `failed with wrong UseCase`() {
|
||||
assertThatThrownBy { privateKey.serialize(context = SerializationDefaults.P2P_CONTEXT) }
|
||||
.isInstanceOf(IllegalStateException::class.java)
|
||||
.hasMessageContaining("UseCase '$P2P' is not within")
|
||||
.hasMessageContaining("UseCase '$P2P' is not 'Storage")
|
||||
}
|
||||
}
|
@ -4,6 +4,10 @@ import com.esotericsoftware.kryo.Kryo
|
||||
import com.esotericsoftware.kryo.KryoException
|
||||
import com.esotericsoftware.kryo.io.Output
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationContext
|
||||
import net.corda.core.serialization.internal.CheckpointSerializationFactory
|
||||
import net.corda.core.serialization.internal.checkpointDeserialize
|
||||
import net.corda.core.serialization.internal.checkpointSerialize
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.node.serialization.kryo.CordaClassResolver
|
||||
import net.corda.node.serialization.kryo.CordaKryo
|
||||
@ -11,6 +15,7 @@ import net.corda.node.serialization.kryo.DefaultKryoCustomizer
|
||||
import net.corda.node.serialization.kryo.kryoMagic
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import net.corda.testing.core.internal.CheckpointSerializationEnvironmentRule
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
@ -18,16 +23,18 @@ import org.junit.Test
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
class SerializationTokenTest {
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val testSerialization = SerializationEnvironmentRule()
|
||||
private lateinit var factory: SerializationFactory
|
||||
private lateinit var context: SerializationContext
|
||||
val testCheckpointSerialization = CheckpointSerializationEnvironmentRule()
|
||||
|
||||
private lateinit var factory: CheckpointSerializationFactory
|
||||
private lateinit var context: CheckpointSerializationContext
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
factory = testSerialization.serializationFactory
|
||||
context = testSerialization.checkpointContext.withWhitelisted(SingletonSerializationToken::class.java)
|
||||
factory = testCheckpointSerialization.checkpointSerializationFactory
|
||||
context = testCheckpointSerialization.checkpointSerializationContext.withWhitelisted(SingletonSerializationToken::class.java)
|
||||
}
|
||||
|
||||
// Large tokenizable object so we can tell from the smaller number of serialized bytes it was actually tokenized
|
||||
@ -42,16 +49,16 @@ class SerializationTokenTest {
|
||||
override fun equals(other: Any?) = other is LargeTokenizable && other.bytes.size == this.bytes.size
|
||||
}
|
||||
|
||||
private fun serializeAsTokenContext(toBeTokenized: Any) = SerializeAsTokenContextImpl(toBeTokenized, factory, context, rigorousMock())
|
||||
private fun serializeAsTokenContext(toBeTokenized: Any) = CheckpointSerializeAsTokenContextImpl(toBeTokenized, factory, context, rigorousMock())
|
||||
@Test
|
||||
fun `write token and read tokenizable`() {
|
||||
val tokenizableBefore = LargeTokenizable()
|
||||
val context = serializeAsTokenContext(tokenizableBefore)
|
||||
val testContext = this.context.withTokenContext(context)
|
||||
|
||||
val serializedBytes = tokenizableBefore.serialize(factory, testContext)
|
||||
val serializedBytes = tokenizableBefore.checkpointSerialize(factory, testContext)
|
||||
assertThat(serializedBytes.size).isLessThan(tokenizableBefore.numBytes)
|
||||
val tokenizableAfter = serializedBytes.deserialize(factory, testContext)
|
||||
val tokenizableAfter = serializedBytes.checkpointDeserialize(factory, testContext)
|
||||
assertThat(tokenizableAfter).isSameAs(tokenizableBefore)
|
||||
}
|
||||
|
||||
@ -62,8 +69,8 @@ class SerializationTokenTest {
|
||||
val tokenizableBefore = UnitSerializeAsToken()
|
||||
val context = serializeAsTokenContext(tokenizableBefore)
|
||||
val testContext = this.context.withTokenContext(context)
|
||||
val serializedBytes = tokenizableBefore.serialize(factory, testContext)
|
||||
val tokenizableAfter = serializedBytes.deserialize(factory, testContext)
|
||||
val serializedBytes = tokenizableBefore.checkpointSerialize(factory, testContext)
|
||||
val tokenizableAfter = serializedBytes.checkpointDeserialize(factory, testContext)
|
||||
assertThat(tokenizableAfter).isSameAs(tokenizableBefore)
|
||||
}
|
||||
|
||||
@ -72,7 +79,7 @@ class SerializationTokenTest {
|
||||
val tokenizableBefore = UnitSerializeAsToken()
|
||||
val context = serializeAsTokenContext(emptyList<Any>())
|
||||
val testContext = this.context.withTokenContext(context)
|
||||
tokenizableBefore.serialize(factory, testContext)
|
||||
tokenizableBefore.checkpointSerialize(factory, testContext)
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException::class)
|
||||
@ -80,14 +87,14 @@ class SerializationTokenTest {
|
||||
val tokenizableBefore = UnitSerializeAsToken()
|
||||
val context = serializeAsTokenContext(emptyList<Any>())
|
||||
val testContext = this.context.withTokenContext(context)
|
||||
val serializedBytes = tokenizableBefore.toToken(serializeAsTokenContext(emptyList<Any>())).serialize(factory, testContext)
|
||||
serializedBytes.deserialize(factory, testContext)
|
||||
val serializedBytes = tokenizableBefore.toToken(serializeAsTokenContext(emptyList<Any>())).checkpointSerialize(factory, testContext)
|
||||
serializedBytes.checkpointDeserialize(factory, testContext)
|
||||
}
|
||||
|
||||
@Test(expected = KryoException::class)
|
||||
fun `no context set`() {
|
||||
val tokenizableBefore = UnitSerializeAsToken()
|
||||
tokenizableBefore.serialize(factory, context)
|
||||
tokenizableBefore.checkpointSerialize(factory, context)
|
||||
}
|
||||
|
||||
@Test(expected = KryoException::class)
|
||||
@ -105,7 +112,7 @@ class SerializationTokenTest {
|
||||
kryo.writeObject(it, emptyList<Any>())
|
||||
}
|
||||
val serializedBytes = SerializedBytes<Any>(stream.toByteArray())
|
||||
serializedBytes.deserialize(factory, testContext)
|
||||
serializedBytes.checkpointDeserialize(factory, testContext)
|
||||
}
|
||||
|
||||
private class WrongTypeSerializeAsToken : SerializeAsToken {
|
||||
@ -121,7 +128,7 @@ class SerializationTokenTest {
|
||||
val tokenizableBefore = WrongTypeSerializeAsToken()
|
||||
val context = serializeAsTokenContext(tokenizableBefore)
|
||||
val testContext = this.context.withTokenContext(context)
|
||||
val serializedBytes = tokenizableBefore.serialize(factory, testContext)
|
||||
serializedBytes.deserialize(factory, testContext)
|
||||
val serializedBytes = tokenizableBefore.checkpointSerialize(factory, testContext)
|
||||
serializedBytes.checkpointDeserialize(factory, testContext)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user