Merge pull request #1548 from corda/merges/os-merge-to-ecbf23a

Merge OS ->ENT to ecbf23a.
This commit is contained in:
szymonsztuka 2018-11-08 12:02:31 +00:00 committed by GitHub
commit bac265d418
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 732 additions and 355 deletions

View File

@ -20,6 +20,8 @@ public class net.corda.core.CordaException extends java.lang.Exception implement
public void setOriginalExceptionClassName(String)
##
public final class net.corda.core.CordaOID extends java.lang.Object
@NotNull
public static final String ALIAS_PRIVATE_KEY = "1.3.6.1.4.1.50530.1.2"
@NotNull
public static final String CORDA_PLATFORM = "1.3.6.1.4.1.50530.1"
public static final net.corda.core.CordaOID INSTANCE

4
.idea/compiler.xml generated
View File

@ -106,10 +106,6 @@
<module name="core_main" target="1.8" />
<module name="core_smokeTest" target="1.8" />
<module name="core_test" target="1.8" />
<module name="crypto-service_main" target="1.8" />
<module name="crypto-service_test" target="1.8" />
<module name="crypto-services_main" target="1.8" />
<module name="crypto-services_test" target="1.8" />
<module name="data_main" target="1.8" />
<module name="data_test" target="1.8" />
<module name="dbmigration_main" target="1.8" />

View File

