From cccbbe1c80708c4efddfeb1148cbab3a22fdbcfa Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Fri, 27 Mar 2020 09:16:31 +0000 Subject: [PATCH] CORDA-3680: Add CorDapp custom serialisers to Driver's in-process nodes. (#6102) * Run serialisation tests with both in-process and out-of-process nodes. * Add custom serialisers and whitelists to Driver's AMQPServerSerializationScheme. --- .../client/AMQPClientSerializationScheme.kt | 2 +- .../amqp/AMQPServerSerializationScheme.kt | 12 ++++++++--- .../node/ContractWithCustomSerializerTest.kt | 12 +++++++++-- ...ContractWithMissingCustomSerializerTest.kt | 20 +++++++++++++------ .../InternalSerializationTestHelpers.kt | 10 ++++++---- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/rpc/client/AMQPClientSerializationScheme.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/rpc/client/AMQPClientSerializationScheme.kt index e86796bf8b..d0c76a593f 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/rpc/client/AMQPClientSerializationScheme.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/rpc/client/AMQPClientSerializationScheme.kt @@ -66,7 +66,7 @@ class AMQPClientSerializationScheme( } } - override fun canDeserializeVersion(magic: CordaSerializationMagic, target: SerializationContext.UseCase): Boolean { + override fun canDeserializeVersion(magic: CordaSerializationMagic, target: UseCase): Boolean { return magic == amqpMagic && (target == UseCase.RPCClient || target == UseCase.P2P) } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/AMQPServerSerializationScheme.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/AMQPServerSerializationScheme.kt index d16f9d6466..75647d05fd 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/AMQPServerSerializationScheme.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/AMQPServerSerializationScheme.kt @@ -18,10 +18,16 @@ class AMQPServerSerializationScheme( cordappSerializationWhitelists: Set, serializerFactoriesForContexts: MutableMap ) : AbstractAMQPSerializationScheme(cordappCustomSerializers, cordappSerializationWhitelists, serializerFactoriesForContexts) { - constructor(cordapps: List) : this(cordapps.customSerializers, cordapps.serializationWhitelists, AccessOrderLinkedHashMap(128).toSynchronised()) - constructor(cordapps: List, serializerFactoriesForContexts: MutableMap) : this(cordapps.customSerializers, cordapps.serializationWhitelists, serializerFactoriesForContexts) + constructor(cordapps: List) : this(cordapps.customSerializers, cordapps.serializationWhitelists) + constructor(cordapps: List, serializerFactoriesForContexts: MutableMap) + : this(cordapps.customSerializers, cordapps.serializationWhitelists, serializerFactoriesForContexts) + constructor( + cordappCustomSerializers: Set>, + cordappSerializationWhitelists: Set + ) : this(cordappCustomSerializers, cordappSerializationWhitelists, AccessOrderLinkedHashMap(128).toSynchronised()) - constructor() : this(emptySet(), emptySet(), AccessOrderLinkedHashMap(128).toSynchronised() ) + @Suppress("UNUSED") + constructor() : this(emptySet(), emptySet()) override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory { throw UnsupportedOperationException() diff --git a/node/src/integration-test/kotlin/net/corda/node/ContractWithCustomSerializerTest.kt b/node/src/integration-test/kotlin/net/corda/node/ContractWithCustomSerializerTest.kt index d55787148f..ffb2d297b1 100644 --- a/node/src/integration-test/kotlin/net/corda/node/ContractWithCustomSerializerTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/ContractWithCustomSerializerTest.kt @@ -18,13 +18,21 @@ import net.corda.testing.node.internal.cordappWithPackages import org.assertj.core.api.Assertions.assertThat import org.junit.BeforeClass import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters import kotlin.test.assertFailsWith +@RunWith(Parameterized::class) @Suppress("FunctionName") -class ContractWithCustomSerializerTest { +class ContractWithCustomSerializerTest(private val runInProcess: Boolean) { companion object { const val CURRANTS = 5000L + @Parameters + @JvmStatic + fun modes(): List> = listOf(Array(1) { true }, Array(1) { false }) + @BeforeClass @JvmStatic fun checkData() { @@ -37,7 +45,7 @@ class ContractWithCustomSerializerTest { val user = User("u", "p", setOf(Permissions.all())) driver(DriverParameters( portAllocation = incrementalPortAllocation(), - startNodesInProcess = false, + startNodesInProcess = runInProcess, notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, validating = true)), cordappsForAllNodes = listOf( cordappWithPackages("net.corda.flows.serialization.custom").signed(), diff --git a/node/src/integration-test/kotlin/net/corda/node/ContractWithMissingCustomSerializerTest.kt b/node/src/integration-test/kotlin/net/corda/node/ContractWithMissingCustomSerializerTest.kt index 0c4d5984fe..2110ff3cfe 100644 --- a/node/src/integration-test/kotlin/net/corda/node/ContractWithMissingCustomSerializerTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/ContractWithMissingCustomSerializerTest.kt @@ -26,10 +26,14 @@ import net.corda.testing.node.internal.cordappWithPackages import org.assertj.core.api.Assertions.assertThat import org.junit.BeforeClass import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters import kotlin.test.assertFailsWith +@RunWith(Parameterized::class) @Suppress("FunctionName") -class ContractWithMissingCustomSerializerTest { +class ContractWithMissingCustomSerializerTest(private val runInProcess: Boolean) { companion object { const val BOBBINS = 5000L @@ -37,15 +41,19 @@ class ContractWithMissingCustomSerializerTest { val flowCorDapp = cordappWithPackages("net.corda.flows.serialization.missing").signed() val contractCorDapp = cordappWithPackages("net.corda.contracts.serialization.missing").signed() - fun driverParameters(cordapps: List): DriverParameters { + fun driverParameters(cordapps: List, runInProcess: Boolean): DriverParameters { return DriverParameters( portAllocation = incrementalPortAllocation(), - startNodesInProcess = false, + startNodesInProcess = runInProcess, notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, validating = true)), cordappsForAllNodes = cordapps ) } + @Parameters + @JvmStatic + fun modes(): List> = listOf(Array(1) { true }, Array(1) { false }) + @BeforeClass @JvmStatic fun checkData() { @@ -62,7 +70,7 @@ class ContractWithMissingCustomSerializerTest { val flowId = flowCorDapp.jarFile.hash val fixupCorDapp = cordappWithFixups(listOf(setOf(contractId) to setOf(contractId, flowId))).signed() - driver(driverParameters(listOf(flowCorDapp, contractCorDapp, fixupCorDapp))) { + driver(driverParameters(listOf(flowCorDapp, contractCorDapp, fixupCorDapp), runInProcess)) { val alice = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).getOrThrow() val ex = assertFailsWith { CordaRPCClient(hostAndPort = alice.rpcAddress) @@ -83,7 +91,7 @@ class ContractWithMissingCustomSerializerTest { */ @Test(timeout=300_000) fun `flow with missing custom serializer but without fixup`() { - driver(driverParameters(listOf(flowCorDapp, contractCorDapp))) { + driver(driverParameters(listOf(flowCorDapp, contractCorDapp), runInProcess)) { val alice = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).getOrThrow() val ex = assertFailsWith { CordaRPCClient(hostAndPort = alice.rpcAddress) @@ -104,7 +112,7 @@ class ContractWithMissingCustomSerializerTest { */ @Test(timeout=300_000) fun `transaction builder flow with missing custom serializer by rpc`() { - driver(driverParameters(listOf(flowCorDapp, contractCorDapp))) { + driver(driverParameters(listOf(flowCorDapp, contractCorDapp), runInProcess)) { val alice = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).getOrThrow() val ex = assertFailsWith { CordaRPCClient(hostAndPort = alice.rpcAddress) diff --git a/testing/core-test-utils/src/main/kotlin/net/corda/coretesting/internal/InternalSerializationTestHelpers.kt b/testing/core-test-utils/src/main/kotlin/net/corda/coretesting/internal/InternalSerializationTestHelpers.kt index 6e2253814b..61bf91aac9 100644 --- a/testing/core-test-utils/src/main/kotlin/net/corda/coretesting/internal/InternalSerializationTestHelpers.kt +++ b/testing/core-test-utils/src/main/kotlin/net/corda/coretesting/internal/InternalSerializationTestHelpers.kt @@ -25,16 +25,18 @@ fun createTestSerializationEnv(): SerializationEnvironment { } fun createTestSerializationEnv(classLoader: ClassLoader?): SerializationEnvironment { - val clientSerializationScheme = if (classLoader != null) { + val (clientSerializationScheme, serverSerializationScheme) = if (classLoader != null) { val customSerializers = createInstancesOfClassesImplementing(classLoader, SerializationCustomSerializer::class.java) val serializationWhitelists = ServiceLoader.load(SerializationWhitelist::class.java, classLoader).toSet() - AMQPClientSerializationScheme(customSerializers, serializationWhitelists) + + Pair(AMQPClientSerializationScheme(customSerializers, serializationWhitelists), + AMQPServerSerializationScheme(customSerializers, serializationWhitelists)) } else { - AMQPClientSerializationScheme(emptyList()) + Pair(AMQPClientSerializationScheme(emptyList()), AMQPServerSerializationScheme(emptyList())) } val factory = SerializationFactoryImpl().apply { registerScheme(clientSerializationScheme) - registerScheme(AMQPServerSerializationScheme(emptyList())) + registerScheme(serverSerializationScheme) } return SerializationEnvironment.with( factory,