Remove Kryo from core module completely, including gradle dependencies (#1161)

This commit is contained in:
Rick Parker 2017-08-09 14:53:46 +01:00 committed by GitHub
parent f81f374377
commit 28610868c4
84 changed files with 450 additions and 387 deletions

View File

@ -9,9 +9,9 @@ import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.ArtemisTcpTransport.Companion.tcpTransport
import net.corda.nodeapi.ConnectionDirection
import net.corda.nodeapi.config.SSLConfiguration
import net.corda.nodeapi.serialization.KRYO_P2P_CONTEXT
import net.corda.nodeapi.serialization.KRYO_RPC_CLIENT_CONTEXT
import net.corda.nodeapi.serialization.SerializationFactoryImpl
import net.corda.nodeapi.internal.serialization.KRYO_P2P_CONTEXT
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
import java.time.Duration
/** @see RPCClient.RPCConnection */

View File

@ -2,12 +2,12 @@ package net.corda.client.rpc.serialization
import com.esotericsoftware.kryo.pool.KryoPool
import net.corda.client.rpc.internal.RpcClientObservableSerializer
import net.corda.core.serialization.DefaultKryoCustomizer
import net.corda.core.serialization.SerializationContext
import net.corda.core.utilities.ByteSequence
import net.corda.nodeapi.RPCKryo
import net.corda.nodeapi.serialization.AbstractKryoSerializationScheme
import net.corda.nodeapi.serialization.KryoHeaderV0_1
import net.corda.nodeapi.internal.serialization.AbstractKryoSerializationScheme
import net.corda.nodeapi.internal.serialization.DefaultKryoCustomizer
import net.corda.nodeapi.internal.serialization.KryoHeaderV0_1
class KryoClientSerializationScheme : AbstractKryoSerializationScheme() {
override fun canDeserializeVersion(byteSequence: ByteSequence, target: SerializationContext.UseCase): Boolean {

View File

@ -53,10 +53,6 @@ dependencies {
// RxJava: observable streams of events.
compile "io.reactivex:rxjava:$rxjava_version"
// Kryo: object graph serialization.
compile "com.esotericsoftware:kryo:4.0.0"
compile "de.javakaffee:kryo-serializers:0.41"
// Apache JEXL: An embeddable expression evaluation library.
// This may be temporary until we experiment with other ways to do on-the-fly contract specialisation via an API.
compile "org.apache.commons:commons-jexl3:3.0"

View File

@ -58,9 +58,9 @@ open class CordaException internal constructor(override var originalExceptionCla
}
}
open class CordaRuntimeException internal constructor(override var originalExceptionClassName: String?,
private var _message: String? = null,
private var _cause: Throwable? = null) : RuntimeException(null, null, true, true), CordaThrowable {
open class CordaRuntimeException(override var originalExceptionClassName: String?,
private var _message: String? = null,
private var _cause: Throwable? = null) : RuntimeException(null, null, true, true), CordaThrowable {
constructor(message: String?, cause: Throwable?) : this(null, message, cause)
override val message: String?

View File

@ -283,7 +283,7 @@ object Crypto {
/**
* Decode a PKCS8 encoded key to its [PrivateKey] object based on the input scheme code name.
* This should be used when the type key is known, e.g. during Kryo deserialisation or with key caches or key managers.
* This should be used when the type key is known, e.g. during deserialisation or with key caches or key managers.
* @param schemeCodeName a [String] that should match a key in supportedSignatureSchemes map (e.g. ECDSA_SECP256K1_SHA256).
* @param encodedKey a PKCS8 encoded private key.
* @throws IllegalArgumentException on not supported scheme or if the given key specification
@ -294,7 +294,7 @@ object Crypto {
/**
* Decode a PKCS8 encoded key to its [PrivateKey] object based on the input scheme code name.
* This should be used when the type key is known, e.g. during Kryo deserialisation or with key caches or key managers.
* This should be used when the type key is known, e.g. during deserialisation or with key caches or key managers.
* @param signatureScheme a signature scheme (e.g. ECDSA_SECP256K1_SHA256).
* @param encodedKey a PKCS8 encoded private key.
* @throws IllegalArgumentException on not supported scheme or if the given key specification
@ -326,7 +326,7 @@ object Crypto {
/**
* Decode an X509 encoded key to its [PrivateKey] object based on the input scheme code name.
* This should be used when the type key is known, e.g. during Kryo deserialisation or with key caches or key managers.
* This should be used when the type key is known, e.g. during deserialisation or with key caches or key managers.
* @param schemeCodeName a [String] that should match a key in supportedSignatureSchemes map (e.g. ECDSA_SECP256K1_SHA256).
* @param encodedKey an X509 encoded public key.
* @throws IllegalArgumentException if the requested scheme is not supported.
@ -338,7 +338,7 @@ object Crypto {
/**
* Decode an X509 encoded key to its [PrivateKey] object based on the input scheme code name.
* This should be used when the type key is known, e.g. during Kryo deserialisation or with key caches or key managers.
* This should be used when the type key is known, e.g. during deserialisation or with key caches or key managers.
* @param signatureScheme a signature scheme (e.g. ECDSA_SECP256K1_SHA256).
* @param encodedKey an X509 encoded public key.
* @throws IllegalArgumentException if the requested scheme is not supported.

View File

@ -60,7 +60,7 @@ fun String.hexToBase58(): String = hexToByteArray().toBase58()
/** Encoding changer. Hex-[String] to Base64-[String], i.e. "48656C6C6F20576F726C64" -> "SGVsbG8gV29ybGQ=" */
fun String.hexToBase64(): String = hexToByteArray().toBase64()
// TODO We use for both CompositeKeys and EdDSAPublicKey custom Kryo serializers and deserializers. We need to specify encoding.
// TODO We use for both CompositeKeys and EdDSAPublicKey custom serializers and deserializers. We need to specify encoding.
// TODO: follow the crypto-conditions ASN.1 spec, some changes are needed to be compatible with the condition
// structure, e.g. mapping a PublicKey to a condition with the specific feature (ED25519).
fun parsePublicKeyBase58(base58String: String): PublicKey = base58String.base58ToByteArray().deserialize<PublicKey>()

View File

@ -5,7 +5,7 @@ import net.corda.core.serialization.CordaSerializable
/**
* Custom class for holding signature data. This exists for later extension work to provide a standardised cross-platform
* serialization format (i.e. not Kryo).
* serialization format.
*/
@CordaSerializable
data class CompositeSignaturesWithKeys(val sigs: List<TransactionSignature>) {

View File

@ -1,12 +1,12 @@
package net.corda.core.node
import net.corda.core.contracts.ContractState
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.services.VaultQueryService
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.QueryableState
import net.corda.core.serialization.SerializationCustomization
import java.util.function.Function
import net.corda.core.schemas.QueryableState
import net.corda.core.contracts.ContractState
import net.corda.core.node.services.VaultQueryService
/**
* Implement this interface on a class advertised in a META-INF/services/net.corda.core.node.CordaPluginRegistry file

View File

@ -2,7 +2,6 @@ package net.corda.core.node.services
import net.corda.core.contracts.PartyAndReference
import net.corda.core.identity.*
import net.corda.core.identity.AnonymousPartyAndPath
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.cert.X509CertificateHolder
import java.security.InvalidAlgorithmParameterException

View File

@ -4,9 +4,9 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.contracts.Contract
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.internal.randomOrNull
import net.corda.core.messaging.DataFeed
import net.corda.core.node.NodeInfo
import net.corda.core.internal.randomOrNull
import net.corda.core.serialization.CordaSerializable
import org.bouncycastle.asn1.x500.X500Name
import rx.Observable

View File

@ -0,0 +1,7 @@
package net.corda.core.serialization
import net.corda.core.crypto.SecureHash
/** Thrown during deserialisation to indicate that an attachment needed to construct the [WireTransaction] is not found */
@CordaSerializable
class MissingAttachmentsException(val ids: List<SecureHash>) : Exception()

View File

@ -5,7 +5,6 @@ import net.corda.core.crypto.sha256
import net.corda.core.internal.WriteOnceProperty
import net.corda.core.serialization.SerializationDefaults.P2P_CONTEXT
import net.corda.core.serialization.SerializationDefaults.SERIALIZATION_FACTORY
import net.corda.core.transactions.WireTransaction
import net.corda.core.utilities.ByteSequence
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.sequence
@ -135,3 +134,7 @@ class SerializedBytes<T : Any>(bytes: ByteArray) : OpaqueBytes(bytes) {
// It's OK to use lazy here because SerializedBytes is configured to use the ImmutableClassSerializer.
val hash: SecureHash by lazy { bytes.sha256() }
}
interface ClassWhitelist {
fun hasListed(type: Class<*>): Boolean
}

View File

@ -1,13 +1,6 @@
package net.corda.core.serialization
import com.esotericsoftware.kryo.Kryo
interface SerializationCustomization {
fun addToWhitelist(type: Class<*>)
}
class KryoSerializationCustomization(val kryo: Kryo) : SerializationCustomization {
override fun addToWhitelist(type: Class<*>) {
kryo.addToWhitelist(type)
}
}

View File

@ -1,11 +1,5 @@
package net.corda.core.serialization
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoException
import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import net.corda.core.internal.castIfPossible
import net.corda.core.node.ServiceHub
import net.corda.core.serialization.SingletonSerializationToken.Companion.singletonSerializationToken
@ -36,70 +30,13 @@ interface SerializationToken {
fun fromToken(context: SerializeAsTokenContext): Any
}
/**
* A Kryo serializer for [SerializeAsToken] implementations.
*/
class SerializeAsTokenSerializer<T : SerializeAsToken> : Serializer<T>() {
override fun write(kryo: Kryo, output: Output, obj: T) {
kryo.writeClassAndObject(output, obj.toToken(kryo.serializationContext() ?: throw KryoException("Attempt to write a ${SerializeAsToken::class.simpleName} instance of ${obj.javaClass.name} without initialising a context")))
}
override fun read(kryo: Kryo, input: Input, type: Class<T>): T {
val token = (kryo.readClassAndObject(input) as? SerializationToken) ?: throw KryoException("Non-token read for tokenized type: ${type.name}")
val fromToken = token.fromToken(kryo.serializationContext() ?: throw KryoException("Attempt to read a token for a ${SerializeAsToken::class.simpleName} instance of ${type.name} without initialising a context"))
return type.castIfPossible(fromToken) ?: throw KryoException("Token read ($token) did not return expected tokenized type: ${type.name}")
}
}
private val serializationContextKey = SerializeAsTokenContext::class.java
fun SerializationContext.withTokenContext(serializationContext: SerializeAsTokenContext): SerializationContext = this.withProperty(serializationContextKey, serializationContext)
fun Kryo.serializationContext(): SerializeAsTokenContext? = context.get(serializationContextKey) as? SerializeAsTokenContext
/**
* A context for mapping SerializationTokens to/from SerializeAsTokens.
*
* A context is initialised with an object containing all the instances of [SerializeAsToken] to eagerly register all the tokens.
* In our case this can be the [ServiceHub].
*
* Then it is a case of using the companion object methods on [SerializeAsTokenSerializer] to set and clear context as necessary
* on the Kryo instance when serializing to enable/disable tokenization.
*/
class SerializeAsTokenContext internal constructor(val serviceHub: ServiceHub, init: SerializeAsTokenContext.() -> Unit) {
constructor(toBeTokenized: Any, serializationFactory: SerializationFactory, context: SerializationContext, serviceHub: ServiceHub) : this(serviceHub, {
serializationFactory.serialize(toBeTokenized, context.withTokenContext(this))
})
private val classNameToSingleton = mutableMapOf<String, SerializeAsToken>()
private var readOnly = false
init {
/**
* Go ahead and eagerly serialize the object to register all of the tokens in the context.
*
* This results in the toToken() method getting called for any [SingletonSerializeAsToken] instances which
* are encountered in the object graph as they are serialized by Kryo and will therefore register the token to
* object mapping for those instances. We then immediately set the readOnly flag to stop further adhoc or
* accidental registrations from occuring as these could not be deserialized in a deserialization-first
* scenario if they are not part of this iniital context construction serialization.
*/
init(this)
readOnly = true
}
internal fun putSingleton(toBeTokenized: SerializeAsToken) {
val className = toBeTokenized.javaClass.name
if (className !in classNameToSingleton) {
// Only allowable if we are in SerializeAsTokenContext init (readOnly == false)
if (readOnly) {
throw UnsupportedOperationException("Attempt to write token for lazy registered ${className}. All tokens should be registered during context construction.")
}
classNameToSingleton[className] = toBeTokenized
}
}
internal fun getSingleton(className: String) = classNameToSingleton[className] ?: throw IllegalStateException("Unable to find tokenized instance of $className in context $this")
interface SerializeAsTokenContext {
val serviceHub: ServiceHub
fun putSingleton(toBeTokenized: SerializeAsToken)
fun getSingleton(className: String): SerializeAsToken
}
/**

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp;
package net.corda.nodeapi.internal.serialization.amqp;
import net.corda.core.serialization.SerializedBytes;
import org.apache.qpid.proton.codec.DecoderImpl;

View File

@ -86,7 +86,7 @@ class CompositeKeyTests : TestDependencyInjectionBase() {
}
@Test
fun `kryo encoded tree decodes correctly`() {
fun `encoded tree decodes correctly`() {
val aliceAndBob = CompositeKey.Builder().addKeys(alicePublicKey, bobPublicKey).build()
val aliceAndBobOrCharlie = CompositeKey.Builder().addKeys(aliceAndBob, charliePublicKey).build(threshold = 1)

View File

@ -1,6 +1,6 @@
package net.corda.core.crypto
import com.esotericsoftware.kryo.KryoException
import net.corda.contracts.asset.Cash
import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash.Companion.zeroHash
@ -232,7 +232,7 @@ class PartialMerkleTreeTest : TestDependencyInjectionBase() {
assertFalse(pmt.verify(wrongRoot, inclHashes))
}
@Test(expected = KryoException::class)
@Test(expected = Exception::class)
fun `hash map serialization not allowed`() {
val hm1 = hashMapOf("a" to 1, "b" to 2, "c" to 3, "e" to 4)
hm1.serialize()

View File

@ -1,6 +1,6 @@
package net.corda.core.node
import org.junit.Assert.*
import org.junit.Assert.assertEquals
import org.junit.Test
class CityDatabaseTest {

View File

@ -1,10 +1,8 @@
package net.corda.core.node
import net.corda.core.crypto.X509Utilities
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.ServiceType
import net.corda.testing.getTestX509Name
import org.bouncycastle.asn1.x500.X500Name
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith

View File

@ -1,16 +1,5 @@
package net.corda.core.utilities
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoSerializable
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import net.corda.core.serialization.AllWhitelist
import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.serialize
import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.nodeapi.serialization.KryoHeaderV0_1
import net.corda.nodeapi.serialization.SerializationContextImpl
import net.corda.nodeapi.serialization.SerializationFactoryImpl
import org.junit.Before
import org.junit.Test
import java.util.*
@ -99,34 +88,4 @@ class ProgressTrackerTest {
pt.currentStep = SimpleSteps.ONE
assertEquals(SimpleSteps.TWO, pt.nextStep())
}
@Test
fun rxSubscriptionsAreNotSerialized() {
class Unserializable : KryoSerializable {
override fun write(kryo: Kryo?, output: Output?) = throw AssertionError("not called")
override fun read(kryo: Kryo?, input: Input?) = throw AssertionError("not called")
fun foo() {
println("bar")
}
}
pt.setChildProgressTracker(SimpleSteps.TWO, pt2)
class Tmp {
val unserializable = Unserializable()
init {
pt2.changes.subscribe { unserializable.foo() }
}
}
Tmp()
val factory = SerializationFactoryImpl().apply { registerScheme(KryoServerSerializationScheme()) }
val context = SerializationContextImpl(KryoHeaderV0_1,
javaClass.classLoader,
AllWhitelist,
emptyMap(),
true,
SerializationContext.UseCase.P2P)
pt.serialize(factory, context)
}
}

View File

@ -6,12 +6,11 @@ import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder
// The dummy contract doesn't do anything useful. It exists for testing purposes.
import net.corda.nodeapi.DummyContractBackdoor
val ANOTHER_DUMMY_PROGRAM_ID = AnotherDummyContract()
class AnotherDummyContract : Contract, net.corda.core.node.DummyContractBackdoor {
class AnotherDummyContract : Contract, DummyContractBackdoor {
data class State(val magicNumber: Int = 0) : ContractState {
override val contract = ANOTHER_DUMMY_PROGRAM_ID
override val participants: List<AbstractParty>

View File

@ -1,4 +1,4 @@
package net.corda.core.node
package net.corda.nodeapi
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.PartyAndReference

View File

@ -27,6 +27,10 @@ dependencies {
// TypeSafe Config: for simple and human friendly config files.
compile "com.typesafe:config:$typesafe_config_version"
// Kryo: object graph serialization.
compile "com.esotericsoftware:kryo:4.0.0"
compile "de.javakaffee:kryo-serializers:0.41"
// Unit testing helpers.
testCompile "junit:junit:$junit_version"
testCompile "org.assertj:assertj-core:${assertj_version}"

View File

@ -6,10 +6,12 @@ import com.esotericsoftware.kryo.Registration
import com.esotericsoftware.kryo.Serializer
import net.corda.core.concurrent.CordaFuture
import net.corda.core.CordaRuntimeException
import net.corda.core.serialization.*
import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.CordaSerializable
import net.corda.core.toFuture
import net.corda.core.toObservable
import net.corda.nodeapi.config.OldConfig
import net.corda.nodeapi.internal.serialization.*
import rx.Observable
import java.io.InputStream

View File

@ -1,12 +1,22 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import net.corda.core.serialization.ClassWhitelist
import sun.misc.Unsafe
import sun.security.util.Password
import java.io.*
import java.lang.invoke.*
import java.lang.reflect.*
import java.net.*
import java.security.*
import java.lang.reflect.AccessibleObject
import java.lang.reflect.Modifier
import java.lang.reflect.Parameter
import java.lang.reflect.ReflectPermission
import java.net.DatagramSocket
import java.net.ServerSocket
import java.net.Socket
import java.net.URLConnection
import java.security.AccessController
import java.security.KeyStore
import java.security.Permission
import java.security.Provider
import java.sql.Connection
import java.util.*
import java.util.logging.Handler

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.*
import com.esotericsoftware.kryo.io.Input
@ -6,6 +6,9 @@ import com.esotericsoftware.kryo.io.Output
import com.esotericsoftware.kryo.serializers.FieldSerializer
import com.esotericsoftware.kryo.util.DefaultClassResolver
import com.esotericsoftware.kryo.util.Util
import net.corda.core.serialization.AttachmentsClassLoader
import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.loggerFor
import java.io.PrintWriter
import java.lang.reflect.Modifier.isAbstract
@ -145,10 +148,6 @@ class CordaClassResolver(val whitelist: ClassWhitelist, val amqpEnabled: Boolean
}
}
interface ClassWhitelist {
fun hasListed(type: Class<*>): Boolean
}
interface MutableClassWhitelist : ClassWhitelist {
fun add(entry: Class<*>)
}

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.Serializer
@ -13,6 +13,8 @@ import de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer
import de.javakaffee.kryoserializers.guava.*
import net.corda.core.crypto.composite.CompositeKey
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.serialization.SerializeAsToken
import net.corda.core.serialization.SerializedBytes
import net.corda.core.transactions.NotaryChangeWireTransaction
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.WireTransaction
@ -32,6 +34,7 @@ import org.objenesis.instantiator.ObjectInstantiator
import org.objenesis.strategy.InstantiatorStrategy
import org.objenesis.strategy.StdInstantiatorStrategy
import org.slf4j.Logger
import sun.security.ec.ECPublicKeyImpl
import sun.security.provider.certpath.X509CertPath
import java.io.BufferedInputStream
import java.io.FileInputStream
@ -82,7 +85,7 @@ object DefaultKryoCustomizer {
noReferencesWithin<WireTransaction>()
register(sun.security.ec.ECPublicKeyImpl::class.java, ECPublicKeyImplSerializer)
register(ECPublicKeyImpl::class.java, ECPublicKeyImplSerializer)
register(EdDSAPublicKey::class.java, Ed25519PublicKeySerializer)
register(EdDSAPrivateKey::class.java, Ed25519PrivateKeySerializer)

View File

@ -1,4 +1,4 @@
package net.corda.nodeapi.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.KryoException
import net.corda.core.node.CordaPluginRegistry

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.*
import com.esotericsoftware.kryo.io.Input
@ -11,6 +11,10 @@ import net.corda.core.crypto.TransactionSignature
import net.corda.core.crypto.composite.CompositeKey
import net.corda.core.identity.Party
import net.corda.core.internal.VisibleForTesting
import net.corda.core.serialization.AttachmentsClassLoader
import net.corda.core.serialization.MissingAttachmentsException
import net.corda.core.serialization.SerializeAsTokenContext
import net.corda.core.serialization.SerializedBytes
import net.corda.core.transactions.CoreTransaction
import net.corda.core.transactions.NotaryChangeWireTransaction
import net.corda.core.transactions.SignedTransaction
@ -25,6 +29,8 @@ import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.cert.X509CertificateHolder
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import sun.security.ec.ECPublicKeyImpl
import sun.security.util.DerValue
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.lang.reflect.InvocationTargetException
@ -229,10 +235,6 @@ fun Input.readBytesWithLength(): ByteArray {
return this.readBytes(size)
}
/** Thrown during deserialisation to indicate that an attachment needed to construct the [WireTransaction] is not found */
@CordaSerializable
class MissingAttachmentsException(val ids: List<SecureHash>) : Exception()
/** A serialisation engine that knows how to deserialise code inside a sandbox */
@ThreadSafe
object WireTransactionSerializer : Serializer<WireTransaction>() {
@ -343,15 +345,15 @@ object Ed25519PublicKeySerializer : Serializer<EdDSAPublicKey>() {
/** For serialising an ed25519 public key */
@ThreadSafe
object ECPublicKeyImplSerializer : Serializer<sun.security.ec.ECPublicKeyImpl>() {
override fun write(kryo: Kryo, output: Output, obj: sun.security.ec.ECPublicKeyImpl) {
object ECPublicKeyImplSerializer : Serializer<ECPublicKeyImpl>() {
override fun write(kryo: Kryo, output: Output, obj: ECPublicKeyImpl) {
output.writeBytesWithLength(obj.encoded)
}
override fun read(kryo: Kryo, input: Input, type: Class<sun.security.ec.ECPublicKeyImpl>): sun.security.ec.ECPublicKeyImpl {
override fun read(kryo: Kryo, input: Input, type: Class<ECPublicKeyImpl>): ECPublicKeyImpl {
val A = input.readBytesWithLength()
val der = sun.security.util.DerValue(A)
return sun.security.ec.ECPublicKeyImpl.parse(der) as sun.security.ec.ECPublicKeyImpl
val der = DerValue(A)
return ECPublicKeyImpl.parse(der) as ECPublicKeyImpl
}
}
@ -562,3 +564,5 @@ object X509CertificateSerializer : Serializer<X509CertificateHolder>() {
output.writeBytes(obj.encoded)
}
}
fun Kryo.serializationContext(): SerializeAsTokenContext? = context.get(serializationContextKey) as? SerializeAsTokenContext

View File

@ -1,12 +1,13 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import net.corda.core.serialization.amqp.DeserializationInput
import net.corda.core.serialization.amqp.SerializationOutput
import net.corda.core.serialization.amqp.SerializerFactory
import net.corda.core.serialization.SerializedBytes
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
import net.corda.nodeapi.internal.serialization.amqp.SerializationOutput
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory
/**
* This [Kryo] custom [Serializer] switches the object graph of anything annotated with `@CordaSerializable`
@ -17,12 +18,12 @@ import net.corda.core.serialization.amqp.SerializerFactory
object KryoAMQPSerializer : Serializer<Any>() {
internal fun registerCustomSerializers(factory: SerializerFactory) {
factory.apply {
register(net.corda.core.serialization.amqp.custom.PublicKeySerializer)
register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(this))
register(net.corda.core.serialization.amqp.custom.X500NameSerializer)
register(net.corda.core.serialization.amqp.custom.BigDecimalSerializer)
register(net.corda.core.serialization.amqp.custom.CurrencySerializer)
register(net.corda.core.serialization.amqp.custom.InstantSerializer(this))
register(net.corda.nodeapi.internal.serialization.amqp.custom.PublicKeySerializer)
register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(this))
register(net.corda.nodeapi.internal.serialization.amqp.custom.X500NameSerializer)
register(net.corda.nodeapi.internal.serialization.amqp.custom.BigDecimalSerializer)
register(net.corda.nodeapi.internal.serialization.amqp.custom.CurrencySerializer)
register(net.corda.nodeapi.internal.serialization.amqp.custom.InstantSerializer(this))
}
}

View File

@ -0,0 +1,10 @@
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.Kryo
import net.corda.core.serialization.SerializationCustomization
class KryoSerializationCustomization(val kryo: Kryo) : SerializationCustomization {
override fun addToWhitelist(type: Class<*>) {
kryo.addToWhitelist(type)
}
}

View File

@ -1,4 +1,4 @@
package net.corda.nodeapi.serialization
package net.corda.nodeapi.internal.serialization
import co.paralleluniverse.fibers.Fiber
import co.paralleluniverse.io.serialization.kryo.KryoSerializer

View File

@ -0,0 +1,56 @@
package net.corda.nodeapi.internal.serialization
import net.corda.core.node.ServiceHub
import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.SerializationFactory
import net.corda.core.serialization.SerializeAsToken
import net.corda.core.serialization.SerializeAsTokenContext
val serializationContextKey = SerializeAsTokenContext::class.java
fun SerializationContext.withTokenContext(serializationContext: SerializeAsTokenContext): SerializationContext = this.withProperty(serializationContextKey, serializationContext)
/**
* A context for mapping SerializationTokens to/from SerializeAsTokens.
*
* A context is initialised with an object containing all the instances of [SerializeAsToken] to eagerly register all the tokens.
* In our case this can be the [ServiceHub].
*
* Then it is a case of using the companion object methods on [SerializeAsTokenSerializer] to set and clear context as necessary
* when serializing to enable/disable tokenization.
*/
class SerializeAsTokenContextImpl(override val serviceHub: ServiceHub, init: SerializeAsTokenContext.() -> Unit) : SerializeAsTokenContext {
constructor(toBeTokenized: Any, serializationFactory: SerializationFactory, context: SerializationContext, serviceHub: ServiceHub) : this(serviceHub, {
serializationFactory.serialize(toBeTokenized, context.withTokenContext(this))
})
private val classNameToSingleton = mutableMapOf<String, SerializeAsToken>()
private var readOnly = false
init {
/**
* Go ahead and eagerly serialize the object to register all of the tokens in the context.
*
* This results in the toToken() method getting called for any [SingletonSerializeAsToken] instances which
* are encountered in the object graph as they are serialized and will therefore register the token to
* object mapping for those instances. We then immediately set the readOnly flag to stop further adhoc or
* accidental registrations from occuring as these could not be deserialized in a deserialization-first
* scenario if they are not part of this iniital context construction serialization.
*/
init(this)
readOnly = true
}
override fun putSingleton(toBeTokenized: SerializeAsToken) {
val className = toBeTokenized.javaClass.name
if (className !in classNameToSingleton) {
// Only allowable if we are in SerializeAsTokenContext init (readOnly == false)
if (readOnly) {
throw UnsupportedOperationException("Attempt to write token for lazy registered ${className}. All tokens should be registered during context construction.")
}
classNameToSingleton[className] = toBeTokenized
}
}
override fun getSingleton(className: String) = classNameToSingleton[className] ?: throw IllegalStateException("Unable to find tokenized instance of $className in context $this")
}

View File

@ -0,0 +1,25 @@
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoException
import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import net.corda.core.internal.castIfPossible
import net.corda.core.serialization.SerializationToken
import net.corda.core.serialization.SerializeAsToken
/**
* A Kryo serializer for [SerializeAsToken] implementations.
*/
class SerializeAsTokenSerializer<T : SerializeAsToken> : Serializer<T>() {
override fun write(kryo: Kryo, output: Output, obj: T) {
kryo.writeClassAndObject(output, obj.toToken(kryo.serializationContext() ?: throw KryoException("Attempt to write a ${SerializeAsToken::class.simpleName} instance of ${obj.javaClass.name} without initialising a context")))
}
override fun read(kryo: Kryo, input: Input, type: Class<T>): T {
val token = (kryo.readClassAndObject(input) as? SerializationToken) ?: throw KryoException("Non-token read for tokenized type: ${type.name}")
val fromToken = token.fromToken(kryo.serializationContext() ?: throw KryoException("Attempt to read a token for a ${SerializeAsToken::class.simpleName} instance of ${type.name} without initialising a context"))
return type.castIfPossible(fromToken) ?: throw KryoException("Token read ($token) did not return expected tokenized type: ${type.name}")
}
}

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.amqp.Binary
import org.apache.qpid.proton.codec.Data

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.codec.Data
import java.lang.reflect.Type

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.codec.Data
import java.io.NotSerializableException

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.codec.Data
import java.io.NotSerializableException

View File

@ -1,6 +1,6 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import net.corda.core.serialization.amqp.SerializerFactory.Companion.nameForType
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.nameForType
import org.apache.qpid.proton.codec.Data
import java.lang.reflect.Type

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import net.corda.core.internal.getStackTraceAsString
import net.corda.core.serialization.SerializedBytes

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import java.lang.reflect.GenericArrayType
import java.lang.reflect.Type

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import com.google.common.primitives.Primitives
import java.io.NotSerializableException

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.codec.Data
import java.io.NotSerializableException

View File

@ -1,6 +1,6 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import net.corda.core.serialization.amqp.SerializerFactory.Companion.nameForType
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.nameForType
import org.apache.qpid.proton.amqp.UnsignedInteger
import org.apache.qpid.proton.codec.Data
import java.io.NotSerializableException

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.amqp.Binary
import org.apache.qpid.proton.codec.Data

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import com.google.common.hash.Hasher
import com.google.common.hash.Hashing
@ -14,9 +14,8 @@ import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.lang.reflect.TypeVariable
import java.util.*
import net.corda.core.serialization.carpenter.Schema as CarpenterSchema
import net.corda.core.serialization.carpenter.Field as CarpenterField
import net.corda.nodeapi.internal.serialization.carpenter.Field as CarpenterField
import net.corda.nodeapi.internal.serialization.carpenter.Schema as CarpenterSchema
// TODO: get an assigned number as per AMQP spec
val DESCRIPTOR_TOP_32BITS: Long = 0xc0da0000

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import com.google.common.reflect.TypeToken
import org.apache.qpid.proton.codec.Data

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import net.corda.core.serialization.SerializedBytes
import org.apache.qpid.proton.codec.Data

View File

@ -1,10 +1,10 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import com.google.common.primitives.Primitives
import com.google.common.reflect.TypeResolver
import net.corda.core.serialization.AllWhitelist
import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.CordaSerializable
import net.corda.nodeapi.internal.serialization.AllWhitelist
import org.apache.qpid.proton.amqp.*
import java.io.NotSerializableException
import java.lang.reflect.GenericArrayType

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.codec.Data
import java.lang.reflect.Type

View File

@ -1,6 +1,6 @@
package net.corda.core.serialization.amqp.custom
package net.corda.nodeapi.internal.serialization.amqp.custom
import net.corda.core.serialization.amqp.CustomSerializer
import net.corda.nodeapi.internal.serialization.amqp.CustomSerializer
import java.math.BigDecimal
/**

View File

@ -1,6 +1,6 @@
package net.corda.core.serialization.amqp.custom
package net.corda.nodeapi.internal.serialization.amqp.custom
import net.corda.core.serialization.amqp.CustomSerializer
import net.corda.nodeapi.internal.serialization.amqp.CustomSerializer
import java.util.*
/**

View File

@ -1,7 +1,7 @@
package net.corda.core.serialization.amqp.custom
package net.corda.nodeapi.internal.serialization.amqp.custom
import net.corda.core.serialization.amqp.CustomSerializer
import net.corda.core.serialization.amqp.SerializerFactory
import net.corda.nodeapi.internal.serialization.amqp.CustomSerializer
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory
import java.time.Instant
/**

View File

@ -1,7 +1,7 @@
package net.corda.core.serialization.amqp.custom
package net.corda.nodeapi.internal.serialization.amqp.custom
import net.corda.core.crypto.Crypto
import net.corda.core.serialization.amqp.*
import net.corda.nodeapi.internal.serialization.amqp.*
import org.apache.qpid.proton.codec.Data
import java.lang.reflect.Type
import java.security.PublicKey

View File

@ -1,11 +1,11 @@
package net.corda.core.serialization.amqp.custom
package net.corda.nodeapi.internal.serialization.amqp.custom
import net.corda.core.serialization.amqp.CustomSerializer
import net.corda.core.serialization.amqp.SerializerFactory
import net.corda.core.serialization.amqp.constructorForDeserialization
import net.corda.core.serialization.amqp.propertiesForSerialization
import net.corda.core.CordaRuntimeException
import net.corda.core.CordaThrowable
import net.corda.nodeapi.internal.serialization.amqp.CustomSerializer
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory
import net.corda.nodeapi.internal.serialization.amqp.constructorForDeserialization
import net.corda.nodeapi.internal.serialization.amqp.propertiesForSerialization
import java.io.NotSerializableException
class ThrowableSerializer(factory: SerializerFactory) : CustomSerializer.Proxy<Throwable, ThrowableSerializer.ThrowableProxy>(Throwable::class.java, ThrowableProxy::class.java, factory) {

View File

@ -1,6 +1,6 @@
package net.corda.core.serialization.amqp.custom
package net.corda.nodeapi.internal.serialization.amqp.custom
import net.corda.core.serialization.amqp.*
import net.corda.nodeapi.internal.serialization.amqp.*
import org.apache.qpid.proton.codec.Data
import org.bouncycastle.asn1.ASN1InputStream
import org.bouncycastle.asn1.x500.X500Name

View File

@ -1,8 +1,8 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import net.corda.core.serialization.amqp.Schema as AMQPSchema
import net.corda.core.serialization.amqp.Field as AMQPField
import net.corda.core.serialization.amqp.CompositeType
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
import net.corda.nodeapi.internal.serialization.amqp.Field as AMQPField
import net.corda.nodeapi.internal.serialization.amqp.Schema as AMQPSchema
fun AMQPSchema.carpenterSchema(
loaders : List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader()))
@ -41,7 +41,7 @@ private fun CompositeType.validatePropertyTypes(
*/
fun CompositeType.carpenterSchema(
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader()),
carpenterSchemas : CarpenterSchemas,
carpenterSchemas: CarpenterSchemas,
force : Boolean = false) {
if (classLoaders.exists(name)) {
validatePropertyTypes(classLoaders)
@ -68,7 +68,7 @@ fun CompositeType.carpenterSchema(
}
}
val m : MutableMap<String, Field> = mutableMapOf()
val m: MutableMap<String, Field> = mutableMapOf()
fields.forEach {
try {

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.MethodVisitor
@ -303,7 +303,7 @@ class ClassCarpenter {
it.name.startsWith("get") -> it.name.substring(3).decapitalize()
else -> throw InterfaceMismatchException(
"Requested interfaces must consist only of methods that start "
+ "with 'get': ${itf.name}.${it.name}")
+ "with 'get': ${itf.name}.${it.name}")
}
// If we're trying to carpent a class that prior to serialisation / deserialisation
@ -314,7 +314,7 @@ class ClassCarpenter {
if ((schema is ClassSchema) and (fieldNameFromItf !in allFields))
throw InterfaceMismatchException(
"Interface ${itf.name} requires a field named $fieldNameFromItf but that "
+ "isn't found in the schema or any superclass schemas")
+ "isn't found in the schema or any superclass schemas")
}
}
}

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
class DuplicateNameException : RuntimeException (
"An attempt was made to register two classes with the same name within the same ClassCarpenter namespace.")

View File

@ -1,7 +1,7 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import net.corda.core.serialization.amqp.CompositeType
import net.corda.core.serialization.amqp.TypeNotation
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
import net.corda.nodeapi.internal.serialization.amqp.TypeNotation
/**
* Generated from an AMQP schema this class represents the classes unknown to the deserialiser and that thusly
@ -23,9 +23,9 @@ import net.corda.core.serialization.amqp.TypeNotation
* and if that list is reduced to zero know we can now generate a [Schema] for them and carpent them up
*/
data class CarpenterSchemas (
val carpenterSchemas : MutableList<Schema>,
val dependencies : MutableMap<String, Pair<TypeNotation, MutableList<String>>>,
val dependsOn : MutableMap<String, MutableList<String>>) {
val carpenterSchemas: MutableList<Schema>,
val dependencies: MutableMap<String, Pair<TypeNotation, MutableList<String>>>,
val dependsOn: MutableMap<String, MutableList<String>>) {
companion object CarpenterSchemaConstructor {
fun newInstance(): CarpenterSchemas {
return CarpenterSchemas(
@ -57,7 +57,7 @@ abstract class MetaCarpenterBase (val schemas : CarpenterSchemas) {
private val cc = ClassCarpenter()
val objects = mutableMapOf<String, Class<*>>()
fun step (newObject : Schema) {
fun step(newObject: Schema) {
objects[newObject.name] = cc.build (newObject)
// go over the list of everything that had a dependency on the newly
@ -82,7 +82,7 @@ abstract class MetaCarpenterBase (val schemas : CarpenterSchemas) {
abstract fun build()
}
class MetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
class MetaCarpenter(schemas: CarpenterSchemas) : MetaCarpenterBase(schemas) {
override fun build() {
while (schemas.carpenterSchemas.isNotEmpty()) {
val newObject = schemas.carpenterSchemas.removeAt(0)
@ -91,7 +91,7 @@ class MetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
}
}
class TestMetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
class TestMetaCarpenter(schemas: CarpenterSchemas) : MetaCarpenterBase(schemas) {
override fun build() {
if (schemas.carpenterSchemas.isEmpty()) return
step (schemas.carpenterSchemas.removeAt(0))

View File

@ -1,12 +1,10 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import jdk.internal.org.objectweb.asm.Opcodes.*
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Type
import java.util.LinkedHashMap
import java.util.*
/**
* A Schema represents a desired class.
@ -35,18 +33,18 @@ abstract class Schema(
}
class ClassSchema(
name: String,
fields: Map<String, Field>,
superclass: Schema? = null,
interfaces: List<Class<*>> = emptyList()
) : Schema (name, fields, superclass, interfaces)
name: String,
fields: Map<String, Field>,
superclass: Schema? = null,
interfaces: List<Class<*>> = emptyList()
) : Schema(name, fields, superclass, interfaces)
class InterfaceSchema(
name: String,
fields: Map<String, Field>,
superclass: Schema? = null,
interfaces: List<Class<*>> = emptyList()
) : Schema (name, fields, superclass, interfaces)
name: String,
fields: Map<String, Field>,
superclass: Schema? = null,
interfaces: List<Class<*>> = emptyList()
) : Schema(name, fields, superclass, interfaces)
object CarpenterSchemaFactory {
fun newInstance (

View File

@ -1,2 +1,2 @@
# Register a ServiceLoader service extending from net.corda.core.node.CordaPluginRegistry
net.corda.nodeapi.serialization.DefaultWhitelist
net.corda.nodeapi.internal.serialization.DefaultWhitelist

View File

@ -1,4 +1,4 @@
package net.corda.core.node
package net.corda.nodeapi
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
@ -6,11 +6,15 @@ import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.AttachmentStorage
import net.corda.core.serialization.*
import net.corda.core.serialization.SerializationDefaults.P2P_CONTEXT
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.nodeapi.internal.serialization.SerializeAsTokenContextImpl
import net.corda.nodeapi.internal.serialization.WireTransactionSerializer
import net.corda.nodeapi.internal.serialization.withTokenContext
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.MEGA_CORP
import net.corda.testing.TestDependencyInjectionBase
@ -43,7 +47,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
private fun SerializationContext.withAttachmentStorage(attachmentStorage: AttachmentStorage): SerializationContext {
val serviceHub = mock<ServiceHub>()
whenever(serviceHub.attachments).thenReturn(attachmentStorage)
return this.withTokenContext(SerializeAsTokenContext(serviceHub) {}).withProperty(WireTransactionSerializer.attachmentsClassLoaderEnabled, true)
return this.withTokenContext(SerializeAsTokenContextImpl(serviceHub) {}).withProperty(WireTransactionSerializer.attachmentsClassLoaderEnabled, true)
}
}
@ -192,7 +196,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
@Test
fun `verify that contract DummyContract is in classPath`() {
val contractClass = Class.forName("net.corda.core.node.AttachmentClassLoaderTests\$AttachmentDummyContract")
val contractClass = Class.forName("net.corda.nodeapi.AttachmentClassLoaderTests\$AttachmentDummyContract")
val contract = contractClass.newInstance() as Contract
assertNotNull(contract)

View File

@ -1,11 +1,13 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.*
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import com.esotericsoftware.kryo.util.MapReferenceResolver
import net.corda.core.node.AttachmentClassLoaderTests
import net.corda.core.node.services.AttachmentStorage
import net.corda.core.serialization.AttachmentsClassLoader
import net.corda.core.serialization.CordaSerializable
import net.corda.nodeapi.AttachmentClassLoaderTests
import net.corda.testing.node.MockAttachmentStorage
import org.junit.Rule
import org.junit.Test
@ -182,7 +184,7 @@ class CordaClassResolverTests {
@Test
fun `Check blacklisted subclass`() {
expectedEx.expect(IllegalStateException::class.java)
expectedEx.expectMessage("The superclass java.util.HashSet of net.corda.core.serialization.CordaClassResolverTests\$SubHashSet is blacklisted, so it cannot be used in serialization.")
expectedEx.expectMessage("The superclass java.util.HashSet of net.corda.nodeapi.internal.serialization.CordaClassResolverTests\$SubHashSet is blacklisted, so it cannot be used in serialization.")
val resolver = CordaClassResolver(AllButBlacklisted)
// SubHashSet extends the blacklisted HashSet.
resolver.getRegistration(SubHashSet::class.java)
@ -192,7 +194,7 @@ class CordaClassResolverTests {
@Test
fun `Check blacklisted subsubclass`() {
expectedEx.expect(IllegalStateException::class.java)
expectedEx.expectMessage("The superclass java.util.HashSet of net.corda.core.serialization.CordaClassResolverTests\$SubSubHashSet is blacklisted, so it cannot be used in serialization.")
expectedEx.expectMessage("The superclass java.util.HashSet of net.corda.nodeapi.internal.serialization.CordaClassResolverTests\$SubSubHashSet is blacklisted, so it cannot be used in serialization.")
val resolver = CordaClassResolver(AllButBlacklisted)
// SubSubHashSet extends SubHashSet, which extends the blacklisted HashSet.
resolver.getRegistration(SubSubHashSet::class.java)
@ -202,7 +204,7 @@ class CordaClassResolverTests {
@Test
fun `Check blacklisted interface impl`() {
expectedEx.expect(IllegalStateException::class.java)
expectedEx.expectMessage("The superinterface java.sql.Connection of net.corda.core.serialization.CordaClassResolverTests\$ConnectionImpl is blacklisted, so it cannot be used in serialization.")
expectedEx.expectMessage("The superinterface java.sql.Connection of net.corda.nodeapi.internal.serialization.CordaClassResolverTests\$ConnectionImpl is blacklisted, so it cannot be used in serialization.")
val resolver = CordaClassResolver(AllButBlacklisted)
// ConnectionImpl implements blacklisted Connection.
resolver.getRegistration(ConnectionImpl::class.java)
@ -213,7 +215,7 @@ class CordaClassResolverTests {
@Test
fun `Check blacklisted super-interface impl`() {
expectedEx.expect(IllegalStateException::class.java)
expectedEx.expectMessage("The superinterface java.sql.Connection of net.corda.core.serialization.CordaClassResolverTests\$SubConnectionImpl is blacklisted, so it cannot be used in serialization.")
expectedEx.expectMessage("The superinterface java.sql.Connection of net.corda.nodeapi.internal.serialization.CordaClassResolverTests\$SubConnectionImpl is blacklisted, so it cannot be used in serialization.")
val resolver = CordaClassResolver(AllButBlacklisted)
// SubConnectionImpl implements SubConnection, which extends the blacklisted Connection.
resolver.getRegistration(SubConnectionImpl::class.java)
@ -231,7 +233,7 @@ class CordaClassResolverTests {
@Test
fun `Check blacklist precedes CordaSerializable`() {
expectedEx.expect(IllegalStateException::class.java)
expectedEx.expectMessage("The superclass java.util.HashSet of net.corda.core.serialization.CordaClassResolverTests\$CordaSerializableHashSet is blacklisted, so it cannot be used in serialization.")
expectedEx.expectMessage("The superclass java.util.HashSet of net.corda.nodeapi.internal.serialization.CordaClassResolverTests\$CordaSerializableHashSet is blacklisted, so it cannot be used in serialization.")
val resolver = CordaClassResolver(AllButBlacklisted)
// CordaSerializableHashSet is @CordaSerializable, but extends the blacklisted HashSet.
resolver.getRegistration(CordaSerializableHashSet::class.java)

View File

@ -1,13 +1,16 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoSerializable
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import com.google.common.primitives.Ints
import net.corda.core.crypto.*
import net.corda.core.serialization.*
import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.sequence
import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.nodeapi.serialization.KryoHeaderV0_1
import net.corda.nodeapi.serialization.SerializationContextImpl
import net.corda.nodeapi.serialization.SerializationFactoryImpl
import net.corda.testing.ALICE
import net.corda.testing.ALICE_PUBKEY
import net.corda.testing.BOB
@ -182,4 +185,53 @@ class KryoTests {
@CordaSerializable
private object TestSingleton
object SimpleSteps {
object ONE : ProgressTracker.Step("one")
object TWO : ProgressTracker.Step("two")
object THREE : ProgressTracker.Step("three")
object FOUR : ProgressTracker.Step("four")
fun tracker() = ProgressTracker(ONE, TWO, THREE, FOUR)
}
object ChildSteps {
object AYY : ProgressTracker.Step("ayy")
object BEE : ProgressTracker.Step("bee")
object SEA : ProgressTracker.Step("sea")
fun tracker() = ProgressTracker(AYY, BEE, SEA)
}
@Test
fun rxSubscriptionsAreNotSerialized() {
val pt: ProgressTracker = SimpleSteps.tracker()
val pt2: ProgressTracker = ChildSteps.tracker()
class Unserializable : KryoSerializable {
override fun write(kryo: Kryo?, output: Output?) = throw AssertionError("not called")
override fun read(kryo: Kryo?, input: Input?) = throw AssertionError("not called")
fun foo() {
println("bar")
}
}
pt.setChildProgressTracker(SimpleSteps.TWO, pt2)
class Tmp {
val unserializable = Unserializable()
init {
pt2.changes.subscribe { unserializable.foo() }
}
}
Tmp()
val factory = SerializationFactoryImpl().apply { registerScheme(KryoServerSerializationScheme()) }
val context = SerializationContextImpl(KryoHeaderV0_1,
javaClass.classLoader,
AllWhitelist,
emptyMap(),
true,
SerializationContext.UseCase.P2P)
pt.serialize(factory, context)
}
}

View File

@ -1,15 +1,13 @@
package net.corda.core.serialization
package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoException
import com.esotericsoftware.kryo.io.Output
import com.nhaarman.mockito_kotlin.mock
import net.corda.core.node.ServiceHub
import net.corda.core.serialization.*
import net.corda.core.utilities.OpaqueBytes
import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.nodeapi.serialization.KryoHeaderV0_1
import net.corda.nodeapi.serialization.SerializationContextImpl
import net.corda.nodeapi.serialization.SerializationFactoryImpl
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
@ -43,7 +41,7 @@ class SerializationTokenTest {
override fun equals(other: Any?) = other is LargeTokenizable && other.bytes.size == this.bytes.size
}
private fun serializeAsTokenContext(toBeTokenized: Any) = SerializeAsTokenContext(toBeTokenized, factory, context, mock<ServiceHub>())
private fun serializeAsTokenContext(toBeTokenized: Any) = SerializeAsTokenContextImpl(toBeTokenized, factory, context, mock<ServiceHub>())
@Test
fun `write token and read tokenizable`() {

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.junit.Test
import kotlin.test.assertEquals

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.apache.qpid.proton.codec.Data
import org.junit.Test

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import org.junit.Test
import java.io.NotSerializableException

View File

@ -1,4 +1,4 @@
package net.corda.core.serialization.amqp
package net.corda.nodeapi.internal.serialization.amqp
import net.corda.core.CordaRuntimeException
import net.corda.core.contracts.Contract
@ -9,11 +9,12 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowException
import net.corda.core.identity.AbstractParty
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.EmptyWhitelist
import net.corda.core.serialization.KryoAMQPSerializer
import net.corda.core.serialization.amqp.SerializerFactory.Companion.isPrimitive
import net.corda.core.transactions.LedgerTransaction
import net.corda.nodeapi.RPCException
import net.corda.nodeapi.internal.serialization.EmptyWhitelist
import net.corda.nodeapi.internal.serialization.KryoAMQPSerializer
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.isPrimitive
import net.corda.nodeapi.internal.serialization.amqp.custom.*
import net.corda.testing.MEGA_CORP
import net.corda.testing.MEGA_CORP_PUBKEY
import org.apache.qpid.proton.amqp.*
@ -387,9 +388,9 @@ class SerializationOutputTests {
@Test
fun `test custom serializers on public key`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.PublicKeySerializer)
factory.register(PublicKeySerializer)
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.PublicKeySerializer)
factory2.register(PublicKeySerializer)
val obj = MEGA_CORP_PUBKEY
serdes(obj, factory, factory2)
}
@ -403,10 +404,10 @@ class SerializationOutputTests {
@Test
fun `test throwables serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory))
factory.register(ThrowableSerializer(factory))
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory2))
factory2.register(ThrowableSerializer(factory2))
val t = IllegalAccessException("message").fillInStackTrace()
val desThrowable = serdes(t, factory, factory2, false) as Throwable
@ -416,10 +417,10 @@ class SerializationOutputTests {
@Test
fun `test complex throwables serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory))
factory.register(ThrowableSerializer(factory))
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory2))
factory2.register(ThrowableSerializer(factory2))
try {
try {
@ -447,10 +448,10 @@ class SerializationOutputTests {
@Test
fun `test suppressed throwables serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory))
factory.register(ThrowableSerializer(factory))
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory2))
factory2.register(ThrowableSerializer(factory2))
try {
try {
@ -469,10 +470,10 @@ class SerializationOutputTests {
@Test
fun `test flow corda exception subclasses serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory))
factory.register(ThrowableSerializer(factory))
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory2))
factory2.register(ThrowableSerializer(factory2))
val obj = FlowException("message").fillInStackTrace()
serdes(obj, factory, factory2)
@ -481,10 +482,10 @@ class SerializationOutputTests {
@Test
fun `test RPC corda exception subclasses serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory))
factory.register(ThrowableSerializer(factory))
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.ThrowableSerializer(factory2))
factory2.register(ThrowableSerializer(factory2))
val obj = RPCException("message").fillInStackTrace()
serdes(obj, factory, factory2)
@ -542,10 +543,10 @@ class SerializationOutputTests {
@Test
fun `test currencies serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.CurrencySerializer)
factory.register(CurrencySerializer)
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.CurrencySerializer)
factory2.register(CurrencySerializer)
val obj = Currency.getInstance("USD")
serdes(obj, factory, factory2)
@ -554,10 +555,10 @@ class SerializationOutputTests {
@Test
fun `test big decimals serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.BigDecimalSerializer)
factory.register(BigDecimalSerializer)
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.BigDecimalSerializer)
factory2.register(BigDecimalSerializer)
val obj = BigDecimal("100000000000000000000000000000.00")
serdes(obj, factory, factory2)
@ -566,10 +567,10 @@ class SerializationOutputTests {
@Test
fun `test instants serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.InstantSerializer(factory))
factory.register(InstantSerializer(factory))
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.InstantSerializer(factory2))
factory2.register(InstantSerializer(factory2))
val obj = Instant.now()
serdes(obj, factory, factory2)
@ -578,10 +579,10 @@ class SerializationOutputTests {
@Test
fun `test StateRef serialize`() {
val factory = SerializerFactory()
factory.register(net.corda.core.serialization.amqp.custom.InstantSerializer(factory))
factory.register(InstantSerializer(factory))
val factory2 = SerializerFactory()
factory2.register(net.corda.core.serialization.amqp.custom.InstantSerializer(factory2))
factory2.register(InstantSerializer(factory2))
val obj = StateRef(SecureHash.randomSHA256(), 0)
serdes(obj, factory, factory2)

View File

@ -1,10 +1,12 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import org.junit.Test
import java.beans.Introspector
import java.lang.reflect.Field
import java.lang.reflect.Method
import javax.annotation.Nonnull
import javax.annotation.Nullable
import kotlin.test.assertEquals
import java.beans.Introspector
import kotlin.test.assertNotEquals
class ClassCarpenterTest {
@ -42,7 +44,7 @@ class ClassCarpenterTest {
"floatMyBoat" to Float::class.javaPrimitiveType!!,
"byteMe" to Byte::class.javaPrimitiveType!!,
"booleanField" to Boolean::class.javaPrimitiveType!!).mapValues {
NonNullableField (it.value)
NonNullableField(it.value)
}))
assertEquals(8, clazz.nonSyntheticFields.size)
assertEquals(10, clazz.nonSyntheticMethods.size)
@ -72,7 +74,7 @@ class ClassCarpenterTest {
val clazz = cc.build(ClassSchema("gen.Person", mapOf(
"age" to Int::class.javaPrimitiveType!!,
"name" to String::class.java
).mapValues { NonNullableField (it.value) } ))
).mapValues { NonNullableField(it.value) }))
val i = clazz.constructors[0].newInstance(32, "Mike")
return Pair(clazz, i)
}
@ -100,7 +102,7 @@ class ClassCarpenterTest {
fun `can refer to each other`() {
val (clazz1, i) = genPerson()
val clazz2 = cc.build(ClassSchema("gen.Referee", mapOf(
"ref" to NonNullableField (clazz1)
"ref" to NonNullableField(clazz1)
)))
val i2 = clazz2.constructors[0].newInstance(i)
assertEquals(i, (i2 as SimpleFieldAccess)["ref"])
@ -110,11 +112,11 @@ class ClassCarpenterTest {
fun superclasses() {
val schema1 = ClassSchema(
"gen.A",
mapOf("a" to NonNullableField (String::class.java)))
mapOf("a" to NonNullableField(String::class.java)))
val schema2 = ClassSchema(
"gen.B",
mapOf("b" to NonNullableField (String::class.java)),
mapOf("b" to NonNullableField(String::class.java)),
schema1)
val clazz = cc.build(schema2)
@ -162,7 +164,7 @@ class ClassCarpenterTest {
fun `generate interface`() {
val schema1 = InterfaceSchema(
"gen.Interface",
mapOf("a" to NonNullableField (Int::class.java)))
mapOf("a" to NonNullableField(Int::class.java)))
val iface = cc.build(schema1)
@ -173,7 +175,7 @@ class ClassCarpenterTest {
val schema2 = ClassSchema(
"gen.Derived",
mapOf("a" to NonNullableField (Int::class.java)),
mapOf("a" to NonNullableField(Int::class.java)),
interfaces = listOf(iface))
val clazz = cc.build(schema2)
@ -224,7 +226,7 @@ class ClassCarpenterTest {
val iFace1 = InterfaceSchema(
"gen.Interface1",
mapOf(
"a" to NonNullableField (Int::class.java),
"a" to NonNullableField(Int::class.java),
"b" to NonNullableField(String::class.java)))
val iFace2 = InterfaceSchema(
@ -261,7 +263,7 @@ class ClassCarpenterTest {
val className = "iEnjoySwede"
val schema = ClassSchema(
"gen.$className",
mapOf("a" to NonNullableField (Int::class.java)))
mapOf("a" to NonNullableField(Int::class.java)))
val clazz = cc.build(schema)
val a : Int? = null
@ -273,7 +275,7 @@ class ClassCarpenterTest {
val className = "iEnjoySwede"
val schema = ClassSchema(
"gen.$className",
mapOf("a" to NullableField (Int::class.java)))
mapOf("a" to NullableField(Int::class.java)))
cc.build(schema)
}
@ -283,7 +285,7 @@ class ClassCarpenterTest {
val className = "iEnjoyWibble"
val schema = ClassSchema(
"gen.$className",
mapOf("a" to NullableField (Integer::class.java)))
mapOf("a" to NullableField(Integer::class.java)))
val clazz = cc.build(schema)
val a1 : Int? = null
@ -298,7 +300,7 @@ class ClassCarpenterTest {
val className = "iEnjoyWibble"
val schema = ClassSchema(
"gen.$className",
mapOf("a" to NonNullableField (Integer::class.java)))
mapOf("a" to NonNullableField(Integer::class.java)))
val clazz = cc.build(schema)
@ -311,7 +313,7 @@ class ClassCarpenterTest {
val className = "iEnjoyWibble"
val schema = ClassSchema(
"gen.$className",
mapOf("a" to NonNullableField (Integer::class.java)))
mapOf("a" to NonNullableField(Integer::class.java)))
val clazz = cc.build(schema)
@ -440,7 +442,7 @@ class ClassCarpenterTest {
mapOf(
"a" to Array<String>::class.java,
"b" to String::class.java,
"c" to Array<String>::class.java).mapValues { NullableField (it.value) })
"c" to Array<String>::class.java).mapValues { NullableField(it.value) })
val clazz = cc.build(schema)
@ -466,19 +468,19 @@ class ClassCarpenterTest {
val schema = ClassSchema(
"gen.$className",
mapOf("a" to NullableField(String::class.java),
"b" to NonNullableField(String::class.java)))
"b" to NonNullableField(String::class.java)))
val clazz = cc.build(schema)
assertEquals (2, clazz.declaredFields.size)
assertEquals (1, clazz.getDeclaredField("a").annotations.size)
assertEquals (javax.annotation.Nullable::class.java, clazz.getDeclaredField("a").annotations[0].annotationClass.java)
assertEquals(Nullable::class.java, clazz.getDeclaredField("a").annotations[0].annotationClass.java)
assertEquals (1, clazz.getDeclaredField("b").annotations.size)
assertEquals (javax.annotation.Nonnull::class.java, clazz.getDeclaredField("b").annotations[0].annotationClass.java)
assertEquals(Nonnull::class.java, clazz.getDeclaredField("b").annotations[0].annotationClass.java)
assertEquals (1, clazz.getMethod("getA").annotations.size)
assertEquals (javax.annotation.Nullable::class.java, clazz.getMethod("getA").annotations[0].annotationClass.java)
assertEquals(Nullable::class.java, clazz.getMethod("getA").annotations[0].annotationClass.java)
assertEquals (1, clazz.getMethod("getB").annotations.size)
assertEquals (javax.annotation.Nonnull::class.java, clazz.getMethod("getB").annotations[0].annotationClass.java)
assertEquals(Nonnull::class.java, clazz.getMethod("getB").annotations[0].annotationClass.java)
}
@Test

View File

@ -1,8 +1,8 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import net.corda.core.serialization.amqp.*
import net.corda.core.serialization.amqp.Field
import net.corda.core.serialization.amqp.Schema
import net.corda.nodeapi.internal.serialization.amqp.*
import net.corda.nodeapi.internal.serialization.amqp.Schema
import net.corda.nodeapi.internal.serialization.amqp.Field
fun mangleName(name: String) = "${name}__carpenter"

View File

@ -1,8 +1,8 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.amqp.*
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse

View File

@ -1,8 +1,7 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.amqp.*
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
import org.junit.Test
import kotlin.test.*
@ -43,7 +42,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertEquals(testJ, a.j)
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
assert(obj.obj is A)
assertTrue(obj.obj is A)
val serSchema = obj.envelope.schema
assertEquals(2, serSchema.types.size)
val l1 = serSchema.carpenterSchema()
@ -60,7 +59,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertNotEquals(null, aSchema)
assertEquals(mangleName(classTestName("A")), aSchema!!.name)
assertEquals(1, aSchema.interfaces.size)
assertEquals(net.corda.core.serialization.carpenter.J::class.java, aSchema.interfaces[0])
assertEquals(J::class.java, aSchema.interfaces[0])
val aBuilder = ClassCarpenter().build(aSchema)
val objJ = aBuilder.constructors[0].newInstance(testJ)
@ -83,7 +82,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
assert(obj.obj is A)
assertTrue(obj.obj is A)
val serSchema = obj.envelope.schema
@ -105,7 +104,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertEquals(aName, aSchema!!.name)
assertEquals(1, aSchema.interfaces.size)
assertEquals(net.corda.core.serialization.carpenter.J::class.java, aSchema.interfaces[0])
assertEquals(J::class.java, aSchema.interfaces[0])
val aBuilder = ClassCarpenter().build(aSchema)
val objJ = aBuilder.constructors[0].newInstance(testJ, testJJ)
@ -127,7 +126,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
val a = A(testI, testII)
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
assert(obj.obj is A)
assertTrue(obj.obj is A)
val serSchema = obj.envelope.schema
@ -152,8 +151,8 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertNotEquals(null, aSchema)
assertEquals(aName, aSchema!!.name)
assertEquals(2, aSchema.interfaces.size)
assert(net.corda.core.serialization.carpenter.I::class.java in aSchema.interfaces)
assert(net.corda.core.serialization.carpenter.II::class.java in aSchema.interfaces)
assertTrue(I::class.java in aSchema.interfaces)
assertTrue(II::class.java in aSchema.interfaces)
val aBuilder = ClassCarpenter().build(aSchema)
val objA = aBuilder.constructors[0].newInstance(testI, testII)
@ -175,7 +174,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
val a = A(testI, testIII)
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
assert(obj.obj is A)
assertTrue(obj.obj is A)
val serSchema = obj.envelope.schema
@ -198,8 +197,8 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertNotEquals(null, aSchema)
assertEquals(aName, aSchema!!.name)
assertEquals(2, aSchema.interfaces.size)
assert(net.corda.core.serialization.carpenter.I::class.java in aSchema.interfaces)
assert(net.corda.core.serialization.carpenter.III::class.java in aSchema.interfaces)
assertTrue(I::class.java in aSchema.interfaces)
assertTrue(III::class.java in aSchema.interfaces)
val aBuilder = ClassCarpenter().build(aSchema)
val objA = aBuilder.constructors[0].newInstance(testI, testIII)
@ -224,7 +223,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
val b = B(a, testIIII)
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
assert(obj.obj is B)
assertTrue(obj.obj is B)
val serSchema = obj.envelope.schema
@ -280,7 +279,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
val b = B(a, testIIII)
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
assert(obj.obj is B)
assertTrue(obj.obj is B)
val serSchema = obj.envelope.schema
@ -304,7 +303,7 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
val a = A(testI)
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
assert(obj.obj is A)
assertTrue(obj.obj is A)
val serSchema = obj.envelope.schema
@ -324,12 +323,12 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertNotEquals(null, carpenterSchema.carpenterSchemas.find { it.name == iName })
// since we can't build A it should list I as a dependency
assert(aName in carpenterSchema.dependencies)
assertTrue(aName in carpenterSchema.dependencies)
assertEquals(1, carpenterSchema.dependencies[aName]!!.second.size)
assertEquals(iName, carpenterSchema.dependencies[aName]!!.second[0])
// and conversly I should have A listed as a dependent
assert(iName in carpenterSchema.dependsOn)
assertTrue(iName in carpenterSchema.dependsOn)
assertEquals(1, carpenterSchema.dependsOn[iName]!!.size)
assertEquals(aName, carpenterSchema.dependsOn[iName]!![0])
@ -340,8 +339,8 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertEquals(0, mc.schemas.dependencies.size)
assertEquals(0, mc.schemas.dependsOn.size)
assertEquals(2, mc.objects.size)
assert(aName in mc.objects)
assert(iName in mc.objects)
assertTrue(aName in mc.objects)
assertTrue(iName in mc.objects)
mc.objects[aName]!!.constructors[0].newInstance(testI)
}
@ -373,15 +372,15 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertNotNull(carpenterSchema.carpenterSchemas.find { it.name == iiName })
assertNull(carpenterSchema.carpenterSchemas.find { it.name == aName })
assert(iName in carpenterSchema.dependsOn)
assertTrue(iName in carpenterSchema.dependsOn)
assertEquals(1, carpenterSchema.dependsOn[iName]?.size)
assertNotNull(carpenterSchema.dependsOn[iName]?.find({ it == aName }))
assert(iiName in carpenterSchema.dependsOn)
assertTrue(iiName in carpenterSchema.dependsOn)
assertEquals(1, carpenterSchema.dependsOn[iiName]?.size)
assertNotNull(carpenterSchema.dependsOn[iiName]?.find { it == aName })
assert(aName in carpenterSchema.dependencies)
assertTrue(aName in carpenterSchema.dependencies)
assertEquals(2, carpenterSchema.dependencies[aName]!!.second.size)
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iName })
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiName })
@ -393,9 +392,9 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertEquals(0, mc.schemas.dependencies.size)
assertEquals(0, mc.schemas.dependsOn.size)
assertEquals(3, mc.objects.size)
assert(aName in mc.objects)
assert(iName in mc.objects)
assert(iiName in mc.objects)
assertTrue(aName in mc.objects)
assertTrue(iName in mc.objects)
assertTrue(iiName in mc.objects)
}
@Test
@ -425,23 +424,23 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertNull(carpenterSchema.carpenterSchemas.find { it.name == aName })
// I has III as a direct dependent and A as an indirect one
assert(iName in carpenterSchema.dependsOn)
assertTrue(iName in carpenterSchema.dependsOn)
assertEquals(2, carpenterSchema.dependsOn[iName]?.size)
assertNotNull(carpenterSchema.dependsOn[iName]?.find({ it == iiiName }))
assertNotNull(carpenterSchema.dependsOn[iName]?.find({ it == aName }))
// III has A as a dependent
assert(iiiName in carpenterSchema.dependsOn)
assertTrue(iiiName in carpenterSchema.dependsOn)
assertEquals(1, carpenterSchema.dependsOn[iiiName]?.size)
assertNotNull(carpenterSchema.dependsOn[iiiName]?.find { it == aName })
// conversly III depends on I
assert(iiiName in carpenterSchema.dependencies)
assertTrue(iiiName in carpenterSchema.dependencies)
assertEquals(1, carpenterSchema.dependencies[iiiName]!!.second.size)
assertNotNull(carpenterSchema.dependencies[iiiName]!!.second.find { it == iName })
// and A depends on III and I
assert(aName in carpenterSchema.dependencies)
assertTrue(aName in carpenterSchema.dependencies)
assertEquals(2, carpenterSchema.dependencies[aName]!!.second.size)
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiiName })
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iName })
@ -453,8 +452,8 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
assertEquals(0, mc.schemas.dependencies.size)
assertEquals(0, mc.schemas.dependsOn.size)
assertEquals(3, mc.objects.size)
assert(aName in mc.objects)
assert(iName in mc.objects)
assert(iiiName in mc.objects)
assertTrue(aName in mc.objects)
assertTrue(iName in mc.objects)
assertTrue(iiiName in mc.objects)
}
}

View File

@ -1,8 +1,8 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.amqp.*
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals

View File

@ -1,8 +1,8 @@
package net.corda.core.serialization.carpenter
package net.corda.nodeapi.internal.serialization.carpenter
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.amqp.*
import net.corda.nodeapi.internal.serialization.amqp.CompositeType
import net.corda.nodeapi.internal.serialization.amqp.DeserializationInput
import org.junit.Test
import kotlin.test.assertEquals

View File

@ -32,7 +32,7 @@ import net.corda.nodeapi.ArtemisTcpTransport
import net.corda.nodeapi.ConnectionDirection
import net.corda.nodeapi.internal.ShutdownHook
import net.corda.nodeapi.internal.addShutdownHook
import net.corda.nodeapi.serialization.*
import net.corda.nodeapi.internal.serialization.*
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
import org.apache.activemq.artemis.api.core.RoutingType
import org.apache.activemq.artemis.api.core.client.ActiveMQClient

View File

@ -1,17 +1,17 @@
package net.corda.node.serialization
import com.esotericsoftware.kryo.pool.KryoPool
import net.corda.core.serialization.DefaultKryoCustomizer
import net.corda.core.serialization.SerializationContext
import net.corda.core.utilities.ByteSequence
import net.corda.node.services.messaging.RpcServerObservableSerializer
import net.corda.nodeapi.RPCKryo
import net.corda.nodeapi.serialization.AbstractKryoSerializationScheme
import net.corda.nodeapi.serialization.KryoHeaderV0_1
import net.corda.nodeapi.internal.serialization.AbstractKryoSerializationScheme
import net.corda.nodeapi.internal.serialization.DefaultKryoCustomizer
import net.corda.nodeapi.internal.serialization.KryoHeaderV0_1
class KryoServerSerializationScheme : AbstractKryoSerializationScheme() {
override fun canDeserializeVersion(byteSequence: ByteSequence, target: SerializationContext.UseCase): Boolean {
return byteSequence.equals(KryoHeaderV0_1) && target != SerializationContext.UseCase.RPCClient
return byteSequence == KryoHeaderV0_1 && target != SerializationContext.UseCase.RPCClient
}
override fun rpcClientKryoPool(context: SerializationContext): KryoPool {

View File

@ -19,9 +19,11 @@ import net.corda.core.internal.ThreadBox
import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.internal.castIfPossible
import net.corda.core.messaging.DataFeed
import net.corda.core.serialization.*
import net.corda.core.serialization.SerializationDefaults.CHECKPOINT_CONTEXT
import net.corda.core.serialization.SerializationDefaults.SERIALIZATION_FACTORY
import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.core.utilities.Try
import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor
@ -35,6 +37,8 @@ import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.bufferUntilDatabaseCommit
import net.corda.node.utilities.wrapWithDatabaseTransaction
import net.corda.nodeapi.internal.serialization.SerializeAsTokenContextImpl
import net.corda.nodeapi.internal.serialization.withTokenContext
import org.apache.activemq.artemis.utils.ReusableLatch
import org.slf4j.Logger
import rx.Observable
@ -137,7 +141,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
internal val tokenizableServices = ArrayList<Any>()
// Context for tokenized services in checkpoints
private val serializationContext by lazy {
SerializeAsTokenContext(tokenizableServices, SERIALIZATION_FACTORY, CHECKPOINT_CONTEXT, serviceHub)
SerializeAsTokenContextImpl(tokenizableServices, SERIALIZATION_FACTORY, CHECKPOINT_CONTEXT, serviceHub)
}
fun findServices(predicate: (Any) -> Boolean) = tokenizableServices.filter(predicate)

View File

@ -8,14 +8,13 @@ import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.internal.RPCClient
import net.corda.client.rpc.internal.RPCClientConfiguration
import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.random63BitValue
import net.corda.core.internal.concurrent.fork
import net.corda.core.internal.concurrent.map
import net.corda.core.internal.div
import net.corda.core.messaging.RPCOps
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.parseNetworkHostAndPort
import net.corda.core.crypto.random63BitValue
import net.corda.core.internal.concurrent.fork
import net.corda.core.internal.concurrent.map
import net.corda.testing.driver.ProcessUtilities
import net.corda.node.services.RPCUserService
import net.corda.node.services.messaging.ArtemisMessagingServer
import net.corda.node.services.messaging.RPCServer
@ -24,7 +23,7 @@ import net.corda.nodeapi.ArtemisTcpTransport
import net.corda.nodeapi.ConnectionDirection
import net.corda.nodeapi.RPCApi
import net.corda.nodeapi.User
import net.corda.nodeapi.serialization.KRYO_RPC_CLIENT_CONTEXT
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
import net.corda.testing.driver.*
import org.apache.activemq.artemis.api.core.SimpleString
import org.apache.activemq.artemis.api.core.TransportConfiguration

View File

@ -4,7 +4,7 @@ import net.corda.client.rpc.serialization.KryoClientSerializationScheme
import net.corda.core.serialization.*
import net.corda.core.utilities.ByteSequence
import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.nodeapi.serialization.*
import net.corda.nodeapi.internal.serialization.*
fun <T> withTestSerialization(block: () -> T): T {
initialiseTestSerialization()

View File

@ -18,10 +18,10 @@ import net.corda.nodeapi.VerifierApi.VERIFICATION_REQUESTS_QUEUE_NAME
import net.corda.nodeapi.config.NodeSSLConfiguration
import net.corda.nodeapi.config.getValue
import net.corda.nodeapi.internal.addShutdownHook
import net.corda.nodeapi.serialization.AbstractKryoSerializationScheme
import net.corda.nodeapi.serialization.KRYO_P2P_CONTEXT
import net.corda.nodeapi.serialization.KryoHeaderV0_1
import net.corda.nodeapi.serialization.SerializationFactoryImpl
import net.corda.nodeapi.internal.serialization.AbstractKryoSerializationScheme
import net.corda.nodeapi.internal.serialization.KRYO_P2P_CONTEXT
import net.corda.nodeapi.internal.serialization.KryoHeaderV0_1
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
import java.nio.file.Path
import java.nio.file.Paths