@ -38,10 +38,7 @@ import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.parseAsHex
import net.corda.core.utilities.toHexString
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.constructorForDeserialization
import net.corda.serialization.internal.amqp.hasCordaSerializable
import net.corda.serialization.internal.amqp.propertiesForSerialization
import net.corda.serialization.internal.amqp.*
import java.math.BigDecimal
import java.security.PublicKey
import java.security.cert.CertPath
@ -88,7 +85,7 @@ class CordaModule : SimpleModule("corda-core") {
*/
private class CordaSerializableBeanSerializerModifier : BeanSerializerModifier() {
// We need to pass in a SerializerFactory when scanning for properties, but don't actually do any serialisation so any will do.
private val serializerFactory = SerializerFactory(AllWhitelist, javaClass.classLoader)
private val serializerFactory = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader)
override fun changeProperties(config: SerializationConfig,
beanDesc: BeanDescription,

View File

@ -8,10 +8,7 @@ import net.corda.core.serialization.SerializationCustomSerializer
import net.corda.core.serialization.internal.SerializationEnvironment
import net.corda.core.serialization.internal.nodeSerializationEnv
import net.corda.serialization.internal.*
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.amqpMagic
import net.corda.serialization.internal.amqp.*
import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer
/**
@ -52,7 +49,7 @@ class AMQPClientSerializationScheme(
}
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply {
return SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply {
register(RpcClientObservableDeSerializer)
register(RpcClientCordaFutureSerializer(this))
register(RxNotificationSerializer(this))

View File

@ -1,4 +1,4 @@
gradlePluginsVersion=4.0.33
gradlePluginsVersion=4.0.34
kotlinVersion=1.2.71
# ***************************************************************#
# When incrementing platformVersion make sure to update #

View File

@ -1,18 +1,23 @@
package net.corda.core
import net.corda.core.crypto.internal.AliasPrivateKey
/**
* OIDs used for the Corda platform. Entries MUST NOT be removed from this file; if an OID is incorrectly assigned it
* should be marked deprecated.
* OIDs used for the Corda platform. All entries MUST be defined in this file only and they MUST NOT be removed.
* If an OID is incorrectly assigned, it should be marked deprecated and NEVER be reused again.
*/
@KeepForDJVM
object CordaOID {
/** Assigned to R3, see http://www.oid-info.com/cgi-bin/display?oid=1.3.6.1.4.1.50530&action=display */
const val R3_ROOT = "1.3.6.1.4.1.50530"
/** OIDs issued for the Corda platform */
/** OIDs issued for the Corda platform. */
const val CORDA_PLATFORM = "$R3_ROOT.1"
/**
* Identifier for the X.509 certificate extension specifying the Corda role. See
* https://r3-cev.atlassian.net/wiki/spaces/AWG/pages/156860572/Certificate+identity+type+extension for details.
*/
const val X509_EXTENSION_CORDA_ROLE = "$CORDA_PLATFORM.1"
}
/** OID for [AliasPrivateKey]. */
const val ALIAS_PRIVATE_KEY = "$CORDA_PLATFORM.2"
}

View File

@ -42,7 +42,9 @@ private fun provideNonDeterministic(provider: Provider) {
@KeepForDJVM
object CordaObjectIdentifier {
// UUID-based OID
// TODO: Register for an OID space and issue our own shorter OID.
// TODO define and use an official Corda OID in [CordaOID]. We didn't do yet for backwards compatibility purposes,
// because key.encoded (serialised version of keys) and [PublicKey.hash] for already stored [CompositeKey]s
// will not match.
@JvmField
val COMPOSITE_KEY = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791002")
@JvmField

View File

@ -1,5 +1,6 @@
package net.corda.core.crypto.internal
import net.corda.core.CordaOID
import org.bouncycastle.asn1.*
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
import org.bouncycastle.asn1.x509.AlgorithmIdentifier
@ -17,12 +18,7 @@ import java.security.spec.PKCS8EncodedKeySpec
data class AliasPrivateKey(val alias: String): PrivateKey {
companion object {
// UUID-based OID
// TODO: Register for an OID space and issue our own shorter OID.
@JvmField
val ALIAS_PRIVATE_KEY = ASN1ObjectIdentifier("2.26.40086077608615255153862931087626791001")
const val ALIAS_KEY_ALGORITHM = "ALIAS"
const val ALIAS_KEY_ALGORITHM = "AliasPrivateKey"
}
override fun getAlgorithm() = ALIAS_KEY_ALGORITHM
@ -30,7 +26,10 @@ data class AliasPrivateKey(val alias: String): PrivateKey {
override fun getEncoded(): ByteArray {
val keyVector = ASN1EncodableVector()
keyVector.add(DERUTF8String(alias))
val privateKeyInfoBytes = PrivateKeyInfo(AlgorithmIdentifier(ALIAS_PRIVATE_KEY), DERSequence(keyVector)).getEncoded(ASN1Encoding.DER)
val privateKeyInfoBytes = PrivateKeyInfo(
AlgorithmIdentifier(ASN1ObjectIdentifier(CordaOID.ALIAS_PRIVATE_KEY)),
DERSequence(keyVector)
).getEncoded(ASN1Encoding.DER)
val keySpec = PKCS8EncodedKeySpec(privateKeyInfoBytes)
return keySpec.encoded
}

View File

@ -6,7 +6,7 @@ import net.corda.serialization.internal.AMQP_RPC_CLIENT_CONTEXT
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.DeserializationInput
import net.corda.serialization.internal.amqp.SerializationOutput
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.serialization.internal.amqp.custom.PublicKeySerializer
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
@ -15,7 +15,7 @@ import org.junit.Test
import kotlin.test.assertEquals
class TransactionVerificationExceptionSerialisationTests {
private fun defaultFactory() = SerializerFactory(
private fun defaultFactory() = SerializerFactoryBuilder.build(
AllWhitelist,
ClassLoader.getSystemClassLoader()
)

View File

@ -320,6 +320,8 @@ absolute path to the node's base directory.
Valid values for this property are between 4 (that is the number used for the single threaded state machine in
open source) and the number of flow threads.
.. _corda_configuration_file_signer_blacklist:
:cordappSignerKeyFingerprintBlacklist: List of public keys fingerprints (SHA-256 of public key hash) not allowed as Cordapp JARs signers.
Node will not load Cordapps signed by those keys.
The option takes effect only in production mode and defaults to Corda development keys (``["56CA54E803CB87C8472EBD3FBC6A2F1876E814CEEBF74860BD46997F40729367",

View File

@ -162,6 +162,9 @@ without need to create a keystore and configure the ``cordapp`` plugin.
For production deployment ensure to sign the CorDapp using your own certificate e.g. by setting system properties to point to an external keystore
or by disabling signing in ``cordapp`` plugin and signing the CordDapp JAR downstream in your build pipeline.
CorDapp signed by Corda development certificate is accepted by Corda node only when running in the development mode.
In case CordDapp signed by the (default) development key is run on node in the production mode (e.g. for testing),
the node may be set to accept the development key by adding the ``cordappSignerKeyFingerprintBlacklist = []`` property set to empty list
(see :ref:`Configuring a node <corda_configuration_file_signer_blacklist>`).
Signing options can be contextually overwritten by the relevant system properties as described above.
This allows the single ``build.gradle`` file to be used for a development build (defaulting to the Corda development keystore)

View File

@ -138,4 +138,63 @@ the ``SubResponder`` with ``BaseResponder``
flowOverride("net.corda.Initiator", "net.corda.BaseResponder")
}
This will generate the corresponding ``flowOverrides`` section and place it in the configuration for that node.
This will generate the corresponding ``flowOverrides`` section and place it in the configuration for that node.
Modifying the behaviour of @InitiatingFlow(s)
---------------------------------------------
It is likely that initiating flows will also require changes to reflect the different systems that are likely to be encountered.
At the moment, corda provides the ability to subclass an Initiator, and ensures that the correct responder will be invoked.
In the below example, we will change the behaviour of an Initiator from filtering Notaries out from comms, to only communicating with Notaries
.. code-block:: kotlin
@InitiatingFlow
@StartableByRPC
@StartableByService
open class BaseInitiator : FlowLogic<String>() {
@Suspendable
override fun call(): String {
val partiesToTalkTo = serviceHub.networkMapCache.allNodes
.filterNot { it.legalIdentities.first() in serviceHub.networkMapCache.notaryIdentities }
.filterNot { it.legalIdentities.first().name == ourIdentity.name }.map { it.legalIdentities.first() }
val responses = ArrayList<String>()
for (party in partiesToTalkTo) {
val session = initiateFlow(party)
val received = session.receive<String>().unwrap { it }
responses.add(party.name.toString() + " responded with backend: " + received)
}
return "${getFLowName()} received the following \n" + responses.joinToString("\n") { it }
}
open fun getFLowName(): String {
return "Normal Computer"
}
}
@StartableByRPC
@StartableByService
class NotaryOnlyInitiator : BaseInitiator() {
@Suspendable
override fun call(): String {
return "Notary Communicator received:\n" + serviceHub.networkMapCache.notaryIdentities.map {
"Notary: ${it.name.organisation} is using a " + initiateFlow(it).receive<String>().unwrap { it }
}.joinToString("\n") { it }
}
.. warning:: The subclass must not have the @InitiatingFlow annotation.
Corda will use the first annotation detected in the class hierarchy to determine which responder should be invoked. So for a Responder similar to
.. code-block:: kotlin
@InitiatedBy(BaseInitiator::class)
class BobbyResponder(othersideSession: FlowSession) : BaseResponder(othersideSession) {
override fun getMessageFromBackend(): String {
return "Robert'); DROP TABLE STATES;"
}
}
it would be possible to invoke either ``BaseInitiator`` or ``NotaryOnlyInitiator`` and ``BobbyResponder`` would be used to reply.
.. warning:: You must ensure the sequence of sends/receives/subFlows in a subclass are compatible with the parent.

View File

@ -1,6 +1,7 @@
package net.corda.nodeapi.internal.network
import com.typesafe.config.Config
import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigFactory
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.CordaX500Name
@ -30,6 +31,7 @@ import net.corda.serialization.internal.CordaSerializationMagic
import net.corda.serialization.internal.SerializationFactoryImpl
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.serialization.internal.amqp.amqpMagic
import java.io.File
import java.io.InputStream
import java.nio.file.Path
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
@ -96,21 +98,36 @@ internal constructor(private val initSerEnv: Boolean,
private fun generateNodeInfo(nodeDir: Path): Path {
val logsDir = (nodeDir / LOGS_DIR_NAME).createDirectories()
val nodeInfoGenFile = (logsDir / "node-info-gen.log").toFile()
val process = ProcessBuilder(nodeInfoGenCmd)
.directory(nodeDir.toFile())
.redirectErrorStream(true)
.redirectOutput((logsDir / "node-info-gen.log").toFile())
.redirectOutput(nodeInfoGenFile)
.apply { environment()["CAPSULE_CACHE_DIR"] = "../.cache" }
.start()
if (!process.waitFor(3, TimeUnit.MINUTES)) {
process.destroyForcibly()
throw IllegalStateException("Error while generating node info file. Please check the logs in $logsDir.")
printNodeInfoGenLogToConsole(nodeInfoGenFile)
}
check(process.exitValue() == 0) { "Error while generating node info file. Please check the logs in $logsDir." }
printNodeInfoGenLogToConsole(nodeInfoGenFile) { process.exitValue() == 0 }
return nodeDir.list { paths ->
paths.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }.findFirst().get()
}
}
private fun printNodeInfoGenLogToConsole(nodeInfoGenFile: File, check: (() -> Boolean) = { true }) {
if (!check.invoke()) {
val nodeDir = nodeInfoGenFile.parent
val nodeIdentifier = try {
ConfigFactory.parseFile((nodeDir / "node.conf").toFile()).getString("myLegalName")
} catch (e: ConfigException) {
nodeDir
}
System.err.println("#### Error while generating node info file $nodeIdentifier ####")
nodeInfoGenFile.inputStream().copyTo(System.err)
throw IllegalStateException("Error while generating node info file. Please check the logs in $nodeDir.")
}
}
}
sealed class NotaryCluster {
@ -142,7 +159,7 @@ internal constructor(private val initSerEnv: Boolean,
private fun isBFTNotary(config: Config): Boolean {
// TODO: pass a commandline parameter to the bootstrapper instead. Better yet, a notary config map
// specifying the notary identities and the type (single-node, CFT, BFT) of each notary to set up.
return config.getString ("notary.className").contains("BFT", true)
return config.getString("notary.className").contains("BFT", true)
}
private fun generateServiceIdentitiesForNotaryClusters(configs: Map<Path, Config>) {
@ -172,7 +189,7 @@ internal constructor(private val initSerEnv: Boolean,
}
/** Entry point for the tool */
fun bootstrap(directory: Path, copyCordapps: Boolean, minimumPlatformVersion: Int, packageOwnership : Map<JavaPackageName, PublicKey?> = emptyMap()) {
fun bootstrap(directory: Path, copyCordapps: Boolean, minimumPlatformVersion: Int, packageOwnership: Map<JavaPackageName, PublicKey?> = emptyMap()) {
require(minimumPlatformVersion <= PLATFORM_VERSION) { "Minimum platform version cannot be greater than $PLATFORM_VERSION" }
// Don't accidently include the bootstrapper jar as a CorDapp!
val bootstrapperJar = javaClass.location.toPath()
@ -188,7 +205,7 @@ internal constructor(private val initSerEnv: Boolean,
copyCordapps: Boolean,
fromCordform: Boolean,
minimumPlatformVersion: Int = PLATFORM_VERSION,
packageOwnership : Map<JavaPackageName, PublicKey?> = emptyMap()
packageOwnership: Map<JavaPackageName, PublicKey?> = emptyMap()
) {
directory.createDirectories()
println("Bootstrapping local test network in $directory")
@ -361,21 +378,20 @@ internal constructor(private val initSerEnv: Boolean,
existingNetParams: NetworkParameters?,
nodeDirs: List<Path>,
minimumPlatformVersion: Int,
packageOwnership : Map<JavaPackageName, PublicKey?>
packageOwnership: Map<JavaPackageName, PublicKey?>
): NetworkParameters {
// TODO Add config for maxMessageSize and maxTransactionSize
val netParams = if (existingNetParams != null) {
if (existingNetParams.whitelistedContractImplementations == whitelist && existingNetParams.notaries == notaryInfos &&
existingNetParams.packageOwnership.entries.containsAll(packageOwnership.entries)) {
existingNetParams.packageOwnership.entries.containsAll(packageOwnership.entries)) {
existingNetParams
} else {
var updatePackageOwnership = mutableMapOf(*existingNetParams.packageOwnership.map { Pair(it.key,it.value) }.toTypedArray())
var updatePackageOwnership = mutableMapOf(*existingNetParams.packageOwnership.map { Pair(it.key, it.value) }.toTypedArray())
packageOwnership.forEach { key, value ->
if (value == null) {
if (updatePackageOwnership.remove(key) != null)
println("Unregistering package $key")
}
else {
} else {
if (updatePackageOwnership.put(key, value) == null)
println("Registering package $key for owner ${value.toStringShort()}")
}

View File

@ -8,6 +8,7 @@ import net.corda.serialization.internal.CordaSerializationMagic
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer
/**
@ -28,7 +29,7 @@ class AMQPServerSerializationScheme(
}
override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply {
return SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply {
register(RpcServerObservableSerializer())
register(RpcServerCordaFutureSerializer(this))
register(RxNotificationSerializer(this))

View File

@ -10,7 +10,7 @@ import net.corda.node.serialization.amqp.RpcServerObservableSerializer
import net.corda.node.services.messaging.ObservableSubscription
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.SerializationOutput
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import org.apache.activemq.artemis.api.core.SimpleString
import org.junit.Test
import rx.Observable
@ -34,7 +34,7 @@ class RpcServerObservableSerializerTests {
@Test
fun canSerializerBeRegistered() {
val sf = SerializerFactory(AllWhitelist, javaClass.classLoader)
val sf = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader)
try {
sf.register(RpcServerObservableSerializer())
@ -67,7 +67,7 @@ class RpcServerObservableSerializerTests {
deduplicationIdentity = "thisIsATest",
clientAddress = SimpleString(testClientAddress))
val sf = SerializerFactory(AllWhitelist, javaClass.classLoader).apply {
val sf = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply {
register(RpcServerObservableSerializer())
}

View File

@ -12,6 +12,7 @@ import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.client.rpc.internal.ObservableContext as ClientObservableContext
/**
@ -28,13 +29,13 @@ class AMQPRoundTripRPCSerializationScheme(
cordappCustomSerializers, serializerFactoriesForContexts
) {
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(AllWhitelist, javaClass.classLoader).apply {
return SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply {
register(RpcClientObservableDeSerializer)
}
}
override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory {
return SerializerFactory(AllWhitelist, javaClass.classLoader).apply {
return SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply {
register(RpcServerObservableSerializer())
}
}

View File

@ -50,6 +50,7 @@ task patchSerialization(type: Zip, dependsOn: serializationJarTask) {
exclude 'net/corda/serialization/internal/amqp/AMQPSerializerFactories*'
exclude 'net/corda/serialization/internal/amqp/AMQPStreams*'
exclude 'net/corda/serialization/internal/amqp/AMQPSerializationThreadContext*'
exclude 'net/corda/serialization/internal/model/DefaultCacheProvider*'
}
reproducibleFileOrder = true

View File

@ -15,15 +15,9 @@ fun createSerializerFactoryFactory(): SerializerFactoryFactory = DeterministicSe
private class DeterministicSerializerFactoryFactory : SerializerFactoryFactory {
override fun make(context: SerializationContext) =
SerializerFactory(
whitelist = context.whitelist,
classCarpenter = DummyClassCarpenter(context.whitelist, context.deserializationClassLoader),
serializersByType = mutableMapOf(),
serializersByDescriptor = mutableMapOf(),
customSerializers = ArrayList(),
customSerializersCache = mutableMapOf(),
transformsCache = mutableMapOf()
)
SerializerFactoryBuilder.build(
whitelist = context.whitelist,
classCarpenter = DummyClassCarpenter(context.whitelist, context.deserializationClassLoader))
}
private class DummyClassCarpenter(

View File

@ -0,0 +1,9 @@
package net.corda.serialization.internal.model
/**
* We can't have [ConcurrentHashMap]s in the DJVM, so it must supply its own version of this object which returns
* plain old [MutableMap]s instead.
*/
object DefaultCacheProvider {
fun <K, V> createCache(): MutableMap<K, V> = mutableMapOf()
}

View File

@ -3,11 +3,14 @@
package net.corda.serialization.internal.amqp
import net.corda.core.serialization.SerializationContext
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
fun createSerializerFactoryFactory(): SerializerFactoryFactory = SerializerFactoryFactoryImpl()
open class SerializerFactoryFactoryImpl : SerializerFactoryFactory {
override fun make(context: SerializationContext): SerializerFactory {
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled)
return SerializerFactoryBuilder.build(context.whitelist,
ClassCarpenterImpl(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled)
)
}
}

View File

@ -1,7 +1,6 @@
package net.corda.serialization.internal.amqp
import com.google.common.primitives.Primitives
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.StubOutForDJVM
import net.corda.core.internal.kotlinObjectInstance
@ -12,12 +11,11 @@ import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.trace
import net.corda.serialization.internal.carpenter.*
import net.corda.serialization.internal.model.DefaultCacheProvider
import org.apache.qpid.proton.amqp.*
import java.io.NotSerializableException
import java.lang.reflect.*
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList
import javax.annotation.concurrent.ThreadSafe
@KeepForDJVM
@ -49,54 +47,122 @@ data class CustomSerializersCacheKey(val clazz: Class<*>, val declaredType: Type
// TODO: need to support super classes as well as interfaces with our current code base... what's involved? If we continue to ban, what is the impact?
@KeepForDJVM
@ThreadSafe
open class SerializerFactory(
val whitelist: ClassWhitelist,
val classCarpenter: ClassCarpenter,
private val evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
private val serializersByType: MutableMap<Type, AMQPSerializer<Any>>,
val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>>,
private val customSerializers: MutableList<SerializerFor>,
private val customSerializersCache: MutableMap<CustomSerializersCacheKey, AMQPSerializer<Any>?>,
val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>>,
interface SerializerFactory {
val whitelist: ClassWhitelist
val classCarpenter: ClassCarpenter
val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter
// Caches
val serializersByType: MutableMap<Type, AMQPSerializer<Any>>
val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>>
val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>>
val fingerPrinter: FingerPrinter
val classloader: ClassLoader
/**
* Look up, and manufacture if necessary, a serializer for the given type.
*
* @param actualClass Will be null if there isn't an actual object instance available (e.g. for
* restricted type processing).
*/
@Throws(NotSerializableException::class)
fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer<Any>
/**
* Lookup and manufacture a serializer for the given AMQP type descriptor, assuming we also have the necessary types
* contained in the [Schema].
*/
@Throws(NotSerializableException::class)
fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer<Any>
/**
* Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer
* that expects to find getters and a constructor with a parameter for each property.
*/
fun register(customSerializer: CustomSerializer<out Any>)
fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer<Any>?
fun registerExternal(customSerializer: CorDappCustomSerializer)
fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer<Any>): AMQPSerializer<Any>
object AnyType : WildcardType {
override fun getUpperBounds(): Array<Type> = arrayOf(Object::class.java)
override fun getLowerBounds(): Array<Type> = emptyArray()
override fun toString(): String = "?"
}
companion object {
fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null
fun primitiveTypeName(type: Type): String? {
val clazz = type as? Class<*> ?: return null
return primitiveTypeNames[Primitives.unwrap(clazz)]
}
fun primitiveType(type: String): Class<*>? {
return namesOfPrimitiveTypes[type]
}
private val primitiveTypeNames: Map<Class<*>, String> = mapOf(
Character::class.java to "char",
Char::class.java to "char",
Boolean::class.java to "boolean",
Byte::class.java to "byte",
UnsignedByte::class.java to "ubyte",
Short::class.java to "short",
UnsignedShort::class.java to "ushort",
Int::class.java to "int",
UnsignedInteger::class.java to "uint",
Long::class.java to "long",
UnsignedLong::class.java to "ulong",
Float::class.java to "float",
Double::class.java to "double",
Decimal32::class.java to "decimal32",
Decimal64::class.java to "decimal62",
Decimal128::class.java to "decimal128",
Date::class.java to "timestamp",
UUID::class.java to "uuid",
ByteArray::class.java to "binary",
String::class.java to "string",
Symbol::class.java to "symbol")
private val namesOfPrimitiveTypes: Map<String, Class<*>> = primitiveTypeNames.map { it.value to it.key }.toMap()
fun nameForType(type: Type): String = when (type) {
is Class<*> -> {
primitiveTypeName(type) ?: if (type.isArray) {
"${nameForType(type.componentType)}${if (type.componentType.isPrimitive) "[p]" else "[]"}"
} else type.name
}
is ParameterizedType -> {
"${nameForType(type.rawType)}<${type.actualTypeArguments.joinToString { nameForType(it) }}>"
}
is GenericArrayType -> "${nameForType(type.genericComponentType)}[]"
is WildcardType -> "?"
is TypeVariable<*> -> "?"
else -> throw AMQPNotSerializableException(type, "Unable to render type $type to a string.")
}
}
}
open class DefaultSerializerFactory(
override val whitelist: ClassWhitelist,
override val classCarpenter: ClassCarpenter,
private val evolutionSerializerProvider: EvolutionSerializerProvider,
override val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter,
private val onlyCustomSerializers: Boolean = false
) {
@DeleteForDJVM
constructor(whitelist: ClassWhitelist,
classCarpenter: ClassCarpenter,
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
onlyCustomSerializers: Boolean = false
) : this(
whitelist,
classCarpenter,
evolutionSerializerProvider,
fingerPrinterConstructor,
ConcurrentHashMap(),
ConcurrentHashMap(),
CopyOnWriteArrayList(),
ConcurrentHashMap(),
ConcurrentHashMap(),
onlyCustomSerializers
)
) : SerializerFactory {
@DeleteForDJVM
constructor(whitelist: ClassWhitelist,
carpenterClassLoader: ClassLoader,
lenientCarpenter: Boolean = false,
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
onlyCustomSerializers: Boolean = false
) : this(
whitelist,
ClassCarpenterImpl(whitelist, carpenterClassLoader, lenientCarpenter),
evolutionSerializerProvider,
fingerPrinterConstructor,
onlyCustomSerializers)
// Caches
override val serializersByType: MutableMap<Type, AMQPSerializer<Any>> = DefaultCacheProvider.createCache()
override val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>> = DefaultCacheProvider.createCache()
private var customSerializers: List<SerializerFor> = emptyList()
private val customSerializersCache: MutableMap<CustomSerializersCacheKey, AMQPSerializer<Any>?> = DefaultCacheProvider.createCache()
override val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>> = DefaultCacheProvider.createCache()
val fingerPrinter by lazy { fingerPrinterConstructor(this) }
override val fingerPrinter by lazy { fingerPrinterConstructor(this) }
val classloader: ClassLoader get() = classCarpenter.classloader
override val classloader: ClassLoader get() = classCarpenter.classloader
// Used to short circuit any computation for a given input, for performance.
private data class MemoType(val actualClass: Class<*>?, val declaredType: Type) : Type
@ -108,7 +174,7 @@ open class SerializerFactory(
* restricted type processing).
*/
@Throws(NotSerializableException::class)
fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer<Any> {
override fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer<Any> {
// can be useful to enable but will be *extremely* chatty if you do
logger.trace { "Get Serializer for $actualClass ${declaredType.typeName}" }
@ -169,7 +235,7 @@ open class SerializerFactory(
* contained in the [Schema].
*/
@Throws(NotSerializableException::class)
fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer<Any> {
override fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer<Any> {
return serializersByDescriptor[typeDescriptor] ?: {
logger.trace("get Serializer descriptor=${typeDescriptor}")
processSchema(FactorySchemaAndDescriptor(schema, typeDescriptor))
@ -182,7 +248,7 @@ open class SerializerFactory(
* Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer
* that expects to find getters and a constructor with a parameter for each property.
*/
open fun register(customSerializer: CustomSerializer<out Any>) {
override fun register(customSerializer: CustomSerializer<out Any>) {
logger.trace("action=\"Registering custom serializer\", class=\"${customSerializer.type}\"")
if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) {
customSerializers += customSerializer
@ -193,7 +259,7 @@ open class SerializerFactory(
}
}
fun registerExternal(customSerializer: CorDappCustomSerializer) {
override fun registerExternal(customSerializer: CorDappCustomSerializer) {
logger.trace("action=\"Registering external serializer\", class=\"${customSerializer.type}\"")
if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) {
customSerializers += customSerializer
@ -319,7 +385,7 @@ open class SerializerFactory(
throw AMQPNotSerializableException(
type,
"Serializer does not support synthetic classes")
} else if (isPrimitive(clazz)) {
} else if (SerializerFactory.isPrimitive(clazz)) {
AMQPPrimitiveSerializer(clazz)
} else {
findCustomSerializer(clazz, declaredType) ?: run {
@ -344,7 +410,7 @@ open class SerializerFactory(
}
}
internal fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer<Any>? {
override fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer<Any>? {
return customSerializersCache.computeIfAbsent(CustomSerializersCacheKey(clazz, declaredType), ::doFindCustomSerializer)
}
@ -383,69 +449,11 @@ open class SerializerFactory(
return MapSerializer(declaredType, this)
}
fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer<Any>): AMQPSerializer<Any> =
override fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer<Any>): AMQPSerializer<Any> =
serializersByDescriptor.computeIfAbsent(name) { _ -> serializerCreator() }
companion object {
private val logger = contextLogger()
fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null
fun primitiveTypeName(type: Type): String? {
val clazz = type as? Class<*> ?: return null
return primitiveTypeNames[Primitives.unwrap(clazz)]
}
fun primitiveType(type: String): Class<*>? {
return namesOfPrimitiveTypes[type]
}
private val primitiveTypeNames: Map<Class<*>, String> = mapOf(
Character::class.java to "char",
Char::class.java to "char",
Boolean::class.java to "boolean",
Byte::class.java to "byte",
UnsignedByte::class.java to "ubyte",
Short::class.java to "short",
UnsignedShort::class.java to "ushort",
Int::class.java to "int",
UnsignedInteger::class.java to "uint",
Long::class.java to "long",
UnsignedLong::class.java to "ulong",
Float::class.java to "float",
Double::class.java to "double",
Decimal32::class.java to "decimal32",
Decimal64::class.java to "decimal62",
Decimal128::class.java to "decimal128",
Date::class.java to "timestamp",
UUID::class.java to "uuid",
ByteArray::class.java to "binary",
String::class.java to "string",
Symbol::class.java to "symbol")
private val namesOfPrimitiveTypes: Map<String, Class<*>> = primitiveTypeNames.map { it.value to it.key }.toMap()
fun nameForType(type: Type): String = when (type) {
is Class<*> -> {
primitiveTypeName(type) ?: if (type.isArray) {
"${nameForType(type.componentType)}${if (type.componentType.isPrimitive) "[p]" else "[]"}"
} else type.name
}
is ParameterizedType -> {
"${nameForType(type.rawType)}<${type.actualTypeArguments.joinToString { nameForType(it) }}>"
}
is GenericArrayType -> "${nameForType(type.genericComponentType)}[]"
is WildcardType -> "?"
is TypeVariable<*> -> "?"
else -> throw AMQPNotSerializableException(type, "Unable to render type $type to a string.")
}
}
object AnyType : WildcardType {
override fun getUpperBounds(): Array<Type> = arrayOf(Object::class.java)
override fun getLowerBounds(): Array<Type> = emptyArray()
override fun toString(): String = "?"
}
}

View File

@ -0,0 +1,53 @@
package net.corda.serialization.internal.amqp
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.ClassWhitelist
import net.corda.serialization.internal.carpenter.ClassCarpenter
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
@KeepForDJVM
object SerializerFactoryBuilder {
@JvmStatic
@JvmOverloads
fun build(
whitelist: ClassWhitelist,
classCarpenter: ClassCarpenter,
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
fingerPrinterProvider: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
onlyCustomSerializers: Boolean = false): SerializerFactory {
return makeFactory(
whitelist,
classCarpenter,
evolutionSerializerProvider,
fingerPrinterProvider,
onlyCustomSerializers)
}
@JvmStatic
@JvmOverloads
@DeleteForDJVM
fun build(
whitelist: ClassWhitelist,
carpenterClassLoader: ClassLoader,
lenientCarpenterEnabled: Boolean = false,
evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider,
fingerPrinterProvider: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter,
onlyCustomSerializers: Boolean = false): SerializerFactory {
return makeFactory(
whitelist,
ClassCarpenterImpl(whitelist, carpenterClassLoader, lenientCarpenterEnabled),
evolutionSerializerProvider,
fingerPrinterProvider,
onlyCustomSerializers)
}
private fun makeFactory(whitelist: ClassWhitelist,
classCarpenter: ClassCarpenter,
evolutionSerializerProvider: EvolutionSerializerProvider,
fingerPrinterProvider: (SerializerFactory) -> FingerPrinter,
onlyCustomSerializers: Boolean) =
DefaultSerializerFactory(whitelist, classCarpenter, evolutionSerializerProvider, fingerPrinterProvider,
onlyCustomSerializers)
}

View File

@ -0,0 +1,11 @@
package net.corda.serialization.internal.model
import java.util.concurrent.ConcurrentHashMap
/**
* We can't have [ConcurrentHashMap]s in the DJVM, so it must supply its own version of this object which returns
* plain old [MutableMap]s instead.
*/
object DefaultCacheProvider {
fun <K, V> createCache(): MutableMap<K, V> = ConcurrentHashMap()
}

View File

@ -147,10 +147,7 @@ public class JavaPrivatePropertyTests {
//
// Now ensure we actually got a private property serializer
//
Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor");
f.setAccessible(true);
Map<?, AMQPSerializer<?>> serializersByDescriptor = uncheckedCast(f.get(factory));
Map<Object, AMQPSerializer<Object>> serializersByDescriptor = factory.getSerializersByDescriptor();
assertEquals(1, serializersByDescriptor.size());
ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]);
@ -175,9 +172,7 @@ public class JavaPrivatePropertyTests {
//
// Now ensure we actually got a private property serializer
//
Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor");
f.setAccessible(true);
Map<?, AMQPSerializer<?>> serializersByDescriptor = uncheckedCast(f.get(factory));
Map<Object, AMQPSerializer<Object>> serializersByDescriptor = factory.getSerializersByDescriptor();
assertEquals(1, serializersByDescriptor.size());
ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]);

View File

@ -7,7 +7,7 @@ import net.corda.node.serialization.kryo.kryoMagic
import net.corda.node.services.statemachine.DataSessionMessage
import net.corda.serialization.internal.amqp.DeserializationInput
import net.corda.serialization.internal.amqp.Envelope
import net.corda.serialization.internal.amqp.SerializerFactory
import net.corda.serialization.internal.amqp.SerializerFactoryBuilder
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.internal.amqpSpecific
import net.corda.testing.internal.kryoSpecific
@ -28,7 +28,7 @@ class ListsSerializationTest {
fun <T : Any> verifyEnvelope(serBytes: SerializedBytes<T>, envVerBody: (Envelope) -> Unit) =
amqpSpecific("AMQP specific envelope verification") {
val context = SerializationFactory.defaultFactory.defaultContext
val envelope = DeserializationInput(SerializerFactory(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes, context)
val envelope = DeserializationInput(SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes, context)
envVerBody(envelope)
}
}

View File

@ -4,6 +4,7 @@ import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.SerializationCustomSerializer
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.testutils.*
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.assertj.core.api.Assertions
import org.junit.Test
import java.io.NotSerializableException
@ -12,16 +13,16 @@ import kotlin.test.assertEquals
class CorDappSerializerTests {
data class NeedsProxy(val a: String)
private fun proxyFactory(
serializers: List<SerializationCustomSerializer<*, *>>
) = SerializerFactory(
AllWhitelist,
ClassLoader.getSystemClassLoader(),
onlyCustomSerializers = true
).apply {
private fun proxyFactory(serializers: List<SerializationCustomSerializer<*, *>>): SerializerFactory {
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
DefaultEvolutionSerializerProvider)
serializers.forEach {
registerExternal(CorDappCustomSerializer(it, this))
factory.registerExternal(CorDappCustomSerializer(it, factory))
}
return factory
}
class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> {
@ -101,7 +102,10 @@ class CorDappSerializerTests {
override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses
}
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader())
val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory))
val tv1 = 100
@ -123,7 +127,10 @@ class CorDappSerializerTests {
override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses
}
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader())
val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory))
val tv1 = 100
@ -148,7 +155,10 @@ class CorDappSerializerTests {
override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses
}
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader())
val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory))
val tv1 = 100

View File

@ -94,7 +94,9 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase(AllWhitelist) {
// won't already exist and it will be carpented a second time showing that when A and B are the
// same underlying class that we didn't create a second instance of the class with the
// second deserialisation
val lfactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val lfactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val deserialisedC = DeserializationInput(lfactory).deserialize(
TestSerializationOutput(VERBOSE, lfactory).serialize(concreteC))

View File

@ -9,6 +9,7 @@ import net.corda.serialization.internal.amqp.testutils.deserializeAndReturnEnvel
import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema
import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution
import net.corda.serialization.internal.amqp.testutils.testName
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.assertj.core.api.Assertions
import org.junit.Test
import java.io.NotSerializableException
@ -205,7 +206,10 @@ class EnumTests {
}
}
val factory = SerializerFactory(WL(classTestName("C")), ClassLoader.getSystemClassLoader())
val whitelist = WL(classTestName("C"))
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
Assertions.assertThatThrownBy {
TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE))
@ -223,7 +227,10 @@ class EnumTests {
}
}
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader())
val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
// if it all works, this won't explode
TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE))
@ -237,7 +244,10 @@ class EnumTests {
override fun hasListed(type: Class<*>) = false
}
val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader())
val whitelist = WL()
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
// if it all works, this won't explode
TestSerializationOutput(VERBOSE, factory).serialize(C(AnnotatedBras.UNDERWIRE))
@ -252,14 +262,19 @@ class EnumTests {
}
// first serialise the class using a context in which Bras are whitelisted
val factory = SerializerFactory(WL(listOf(classTestName("C"),
"net.corda.serialization.internal.amqp.EnumTests\$Bras")),
ClassLoader.getSystemClassLoader())
val whitelist = WL(listOf(classTestName("C"),
"net.corda.serialization.internal.amqp.EnumTests\$Bras"))
val factory = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
val bytes = TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE))
// then take that serialised object and attempt to deserialize it in a context that
// disallows the Bras enum
val factory2 = SerializerFactory(WL(listOf(classTestName("C"))), ClassLoader.getSystemClassLoader())
val whitelist1 = WL(listOf(classTestName("C")))
val factory2 = SerializerFactoryBuilder.build(whitelist1,
ClassCarpenterImpl(whitelist1, ClassLoader.getSystemClassLoader())
)
Assertions.assertThatThrownBy {
DeserializationInput(factory2).deserialize(bytes)
}.isInstanceOf(NotSerializableException::class.java)

View File

@ -6,6 +6,7 @@ import kotlin.test.assertEquals
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
class FingerPrinterTesting : FingerPrinter {
private var index = 0
@ -39,11 +40,9 @@ class FingerPrinterTestingTests {
fun worksAsReplacement() {
data class C(val a: Int, val b: Long)
val factory = SerializerFactory(
AllWhitelist,
ClassLoader.getSystemClassLoader(),
evolutionSerializerProvider = FailIfEvolutionAttempted,
fingerPrinterConstructor = { _ -> FingerPrinterTesting() })
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
fingerPrinterProvider = { _ -> FingerPrinterTesting() })
val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L))

View File

@ -9,6 +9,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.serialization.SerializedBytes
import net.corda.serialization.internal.amqp.testutils.*
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import net.corda.testing.core.TestIdentity
import org.junit.Test
@ -120,8 +121,12 @@ class GenericsTests {
data class G(val a: Int)
data class Wrapper<T : Any>(val a: Int, val b: SerializedBytes<T>)
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val ser = SerializationOutput(factory)
val gBytes = ser.serialize(G(1))
@ -145,8 +150,12 @@ class GenericsTests {
data class Container<T>(val b: T)
data class Wrapper<T : Any>(val c: Container<T>)
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factories = listOf(factory, SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()))
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factories = listOf(factory, SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val ser = SerializationOutput(factory)
ser.serialize(Wrapper(Container(InnerA(1)))).apply {
@ -178,8 +187,12 @@ class GenericsTests {
data class Wrapper<T : Any>(val c: Container<T>)
val factorys = listOf(
SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()),
SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()))
SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
),
SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val ser = SerializationOutput(factorys[0])
@ -200,7 +213,9 @@ class GenericsTests {
private fun forceWildcardSerialize(
a: ForceWildcard<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())): SerializedBytes<*> {
factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)): SerializedBytes<*> {
val bytes = SerializationOutput(factory).serializeAndReturnSchema(a)
factory.serializersByDescriptor.printKeyToType()
bytes.printSchema()
@ -210,21 +225,27 @@ class GenericsTests {
@Suppress("UNCHECKED_CAST")
private fun forceWildcardDeserializeString(
bytes: SerializedBytes<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) {
factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)) {
DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<String>>)
}
@Suppress("UNCHECKED_CAST")
private fun forceWildcardDeserializeDouble(
bytes: SerializedBytes<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) {
factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)) {
DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<Double>>)
}
@Suppress("UNCHECKED_CAST")
private fun forceWildcardDeserialize(
bytes: SerializedBytes<*>,
factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) {
factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)) {
DeserializationInput(factory).deserialize(bytes as SerializedBytes<ForceWildcard<*>>)
}
@ -236,7 +257,9 @@ class GenericsTests {
@Test
fun forceWildcardSharedFactory() {
val f = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val f = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
forceWildcardDeserializeString(forceWildcardSerialize(ForceWildcard("hello"), f), f)
forceWildcardDeserializeDouble(forceWildcardSerialize(ForceWildcard(3.0), f), f)
}
@ -250,7 +273,9 @@ class GenericsTests {
@Test
fun forceWildcardDeserializeSharedFactory() {
val f = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val f = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard("hello"), f), f)
forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(10), f), f)
forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(20.0), f), f)
@ -288,7 +313,9 @@ class GenericsTests {
// possibly altering how we serialise things
val altClassLoader = cl()
val factory2 = SerializerFactory(AllWhitelist, altClassLoader)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, altClassLoader)
)
factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val ser2 = TestSerializationOutput(VERBOSE, factory2).serializeAndReturnSchema(state)
@ -297,7 +324,9 @@ class GenericsTests {
factory3.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
DeserializationInput(factory3).deserializeAndReturnEnvelope(ser1.obj)
val factory4 = SerializerFactory(AllWhitelist, cl())
val factory4 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, cl())
)
factory4.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
DeserializationInput(factory4).deserializeAndReturnEnvelope(ser2.obj)
}

View File

@ -5,6 +5,7 @@ import net.corda.serialization.internal.amqp.custom.OptionalSerializer
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.equalTo
import org.junit.Assert
@ -17,7 +18,9 @@ class OptionalSerializationTests {
fun setupEnclosedSerializationTest() {
@Test
fun `java optionals should serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(OptionalSerializer(factory))
val obj = Optional.ofNullable("YES")
val bytes = TestSerializationOutput(true, factory).serialize(obj)

View File

@ -17,15 +17,6 @@ import java.util.*
class PrivatePropertyTests {
private val factory = testDefaultFactoryNoEvolution()
companion object {
val fields : Map<String, java.lang.reflect.Field> = mapOf (
"serializersByDesc" to SerializerFactory::class.java.getDeclaredField("serializersByDescriptor")).apply {
this.values.forEach {
it.isAccessible = true
}
}
}
@Test
fun testWithOnePrivateProperty() {
data class C(private val b: String)
@ -134,8 +125,7 @@ class PrivatePropertyTests {
val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1)
assertEquals(1, schemaAndBlob.schema.types.size)
@Suppress("UNCHECKED_CAST")
val serializersByDescriptor = fields["serializersByDesc"]?.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>>
val serializersByDescriptor = factory.serializersByDescriptor
val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name
serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply {
@ -163,8 +153,7 @@ class PrivatePropertyTests {
val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1)
assertEquals(1, schemaAndBlob.schema.types.size)
@Suppress("UNCHECKED_CAST")
val serializersByDescriptor = fields["serializersByDesc"]?.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>>
val serializersByDescriptor = factory.serializersByDescriptor
val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name
serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply {
@ -192,7 +181,7 @@ class PrivatePropertyTests {
val output = SerializationOutput(factory).serializeAndReturnSchema(c1)
println (output.schema)
val serializersByDescriptor = fields["serializersByDesc"]!!.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>>
val serializersByDescriptor = factory.serializersByDescriptor
// Inner and Outer
assertEquals(2, serializersByDescriptor.size)
@ -212,7 +201,7 @@ class PrivatePropertyTests {
val output = SerializationOutput(factory).serializeAndReturnSchema(C("this is nice"))
val serializersByDescriptor = fields["serializersByDesc"]!!.get(factory) as ConcurrentHashMap<Any, AMQPSerializer<Any>>
val serializersByDescriptor = factory.serializersByDescriptor
val schemaDescriptor = output.schema.types.first().descriptor.name
serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply {

View File

@ -23,6 +23,7 @@ import net.corda.nodeapi.internal.crypto.ContentSignerBuilder
import net.corda.serialization.internal.*
import net.corda.serialization.internal.amqp.SerializerFactory.Companion.isPrimitive
import net.corda.serialization.internal.amqp.testutils.*
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.SerializationEnvironmentRule
@ -207,9 +208,8 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
}
private fun defaultFactory(): SerializerFactory {
return SerializerFactory(
AllWhitelist,
ClassLoader.getSystemClassLoader(),
return SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
evolutionSerializerProvider = FailIfEvolutionAttempted
)
}
@ -368,13 +368,17 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test(expected = NotSerializableException::class)
fun `test whitelist`() {
val obj = Woo2(4)
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()))
serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
}
@Test
fun `test annotation whitelisting`() {
val obj = AnnotatedWoo(5)
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()))
serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
}
@Test(expected = NotSerializableException::class)
@ -471,7 +475,9 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `class constructor is invoked on deserialisation`() {
compression == null || return // Manipulation of serialized bytes is invalid if they're compressed.
val ser = SerializationOutput(SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()))
val ser = SerializationOutput(SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val des = DeserializationInput(ser.serializerFactory)
val serialisedOne = ser.serialize(NonZeroByte(1), compression).bytes
val serialisedTwo = ser.serialize(NonZeroByte(2), compression).bytes
@ -496,9 +502,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test custom serializers on public key`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
val obj = MEGA_CORP_PUBKEY
serdes(obj, factory, factory2)
@ -507,21 +517,29 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test annotation is inherited`() {
val obj = InheritAnnotation("blah")
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()))
serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
}
@Test
fun `generics from java are supported`() {
val obj = DummyOptional<String>("YES")
serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()))
serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
))
}
@Test
fun `test throwables serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
val t = IllegalAccessException("message").fillInStackTrace()
@ -537,10 +555,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test complex throwables serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
try {
@ -567,10 +589,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test suppressed throwables serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
try {
@ -589,10 +615,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test flow corda exception subclasses serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
val obj = FlowException("message").fillInStackTrace()
@ -601,10 +631,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test RPC corda exception subclasses serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2))
val obj = RPCException("message").fillInStackTrace()
@ -666,10 +700,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
SerializerFactory::class.java)
func.isAccessible = true
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
func.invoke(scheme, testSerializationContext, factory)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
func.invoke(scheme, testSerializationContext, factory2)
val desState = serdes(state, factory, factory2, expectedEqual = false, expectDeserializedEqual = false)
@ -680,10 +718,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test currencies serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer)
val obj = Currency.getInstance("USD")
@ -692,10 +734,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test big decimals serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val obj = BigDecimal("100000000000000000000000000000.00")
@ -704,10 +750,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test instants serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory2))
val obj = Instant.now()
@ -716,10 +766,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test durations serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory2))
val obj = Duration.of(1000000L, ChronoUnit.MILLIS)
@ -728,10 +782,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test local date serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory2))
val obj = LocalDate.now()
@ -740,10 +798,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test local time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory2))
val obj = LocalTime.now()
@ -752,10 +814,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test local date time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory2))
val obj = LocalDateTime.now()
@ -764,10 +830,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test zoned date time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory2))
val obj = ZonedDateTime.now()
@ -776,10 +846,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test offset time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory2))
val obj = OffsetTime.now()
@ -788,10 +862,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test offset date time serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory2))
val obj = OffsetDateTime.now()
@ -800,10 +878,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test year serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory2))
val obj = Year.now()
@ -812,10 +894,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test year month serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory2))
val obj = YearMonth.now()
@ -824,10 +910,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test month day serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory2))
val obj = MonthDay.now()
@ -836,10 +926,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test period serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory2))
val obj = Period.of(99, 98, 97)
@ -866,10 +960,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test X509 certificate serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer)
val obj = BOB_IDENTITY.certificate
@ -878,10 +976,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test cert path serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory2))
val obj = BOB_IDENTITY.certPath
@ -905,9 +1007,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test StateRef serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val obj = StateRef(SecureHash.randomSHA256(), 0)
serdes(obj, factory, factory2)
@ -953,8 +1059,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
val b = ByteArray(2)
val obj = Bob(listOf(a, b, a))
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val obj2 = serdes(obj, factory, factory2, false, false)
assertNotSame(obj2.byteArrays[0], obj2.byteArrays[2])
@ -967,8 +1077,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
val a = listOf("a", "b")
val obj = Vic(a, a)
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val objCopy = serdes(obj, factory, factory2)
assertSame(objCopy.a, objCopy.b)
}
@ -984,8 +1098,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
fun `test private constructor`() {
val obj = Spike()
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
serdes(obj, factory, factory2)
}
@ -993,10 +1111,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test toString custom serializer`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val obj = BigDecimals(BigDecimal.TEN, BigDecimal.TEN)
@ -1008,10 +1130,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test BigInteger custom serializer`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer)
val obj = BigIntegers(BigInteger.TEN, BigInteger.TEN)
@ -1028,10 +1154,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test X509CRL custom serializer`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer)
val obj = emptyCrl()
@ -1042,10 +1172,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test byte arrays not reference counted`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer)
val bytes = ByteArray(1)
@ -1056,10 +1190,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test StringBuffer serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer)
val obj = StringBuffer("Bob")
@ -1069,10 +1207,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test SimpleString serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer)
val obj = SimpleString("Bob")
@ -1093,10 +1235,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test InputStream serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer)
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer)
val bytes = ByteArray(10) { it.toByte() }
val obj = bytes.inputStream()
@ -1108,10 +1254,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test EnumSet serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory2))
val obj = EnumSet.of(Month.APRIL, Month.AUGUST)
@ -1120,10 +1270,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test BitSet serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory2))
val obj = BitSet.valueOf(kotlin.ByteArray(16) { it.toByte() }).get(0, 123)
@ -1140,10 +1294,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test contract attachment serialize`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2))
val obj = ContractAttachment(GeneratedAttachment("test".toByteArray()), DummyContract.PROGRAM_ID)
@ -1156,10 +1314,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `test contract attachment throws if missing attachment`() {
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory))
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val factory2 = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2))
val obj = ContractAttachment(object : AbstractAttachment({ throw Exception() }) {
@ -1351,7 +1513,9 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test
fun `compression reduces number of bytes significantly`() {
val ser = SerializationOutput(SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()))
val ser = SerializationOutput(SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
))
val obj = ByteArray(20000)
val uncompressedSize = ser.serialize(obj).bytes.size
val compressedSize = ser.serialize(obj, CordaSerializationEncoding.SNAPPY).bytes.size

View File

@ -102,14 +102,13 @@ class SerializationPropertyOrdering {
// Test needs to look at a bunch of private variables, change the access semantics for them
val fields : Map<String, java.lang.reflect.Field> = mapOf (
"serializersByDesc" to SerializerFactory::class.java.getDeclaredField("serializersByDescriptor"),
"setter" to PropertyAccessorGetterSetter::class.java.getDeclaredField("setter")).apply {
this.values.forEach {
it.isAccessible = true
}
}
val serializersByDescriptor = fields["serializersByDesc"]!!.get(sf) as ConcurrentHashMap<Any, AMQPSerializer<Any>>
val serializersByDescriptor = sf.serializersByDescriptor
val schemaDescriptor = output.schema.types.first().descriptor.name
// make sure that each property accessor has a setter to ensure we're using getter / setter instantiation

View File

@ -6,6 +6,7 @@ import net.corda.serialization.internal.BuiltInExceptionsWhitelist
import net.corda.serialization.internal.CordaSerializationMagic
import net.corda.serialization.internal.GlobalTransientClassWhiteList
import net.corda.serialization.internal.SerializationContextImpl
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.junit.Test
import kotlin.test.assertEquals
@ -22,7 +23,7 @@ val TESTING_CONTEXT = SerializationContextImpl(amqpMagic,
class TestSerializerFactory(
wl: ClassWhitelist,
cl: ClassLoader
) : SerializerFactory(wl, cl) {
) : DefaultSerializerFactory(wl, ClassCarpenterImpl(wl, cl, false), DefaultEvolutionSerializerProvider, ::SerializerFingerPrinter) {
var registerCount = 0
override fun register(customSerializer: CustomSerializer<out Any>) {

View File

@ -48,7 +48,9 @@ class StaticInitialisationOfSerializedObjectTest {
fun kotlinObjectWithCompanionObject() {
data class D(val c: C)
val sf = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
val sf = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
val typeMap = sf::class.java.getDeclaredField("serializersByType")
typeMap.isAccessible = true
@ -87,7 +89,10 @@ class StaticInitialisationOfSerializedObjectTest {
".StaticInitialisationOfSerializedObjectTest\$deserializeTest\$D"
}
val sf2 = SerializerFactory(WL(), ClassLoader.getSystemClassLoader())
val whitelist = WL()
val sf2 = SerializerFactoryBuilder.build(whitelist,
ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader())
)
val bytes = url.readBytes()
assertThatThrownBy {
@ -97,8 +102,8 @@ class StaticInitialisationOfSerializedObjectTest {
// Version of a serializer factory that will allow the class carpenter living on the
// factory to have a different whitelist applied to it than the factory
class TestSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) :
SerializerFactory(wl1, ClassCarpenterImpl(wl2, ClassLoader.getSystemClassLoader()))
private fun testSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) =
SerializerFactoryBuilder.build(wl1, ClassCarpenterImpl(wl2, ClassLoader.getSystemClassLoader()))
// This time have the serialization factory and the carpenter use different whitelists
@Test
@ -126,7 +131,7 @@ class StaticInitialisationOfSerializedObjectTest {
override fun hasListed(type: Class<*>) = true
}
val sf2 = TestSerializerFactory(WL1(), WL2())
val sf2 = testSerializerFactory(WL1(), WL2())
val bytes = url.readBytes()
// Deserializing should throw because C is not on the whitelist NOT because

View File

@ -10,6 +10,7 @@ import net.corda.core.utilities.OpaqueBytes
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.EmptyWhitelist
import net.corda.serialization.internal.amqp.*
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import net.corda.testing.common.internal.ProjectStructure
import org.apache.qpid.proton.codec.Data
import org.junit.Test
@ -17,16 +18,20 @@ import java.io.File.separatorChar
import java.io.NotSerializableException
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
fun testDefaultFactory() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
fun testDefaultFactory() = SerializerFactoryBuilder.build(AllWhitelist,
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader())
)
fun testDefaultFactoryNoEvolution(): SerializerFactory {
return SerializerFactory(
return SerializerFactoryBuilder.build(
AllWhitelist,
ClassLoader.getSystemClassLoader(),
evolutionSerializerProvider = FailIfEvolutionAttempted)
ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()),
FailIfEvolutionAttempted)
}
fun testDefaultFactoryWithWhitelist() = SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())
fun testDefaultFactoryWithWhitelist() = SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
)
class TestSerializationOutput(
private val verbose: Boolean,

View File

@ -5,7 +5,6 @@ import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.*
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.serialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import org.assertj.core.api.Assertions
import org.junit.Test
@ -33,8 +32,8 @@ interface TestInterface {
// Create a custom serialization factory where we need to be able to both specify a carpenter
// but also have the class loader used by the carpenter be substantially different from the
// one used by the factory so as to ensure we can control their behaviour independently.
class TestFactory(classCarpenter: ClassCarpenter)
: SerializerFactory(classCarpenter.whitelist, classCarpenter)
private fun testFactory(classCarpenter: ClassCarpenter)
= SerializerFactoryBuilder.build(classCarpenter.whitelist, classCarpenter)
class CarpenterExceptionTests {
companion object {
@ -90,7 +89,7 @@ class CarpenterExceptionTests {
// we set the class loader of the ClassCarpenter to reject one of them, resulting in a CarpentryError
// which we then want the code to wrap in a NotSerializeableException
val cc = ClassCarpenterImpl(AllWhitelist, TestClassLoader(listOf(C2::class.jvmName)))
val factory = TestFactory(cc)
val factory = testFactory(cc)
Assertions.assertThatThrownBy {
DeserializationInput(factory).deserialize(ser)

View File

@ -41,12 +41,12 @@ fun Schema.mangleNames(names: List<String>): Schema {
* Custom implementation of a [SerializerFactory] where we need to give it a class carpenter
* rather than have it create its own
*/
class SerializerFactoryExternalCarpenter(classCarpenter: ClassCarpenter)
: SerializerFactory(classCarpenter.whitelist, classCarpenter)
private fun serializerFactoryExternalCarpenter(classCarpenter: ClassCarpenter)
= SerializerFactoryBuilder.build(classCarpenter.whitelist, classCarpenter)
open class AmqpCarpenterBase(whitelist: ClassWhitelist) {
var cc = ClassCarpenterImpl(whitelist = whitelist)
var factory = SerializerFactoryExternalCarpenter(cc)
var factory = serializerFactoryExternalCarpenter(cc)
fun <T: Any> serialise(obj: T): SerializedBytes<T> = SerializationOutput(factory).serialize(obj)
@Suppress("NOTHING_TO_INLINE")

View File

@ -2,17 +2,15 @@ package net.corda.cliutils
import net.corda.core.internal.rootMessage
import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.loggerFor
import org.fusesource.jansi.AnsiConsole
import org.slf4j.event.Level
import picocli.CommandLine
import picocli.CommandLine.*
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.system.exitProcess
import java.util.*
import java.util.concurrent.Callable
import kotlin.system.exitProcess
/**
* When we have errors in command line flags that are not handled by picocli (e.g. non existing files), an error is thrown
@ -64,18 +62,6 @@ fun CordaCliWrapper.start(args: Array<String>) {
// This line makes sure ANSI escapes work on Windows, where they aren't supported out of the box.
AnsiConsole.systemInstall()
val cmd = CommandLine(this)
// Make sure any provided paths are absolute. Relative paths have caused issues and are less clear in logs.
cmd.registerConverter(Path::class.java) { Paths.get(it).toAbsolutePath().normalize() }
cmd.commandSpec.name(alias)
cmd.commandSpec.usageMessage().description(description)
this.subCommands().forEach {
val subCommand = CommandLine(it)
it.args = args
subCommand.commandSpec.usageMessage().description(it.description)
cmd.commandSpec.addSubcommand(it.alias, subCommand)
}
try {
val defaultAnsiMode = if (CordaSystemUtils.isOsWindows()) {
Help.Ansi.ON
@ -97,7 +83,7 @@ fun CordaCliWrapper.start(args: Array<String>) {
exitProcess(ExitCodes.SUCCESS)
} catch (e: ExecutionException) {
val throwable = e.cause ?: e
if (this.verbose || this.subCommands().any { it.verbose} ) {
if (this.verbose || this.subCommands().any { it.verbose }) {
throwable.printStackTrace()
} else {
System.err.println("*ERROR*: ${throwable.rootMessage ?: "Use --verbose for more details"}")
@ -171,6 +157,21 @@ abstract class CordaCliWrapper(alias: String, description: String) : CliWrapperB
protected open fun additionalSubCommands(): Set<CliWrapperBase> = emptySet()
val cmd by lazy {
CommandLine(this).apply {
// Make sure any provided paths are absolute. Relative paths have caused issues and are less clear in logs.
registerConverter(Path::class.java) { Paths.get(it).toAbsolutePath().normalize() }
commandSpec.name(alias)
commandSpec.usageMessage().description(description)
subCommands().forEach {
val subCommand = CommandLine(it)
it.args = args
subCommand.commandSpec.usageMessage().description(it.description)
commandSpec.addSubcommand(it.alias, subCommand)
}
}
}
fun subCommands(): Set<CliWrapperBase> {
return additionalSubCommands() + installShellExtensionsParser
}
@ -181,6 +182,8 @@ abstract class CordaCliWrapper(alias: String, description: String) : CliWrapperB
installShellExtensionsParser.updateShellExtensions()
return runProgram()
}
fun printHelp() = cmd.usage(System.out)
}
/**

View File

@ -29,7 +29,7 @@ class InteractiveShellTest {
@Suppress("UNUSED")
class FlowA(val a: String) : FlowLogic<String>() {
constructor(b: Int) : this(b.toString())
constructor(b: Int?) : this(b.toString())
constructor(b: Int?, c: String) : this(b.toString() + c)
constructor(amount: Amount<Currency>) : this(amount.toString())
constructor(pair: Pair<Amount<Currency>, SecureHash.SHA256>) : this(pair.toString())
@ -115,7 +115,7 @@ class InteractiveShellTest {
"[b: String[]]: missing parameter b",
"[b: Integer, c: String]: missing parameter b",
"[a: String]: missing parameter a",
"[b: int]: missing parameter b"
"[b: Integer]: missing parameter b"
)
val errors = e.errors.toHashSet()
errors.removeAll(correct)