mirror of
https://github.com/corda/corda.git
synced 2025-06-12 20:28:18 +00:00
[CORDA-1472]: Crackdown on warnings. (#3136)
This commit is contained in:
committed by
GitHub
parent
5a92079011
commit
d027b5b8f2
@ -103,7 +103,7 @@ class ArtemisTcpTransport {
|
||||
direction: ConnectionDirection,
|
||||
hostAndPortList: List<NetworkHostAndPort>,
|
||||
config: SSLConfiguration?,
|
||||
enableSSL: Boolean = true): List<TransportConfiguration>{
|
||||
enableSSL: Boolean = true): List<TransportConfiguration> {
|
||||
val tcpTransports = ArrayList<TransportConfiguration>(hostAndPortList.size)
|
||||
hostAndPortList.forEach {
|
||||
tcpTransports.add(tcpTransport(direction, it, config, enableSSL))
|
||||
|
@ -248,22 +248,22 @@ object RPCApi {
|
||||
}
|
||||
}
|
||||
|
||||
private val TAG_FIELD_NAME = "tag"
|
||||
private val RPC_ID_FIELD_NAME = "rpc-id"
|
||||
private val RPC_ID_TIMESTAMP_FIELD_NAME = "rpc-id-timestamp"
|
||||
private val RPC_SESSION_ID_FIELD_NAME = "rpc-session-id"
|
||||
private val RPC_SESSION_ID_TIMESTAMP_FIELD_NAME = "rpc-session-id-timestamp"
|
||||
private val RPC_EXTERNAL_ID_FIELD_NAME = "rpc-external-id"
|
||||
private val RPC_EXTERNAL_ID_TIMESTAMP_FIELD_NAME = "rpc-external-id-timestamp"
|
||||
private val RPC_EXTERNAL_SESSION_ID_FIELD_NAME = "rpc-external-session-id"
|
||||
private val RPC_EXTERNAL_SESSION_ID_TIMESTAMP_FIELD_NAME = "rpc-external-session-id-timestamp"
|
||||
private val RPC_IMPERSONATED_ACTOR_ID = "rpc-impersonated-actor-id"
|
||||
private val RPC_IMPERSONATED_ACTOR_STORE_ID = "rpc-impersonated-actor-store-id"
|
||||
private val RPC_IMPERSONATED_ACTOR_OWNING_LEGAL_IDENTITY = "rpc-impersonated-actor-owningLegalIdentity"
|
||||
private val DEDUPLICATION_IDENTITY_FIELD_NAME = "deduplication-identity"
|
||||
private val OBSERVABLE_ID_FIELD_NAME = "observable-id"
|
||||
private val OBSERVABLE_ID_TIMESTAMP_FIELD_NAME = "observable-id-timestamp"
|
||||
private val METHOD_NAME_FIELD_NAME = "method-name"
|
||||
private const val TAG_FIELD_NAME = "tag"
|
||||
private const val RPC_ID_FIELD_NAME = "rpc-id"
|
||||
private const val RPC_ID_TIMESTAMP_FIELD_NAME = "rpc-id-timestamp"
|
||||
private const val RPC_SESSION_ID_FIELD_NAME = "rpc-session-id"
|
||||
private const val RPC_SESSION_ID_TIMESTAMP_FIELD_NAME = "rpc-session-id-timestamp"
|
||||
private const val RPC_EXTERNAL_ID_FIELD_NAME = "rpc-external-id"
|
||||
private const val RPC_EXTERNAL_ID_TIMESTAMP_FIELD_NAME = "rpc-external-id-timestamp"
|
||||
private const val RPC_EXTERNAL_SESSION_ID_FIELD_NAME = "rpc-external-session-id"
|
||||
private const val RPC_EXTERNAL_SESSION_ID_TIMESTAMP_FIELD_NAME = "rpc-external-session-id-timestamp"
|
||||
private const val RPC_IMPERSONATED_ACTOR_ID = "rpc-impersonated-actor-id"
|
||||
private const val RPC_IMPERSONATED_ACTOR_STORE_ID = "rpc-impersonated-actor-store-id"
|
||||
private const val RPC_IMPERSONATED_ACTOR_OWNING_LEGAL_IDENTITY = "rpc-impersonated-actor-owningLegalIdentity"
|
||||
private const val DEDUPLICATION_IDENTITY_FIELD_NAME = "deduplication-identity"
|
||||
private const val OBSERVABLE_ID_FIELD_NAME = "observable-id"
|
||||
private const val OBSERVABLE_ID_TIMESTAMP_FIELD_NAME = "observable-id-timestamp"
|
||||
private const val METHOD_NAME_FIELD_NAME = "method-name"
|
||||
|
||||
fun ClientMessage.replyId(): InvocationId {
|
||||
|
||||
|
@ -49,7 +49,6 @@ class ArtemisMessagingComponent {
|
||||
*/
|
||||
val bridgedCertificateSubject = SimpleString("sender-subject-name")
|
||||
|
||||
|
||||
object Type {
|
||||
const val KEY = "corda_p2p_message_type"
|
||||
const val SESSION_INIT_VALUE = "session_init"
|
||||
@ -128,5 +127,4 @@ class ArtemisMessagingComponent {
|
||||
|
||||
override val queueName: String = "$P2P_PREFIX${identity.toStringShort()}"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ inline fun NodeInfo.sign(signer: (PublicKey, SerializedBytes<NodeInfo>) -> Digit
|
||||
class NodeInfoAndSigned private constructor(val nodeInfo: NodeInfo, val signed: SignedNodeInfo) {
|
||||
constructor(nodeInfo: NodeInfo, signer: (PublicKey, SerializedBytes<NodeInfo>) -> DigitalSignature) : this(nodeInfo, nodeInfo.sign(signer))
|
||||
constructor(signedNodeInfo: SignedNodeInfo) : this(signedNodeInfo.verified(), signedNodeInfo)
|
||||
|
||||
operator fun component1(): NodeInfo = nodeInfo
|
||||
operator fun component2(): SignedNodeInfo = signed
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ import kotlin.concurrent.withLock
|
||||
* The Netty thread pool used by the AMQPBridges is also shared and managed by the AMQPBridgeManager.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
class AMQPBridgeManager(config: NodeSSLConfiguration, val artemisMessageClientFactory: () -> ArtemisSessionProvider) : BridgeManager {
|
||||
class AMQPBridgeManager(config: NodeSSLConfiguration, private val artemisMessageClientFactory: () -> ArtemisSessionProvider) : BridgeManager {
|
||||
|
||||
private val lock = ReentrantLock()
|
||||
private val bridgeNameToBridgeMap = mutableMapOf<String, AMQPBridge>()
|
||||
|
@ -6,6 +6,6 @@ data class User(
|
||||
val password: String,
|
||||
val permissions: Set<String>) {
|
||||
override fun toString(): String = "${javaClass.simpleName}($username, permissions=$permissions)"
|
||||
@Deprecated("Use toConfig().root().unwrapped() instead")
|
||||
@Deprecated("Use toConfig().root().unwrapped() instead", ReplaceWith("toConfig().root().unwrapped()"))
|
||||
fun toMap(): Map<String, Any> = toConfig().root().unwrapped()
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import java.security.cert.X509Certificate
|
||||
import java.time.Instant
|
||||
|
||||
|
||||
const val NETWORK_PARAMS_FILE_NAME = "network-parameters"
|
||||
const val NETWORK_PARAMS_UPDATE_FILE_NAME = "network-parameters-update"
|
||||
|
||||
@ -71,6 +70,7 @@ fun <T : Any> SignedDataWithCert<T>.verifiedNetworkMapCert(rootCert: X509Certifi
|
||||
class NetworkMapAndSigned private constructor(val networkMap: NetworkMap, val signed: SignedNetworkMap) {
|
||||
constructor(networkMap: NetworkMap, signer: (SerializedBytes<NetworkMap>) -> DigitalSignatureWithCert) : this(networkMap, networkMap.signWithCert(signer))
|
||||
constructor(signed: SignedNetworkMap) : this(signed.verified(), signed)
|
||||
|
||||
operator fun component1(): NetworkMap = networkMap
|
||||
operator fun component2(): SignedNetworkMap = signed
|
||||
}
|
||||
|
@ -258,9 +258,8 @@ fun <T : Any> rx.Observable<T>.wrapWithDatabaseTransaction(db: CordaPersistence?
|
||||
|
||||
/** Check if any nested cause is of [SQLException] type. */
|
||||
private fun Throwable.hasSQLExceptionCause(): Boolean =
|
||||
if (cause == null)
|
||||
false
|
||||
else if (cause is SQLException)
|
||||
true
|
||||
else
|
||||
cause?.hasSQLExceptionCause() ?: false
|
||||
when (cause) {
|
||||
null -> false
|
||||
is SQLException -> true
|
||||
else -> cause?.hasSQLExceptionCause() ?: false
|
||||
}
|
@ -156,7 +156,7 @@ class HibernateConfiguration(
|
||||
|
||||
// A tweaked version of `org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor` that truncates logged messages.
|
||||
private object CordaPrimitiveByteArrayTypeDescriptor : PrimitiveByteArrayTypeDescriptor() {
|
||||
private val LOG_SIZE_LIMIT = 1024
|
||||
private const val LOG_SIZE_LIMIT = 1024
|
||||
|
||||
override fun extractLoggableRepresentation(value: ByteArray?): String {
|
||||
return if (value == null) {
|
||||
|
@ -62,6 +62,7 @@ internal class ConnectionStateMachine(serverMode: Boolean,
|
||||
transport = Engine.transport()
|
||||
transport.idleTimeout = IDLE_TIMEOUT
|
||||
transport.context = connection
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
transport.setEmitFlowEventOnSend(true)
|
||||
connection.collect(collector)
|
||||
val sasl = transport.sasl()
|
||||
|
@ -90,7 +90,7 @@ class AMQPServer(val hostName: String,
|
||||
parent.password,
|
||||
parent.trace,
|
||||
{
|
||||
parent.clientChannels.put(it.first.remoteAddress(), it.first)
|
||||
parent.clientChannels[it.first.remoteAddress()] = it.first
|
||||
parent._onConnection.onNext(it.second)
|
||||
},
|
||||
{
|
||||
@ -194,5 +194,4 @@ class AMQPServer(val hostName: String,
|
||||
private val _onConnection = PublishSubject.create<ConnectionChange>().toSerialized()
|
||||
val onConnection: Observable<ConnectionChange>
|
||||
get() = _onConnection
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
@file:JvmName("ByteBufferStreams")
|
||||
|
||||
package net.corda.nodeapi.internal.serialization
|
||||
|
||||
import net.corda.core.internal.LazyPool
|
||||
@ -10,9 +11,9 @@ import java.nio.ByteBuffer
|
||||
import kotlin.math.min
|
||||
|
||||
internal val serializeOutputStreamPool = LazyPool(
|
||||
clear = ByteBufferOutputStream::reset,
|
||||
shouldReturnToPool = { it.size() < 256 * 1024 }, // Discard if it grew too large
|
||||
newInstance = { ByteBufferOutputStream(64 * 1024) })
|
||||
clear = ByteBufferOutputStream::reset,
|
||||
shouldReturnToPool = { it.size() < 256 * 1024 }, // Discard if it grew too large
|
||||
newInstance = { ByteBufferOutputStream(64 * 1024) })
|
||||
|
||||
internal fun <T> byteArrayOutput(task: (ByteBufferOutputStream) -> T): ByteArray {
|
||||
return serializeOutputStreamPool.run { underlying ->
|
||||
|
@ -46,7 +46,7 @@ class SerializeAsTokenContextImpl(override val serviceHub: ServiceHub, init: Ser
|
||||
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.")
|
||||
throw UnsupportedOperationException("Attempt to write token for lazy registered $className. All tokens should be registered during context construction.")
|
||||
}
|
||||
classNameToSingleton[className] = toBeTokenized
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import java.lang.reflect.Type
|
||||
* [ByteArray] is automatically marshalled to/from the Proton-J wrapper, [Binary].
|
||||
*/
|
||||
class AMQPPrimitiveSerializer(clazz: Class<*>) : AMQPSerializer<Any> {
|
||||
override val typeDescriptor = Symbol.valueOf(SerializerFactory.primitiveTypeName(clazz)!!)
|
||||
override val typeDescriptor = Symbol.valueOf(SerializerFactory.primitiveTypeName(clazz)!!)!!
|
||||
override val type: Type = clazz
|
||||
|
||||
// NOOP since this is a primitive type.
|
||||
|
@ -68,6 +68,7 @@ abstract class AbstractAMQPSerializationScheme(
|
||||
val List<Cordapp>.customSerializers get() = flatMap { it.serializationCustomSerializers }.toSet()
|
||||
}
|
||||
|
||||
// Parameter "context" is unused directy but passed in by reflection. Removing it will cause failures.
|
||||
private fun registerCustomSerializers(context: SerializationContext, factory: SerializerFactory) {
|
||||
with(factory) {
|
||||
register(publicKeySerializer)
|
||||
|
@ -1,4 +1,5 @@
|
||||
@file:JvmName("AMQPSerializerFactories")
|
||||
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
|
@ -1,4 +1,5 @@
|
||||
@file:JvmName("AMQPStreams")
|
||||
|
||||
package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.ByteBufferInputStream
|
||||
|
@ -32,7 +32,7 @@ open class ArraySerializer(override val type: Type, factory: SerializerFactory)
|
||||
"${type.componentType().typeName}$arrayType"
|
||||
}
|
||||
|
||||
override val typeDescriptor by lazy {
|
||||
override val typeDescriptor: Symbol by lazy {
|
||||
Symbol.valueOf("$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
|
||||
}
|
||||
internal val elementType: Type by lazy { type.componentType() }
|
||||
@ -95,7 +95,7 @@ abstract class PrimArraySerializer(type: Type, factory: SerializerFactory) : Arr
|
||||
companion object {
|
||||
// We don't need to handle the unboxed byte type as that is coercible to a byte array, but
|
||||
// the other 7 primitive types we do
|
||||
val primTypes: Map<Type, (SerializerFactory) -> PrimArraySerializer> = mapOf(
|
||||
private val primTypes: Map<Type, (SerializerFactory) -> PrimArraySerializer> = mapOf(
|
||||
IntArray::class.java to { f -> PrimIntArraySerializer(f) },
|
||||
CharArray::class.java to { f -> PrimCharArraySerializer(f) },
|
||||
BooleanArray::class.java to { f -> PrimBooleanArraySerializer(f) },
|
||||
|
@ -14,10 +14,10 @@ import kotlin.collections.LinkedHashSet
|
||||
/**
|
||||
* Serialization / deserialization of predefined set of supported [Collection] types covering mostly [List]s and [Set]s.
|
||||
*/
|
||||
class CollectionSerializer(val declaredType: ParameterizedType, factory: SerializerFactory) : AMQPSerializer<Any> {
|
||||
class CollectionSerializer(private val declaredType: ParameterizedType, factory: SerializerFactory) : AMQPSerializer<Any> {
|
||||
override val type: Type = declaredType as? DeserializedParameterizedType
|
||||
?: DeserializedParameterizedType.make(SerializerFactory.nameForType(declaredType))
|
||||
override val typeDescriptor by lazy {
|
||||
override val typeDescriptor: Symbol by lazy {
|
||||
Symbol.valueOf("$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
|
||||
}
|
||||
|
||||
@ -53,10 +53,8 @@ class CollectionSerializer(val declaredType: ParameterizedType, factory: Seriali
|
||||
(declaredType as? ParameterizedType)
|
||||
?: DeserializedParameterizedType(collectionClass, arrayOf(SerializerFactory.AnyType))
|
||||
|
||||
|
||||
private fun findMostSuitableCollectionType(actualClass: Class<*>): Class<out Collection<*>> =
|
||||
supportedTypes.keys.findLast { it.isAssignableFrom(actualClass) }!!
|
||||
|
||||
}
|
||||
|
||||
private val concreteBuilder: (List<*>) -> Collection<*> = findConcreteType(declaredType.rawType as Class<*>)
|
||||
|
@ -59,7 +59,7 @@ class CorDappCustomSerializer(
|
||||
|
||||
override val type = types[CORDAPP_TYPE]
|
||||
val proxyType = types[PROXY_TYPE]
|
||||
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${nameForType(type)}")
|
||||
override val typeDescriptor: Symbol = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${nameForType(type)}")
|
||||
val descriptor: Descriptor = Descriptor(typeDescriptor)
|
||||
private val proxySerializer: ObjectSerializer by lazy { ObjectSerializer(proxyType, factory) }
|
||||
|
||||
|
@ -64,7 +64,7 @@ abstract class CustomSerializer<T : Any> : AMQPSerializer<T>, SerializerFor {
|
||||
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = clazz == this.clazz
|
||||
override val type: Type get() = clazz
|
||||
override val typeDescriptor by lazy {
|
||||
override val typeDescriptor: Symbol by lazy {
|
||||
Symbol.valueOf("$DESCRIPTOR_DOMAIN:${SerializerFingerPrinter().fingerprintForDescriptors(superClassSerializer.typeDescriptor.toString(), nameForType(clazz))}")
|
||||
}
|
||||
private val typeNotation: TypeNotation = RestrictedType(
|
||||
@ -100,7 +100,7 @@ abstract class CustomSerializer<T : Any> : AMQPSerializer<T>, SerializerFor {
|
||||
*/
|
||||
abstract class CustomSerializerImp<T : Any>(protected val clazz: Class<T>, protected val withInheritance: Boolean) : CustomSerializer<T>() {
|
||||
override val type: Type get() = clazz
|
||||
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${nameForType(clazz)}")
|
||||
override val typeDescriptor: Symbol = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${nameForType(clazz)}")
|
||||
override fun writeClassInfo(output: SerializationOutput) {}
|
||||
override val descriptor: Descriptor = Descriptor(typeDescriptor)
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = if (withInheritance) this.clazz.isAssignableFrom(clazz) else this.clazz == clazz
|
||||
|
@ -8,7 +8,6 @@ import net.corda.core.utilities.ByteSequence
|
||||
import net.corda.nodeapi.internal.serialization.*
|
||||
import org.apache.qpid.proton.amqp.Binary
|
||||
import org.apache.qpid.proton.amqp.DescribedType
|
||||
import org.apache.qpid.proton.amqp.UnsignedByte
|
||||
import org.apache.qpid.proton.amqp.UnsignedInteger
|
||||
import org.apache.qpid.proton.codec.Data
|
||||
import java.io.InputStream
|
||||
@ -32,28 +31,6 @@ class DeserializationInput @JvmOverloads constructor(private val serializerFacto
|
||||
private val objectHistory: MutableList<Any> = mutableListOf()
|
||||
|
||||
companion object {
|
||||
private const val BYTES_NEEDED_TO_PEEK: Int = 23
|
||||
|
||||
fun peekSize(bytes: ByteArray): Int {
|
||||
// There's an 8 byte header, and then a 0 byte plus descriptor followed by constructor
|
||||
val eighth = bytes[8].toInt()
|
||||
check(eighth == 0x0) { "Expected to find a descriptor in the AMQP stream" }
|
||||
// We should always have an Envelope, so the descriptor should be a 64-bit long (0x80)
|
||||
val ninth = UnsignedByte.valueOf(bytes[9]).toInt()
|
||||
check(ninth == 0x80) { "Expected to find a ulong in the AMQP stream" }
|
||||
// Skip 8 bytes
|
||||
val eighteenth = UnsignedByte.valueOf(bytes[18]).toInt()
|
||||
check(eighteenth == 0xd0 || eighteenth == 0xc0) { "Expected to find a list8 or list32 in the AMQP stream" }
|
||||
val size = if (eighteenth == 0xc0) {
|
||||
// Next byte is size
|
||||
UnsignedByte.valueOf(bytes[19]).toInt() - 3 // Minus three as PEEK_SIZE assumes 4 byte unsigned integer.
|
||||
} else {
|
||||
// Next 4 bytes is size
|
||||
UnsignedByte.valueOf(bytes[19]).toInt().shl(24) + UnsignedByte.valueOf(bytes[20]).toInt().shl(16) + UnsignedByte.valueOf(bytes[21]).toInt().shl(8) + UnsignedByte.valueOf(bytes[22]).toInt()
|
||||
}
|
||||
return size + BYTES_NEEDED_TO_PEEK
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Throws(NotSerializableException::class)
|
||||
fun <T> withDataBytes(byteSequence: ByteSequence, encodingWhitelist: EncodingWhitelist, task: (ByteBuffer) -> T): T {
|
||||
@ -140,13 +117,12 @@ class DeserializationInput @JvmOverloads constructor(private val serializerFacto
|
||||
envelope)
|
||||
}
|
||||
|
||||
internal fun readObjectOrNull(obj: Any?, schema: SerializationSchemas, type: Type, context: SerializationContext,
|
||||
offset: Int = 0
|
||||
internal fun readObjectOrNull(obj: Any?, schema: SerializationSchemas, type: Type, context: SerializationContext
|
||||
): Any? {
|
||||
return if (obj == null) null else readObject(obj, schema, type, context, offset)
|
||||
return if (obj == null) null else readObject(obj, schema, type, context)
|
||||
}
|
||||
|
||||
internal fun readObject(obj: Any, schemas: SerializationSchemas, type: Type, context: SerializationContext, debugIndent: Int = 0): Any =
|
||||
internal fun readObject(obj: Any, schemas: SerializationSchemas, type: Type, context: SerializationContext): Any =
|
||||
if (obj is DescribedType && ReferencedObject.DESCRIPTOR == obj.descriptor) {
|
||||
// It must be a reference to an instance that has already been read, cheaply and quickly returning it by reference.
|
||||
val objectIndex = (obj.described as UnsignedInteger).toInt()
|
||||
|
@ -28,7 +28,7 @@ class DeserializedParameterizedType(private val rawType: Class<*>, private val p
|
||||
private val _typeName: String = makeTypeName()
|
||||
|
||||
private fun makeTypeName(): String {
|
||||
val paramsJoined = params.map { it.typeName }.joinToString(", ")
|
||||
val paramsJoined = params.joinToString(", ") { it.typeName }
|
||||
return "${rawType.name}<$paramsJoined>"
|
||||
}
|
||||
|
||||
@ -145,14 +145,14 @@ class DeserializedParameterizedType(private val rawType: Class<*>, private val p
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is ParameterizedType) {
|
||||
return if (other is ParameterizedType) {
|
||||
if (this === other) {
|
||||
return true
|
||||
true
|
||||
} else {
|
||||
return this.ownerType == other.ownerType && this.rawType == other.rawType && Arrays.equals(this.actualTypeArguments, other.actualTypeArguments)
|
||||
this.ownerType == other.ownerType && this.rawType == other.rawType && Arrays.equals(this.actualTypeArguments, other.actualTypeArguments)
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
@ -91,7 +91,7 @@ abstract class EvolutionSerializer(
|
||||
val constructorArgs = arrayOfNulls<Any?>(constructor.parameters.size)
|
||||
|
||||
constructor.parameters.withIndex().forEach {
|
||||
readersAsSerialized.get(it.value.name!!)?.apply {
|
||||
readersAsSerialized[it.value.name!!]?.apply {
|
||||
this.resultsIndex = it.index
|
||||
} ?: if (!it.value.type.isMarkedNullable) {
|
||||
throw NotSerializableException(
|
||||
|
@ -94,7 +94,7 @@ class SerializerFingerPrinter : FingerPrinter {
|
||||
// serialise the object in the first place (and thus the cache lookup fails). This is also
|
||||
// true of Any, where we need Example<A, B> and Example<?, ?> to have the same fingerprint
|
||||
return if ((type in alreadySeen)
|
||||
&& (type !is SerializerFactory.AnyType)
|
||||
&& (type !== SerializerFactory.AnyType)
|
||||
&& (type !is TypeVariable<*>)
|
||||
&& (type !is WildcardType)) {
|
||||
hasher.putUnencodedChars(ALREADY_SEEN_HASH)
|
||||
|
@ -23,7 +23,7 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS
|
||||
private val logger = contextLogger()
|
||||
}
|
||||
|
||||
open internal val propertySerializers: PropertySerializers by lazy {
|
||||
internal open val propertySerializers: PropertySerializers by lazy {
|
||||
propertiesForSerialization(kotlinConstructor, clazz, factory)
|
||||
}
|
||||
|
||||
@ -32,12 +32,12 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS
|
||||
private val typeName = nameForType(clazz)
|
||||
|
||||
override val typeDescriptor = Symbol.valueOf(
|
||||
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
|
||||
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")!!
|
||||
|
||||
// We restrict to only those annotated or whitelisted
|
||||
private val interfaces = interfacesForSerialization(clazz, factory)
|
||||
|
||||
open internal val typeNotation: TypeNotation by lazy {
|
||||
internal open val typeNotation: TypeNotation by lazy {
|
||||
CompositeType(typeName, null, generateProvides(), Descriptor(typeDescriptor), generateFields())
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ class PrivatePropertyReader(val field: Field, parentType: Type) : PropertyReader
|
||||
// So this used to report as an error, but given we serialise exceptions all the time it
|
||||
// provides for very scary log files so move this to trace level
|
||||
loggerFor<PropertySerializer>().let { logger ->
|
||||
logger.trace("Using kotlin introspection on internal type ${field}")
|
||||
logger.trace("Using kotlin introspection on internal type $field")
|
||||
logger.trace("Unexpected internal Kotlin error", e)
|
||||
}
|
||||
true
|
||||
|
@ -124,18 +124,18 @@ open class SerializationOutput @JvmOverloads constructor(
|
||||
// assigned to them first as they will be first read from the stream on receiving end.
|
||||
// Skip for primitive types as they are too small and overhead of referencing them will be much higher than their content
|
||||
if (suitableForObjectReference(obj.javaClass)) {
|
||||
objectHistory.put(obj, objectHistory.size)
|
||||
objectHistory[obj] = objectHistory.size
|
||||
}
|
||||
} else {
|
||||
data.writeReferencedObject(ReferencedObject(retrievedRefCount))
|
||||
}
|
||||
}
|
||||
|
||||
open internal fun writeTypeNotations(vararg typeNotation: TypeNotation): Boolean {
|
||||
internal open fun writeTypeNotations(vararg typeNotation: TypeNotation): Boolean {
|
||||
return schemaHistory.addAll(typeNotation)
|
||||
}
|
||||
|
||||
open internal fun requireSerializer(type: Type) {
|
||||
internal open fun requireSerializer(type: Type) {
|
||||
if (type != SerializerFactory.AnyType && type != Object::class.java) {
|
||||
val serializer = serializerFactory.get(null, type)
|
||||
if (serializer !in serializerHistory) {
|
||||
|
@ -144,7 +144,7 @@ open class SerializerFactory(
|
||||
return if (actualClass.typeParameters.isNotEmpty()) {
|
||||
// The actual class can never have type variables resolved, due to the JVM's use of type erasure, so let's try and resolve them
|
||||
// Search for declared type in the inheritance hierarchy and then see if that fills in all the variables
|
||||
val implementationChain: List<Type>? = findPathToDeclared(actualClass, declaredType, mutableListOf<Type>())
|
||||
val implementationChain: List<Type>? = findPathToDeclared(actualClass, declaredType, mutableListOf())
|
||||
if (implementationChain != null) {
|
||||
val start = implementationChain.last()
|
||||
val rest = implementationChain.dropLast(1).drop(1)
|
||||
@ -305,6 +305,7 @@ open class SerializerFactory(
|
||||
return if (declaredSuperClass == null
|
||||
|| !customSerializer.isSerializerFor(declaredSuperClass)
|
||||
|| !customSerializer.revealSubclassesInSchema) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
customSerializer as? AMQPSerializer<Any>
|
||||
} else {
|
||||
// Make a subclass serializer for the subclass and return that...
|
||||
|
@ -12,7 +12,7 @@ import java.lang.reflect.Type
|
||||
*/
|
||||
class SingletonSerializer(override val type: Class<*>, val singleton: Any, factory: SerializerFactory) : AMQPSerializer<Any> {
|
||||
override val typeDescriptor = Symbol.valueOf(
|
||||
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
|
||||
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")!!
|
||||
|
||||
private val interfaces = interfacesForSerialization(type, factory)
|
||||
|
||||
|
@ -72,7 +72,7 @@ abstract class Transform : DescribedType {
|
||||
*/
|
||||
class UnknownTransform : Transform() {
|
||||
companion object : DescribedTypeConstructor<UnknownTransform> {
|
||||
val typeName = "UnknownTransform"
|
||||
const val typeName = "UnknownTransform"
|
||||
|
||||
override fun newInstance(obj: Any?) = UnknownTransform()
|
||||
|
||||
@ -90,7 +90,7 @@ class UnknownTransform : Transform() {
|
||||
*/
|
||||
class UnknownTestTransform(val a: Int, val b: Int, val c: Int) : Transform() {
|
||||
companion object : DescribedTypeConstructor<UnknownTestTransform> {
|
||||
val typeName = "UnknownTest"
|
||||
const val typeName = "UnknownTest"
|
||||
|
||||
override fun newInstance(obj: Any?): UnknownTestTransform {
|
||||
val described = obj as List<*>
|
||||
@ -117,7 +117,7 @@ class EnumDefaultSchemaTransform(val old: String, val new: String) : Transform()
|
||||
/**
|
||||
* Value encoded into the schema that identifies a transform as this type
|
||||
*/
|
||||
val typeName = "EnumDefault"
|
||||
const val typeName = "EnumDefault"
|
||||
|
||||
override fun newInstance(obj: Any?): EnumDefaultSchemaTransform {
|
||||
val described = obj as List<*>
|
||||
@ -154,7 +154,7 @@ class RenameSchemaTransform(val from: String, val to: String) : Transform() {
|
||||
/**
|
||||
* Value encoded into the schema that identifies a transform as this type
|
||||
*/
|
||||
val typeName = "Rename"
|
||||
const val typeName = "Rename"
|
||||
|
||||
override fun newInstance(obj: Any?): RenameSchemaTransform {
|
||||
val described = obj as List<*>
|
||||
@ -213,9 +213,7 @@ data class TransformsSchema(val types: Map<String, EnumMap<TransformTypes, Mutab
|
||||
// we're explicitly rejecting repeated annotations, whilst it's fine and we'd just
|
||||
// ignore them it feels like a good thing to alert the user to since this is
|
||||
// more than likely a typo in their code so best make it an actual error
|
||||
if (transforms.computeIfAbsent(transform.enum) { mutableListOf() }
|
||||
.filter { t == it }
|
||||
.isNotEmpty()) {
|
||||
if (transforms.computeIfAbsent(transform.enum) { mutableListOf() }.any { t == it }) {
|
||||
throw NotSerializableException(
|
||||
"Repeated unique transformation annotation of type ${t.name}")
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.corda.nodeapi.internal.serialization.amqp.custom
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.amqp.CustomSerializer
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory
|
||||
import java.lang.reflect.Method
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
@ -14,7 +15,7 @@ class ZonedDateTimeSerializer(factory: SerializerFactory) : CustomSerializer.Pro
|
||||
// Java deserialization of `ZonedDateTime` uses a private method. We will resolve this somewhat statically
|
||||
// so that any change to internals of `ZonedDateTime` is detected early.
|
||||
companion object {
|
||||
val ofLenient = ZonedDateTime::class.java.getDeclaredMethod("ofLenient", LocalDateTime::class.java, ZoneOffset::class.java, ZoneId::class.java)
|
||||
val ofLenient: Method = ZonedDateTime::class.java.getDeclaredMethod("ofLenient", LocalDateTime::class.java, ZoneOffset::class.java, ZoneId::class.java)
|
||||
|
||||
init {
|
||||
ofLenient.isAccessible = true
|
||||
|
@ -124,14 +124,14 @@ fun String.stripGenerics(): String = if (this.endsWith('>')) {
|
||||
this.substring(0, this.indexOf('<'))
|
||||
} else this
|
||||
|
||||
fun AMQPField.getTypeAsClass(classloader: ClassLoader) = typeStrToType[Pair(type, mandatory)] ?: when (type) {
|
||||
fun AMQPField.getTypeAsClass(classloader: ClassLoader) = (typeStrToType[Pair(type, mandatory)] ?: when (type) {
|
||||
"string" -> String::class.java
|
||||
"binary" -> ByteArray::class.java
|
||||
"*" -> if (requires.isEmpty()) Any::class.java else {
|
||||
classloader.loadClass(requires[0].stripGenerics())
|
||||
}
|
||||
else -> classloader.loadClass(type.stripGenerics())
|
||||
}
|
||||
})!!
|
||||
|
||||
fun AMQPField.validateType(classloader: ClassLoader) =
|
||||
when (type) {
|
||||
|
@ -6,7 +6,7 @@ import com.esotericsoftware.kryo.serializers.ClosureSerializer
|
||||
import java.io.Serializable
|
||||
|
||||
object CordaClosureSerializer : ClosureSerializer() {
|
||||
val ERROR_MESSAGE = "Unable to serialize Java Lambda expression, unless explicitly declared e.g., Runnable r = (Runnable & Serializable) () -> System.out.println(\"Hello world!\");"
|
||||
const val ERROR_MESSAGE = "Unable to serialize Java Lambda expression, unless explicitly declared e.g., Runnable r = (Runnable & Serializable) () -> System.out.println(\"Hello world!\");"
|
||||
|
||||
override fun write(kryo: Kryo, output: Output, target: Any) {
|
||||
if (!isSerializable(target)) {
|
||||
@ -21,7 +21,7 @@ object CordaClosureSerializer : ClosureSerializer() {
|
||||
}
|
||||
|
||||
object CordaClosureBlacklistSerializer : ClosureSerializer() {
|
||||
val ERROR_MESSAGE = "Java 8 Lambda expressions are not supported for serialization."
|
||||
const val ERROR_MESSAGE = "Java 8 Lambda expressions are not supported for serialization."
|
||||
|
||||
override fun write(kryo: Kryo, output: Output, target: Any) {
|
||||
throw IllegalArgumentException(ERROR_MESSAGE)
|
||||
|
@ -216,6 +216,7 @@ object DefaultKryoCustomizer {
|
||||
if (kryo.serializationContext() != null) {
|
||||
val attachmentHash = SecureHash.SHA256(input.readBytes(32))
|
||||
val contract = input.readString()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val additionalContracts = kryo.readClassAndObject(input) as Set<ContractClassName>
|
||||
val uploader = input.readString()
|
||||
val context = kryo.serializationContext()!!
|
||||
@ -233,6 +234,7 @@ object DefaultKryoCustomizer {
|
||||
} else {
|
||||
val attachment = GeneratedAttachment(input.readBytesWithLength())
|
||||
val contract = input.readString()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val additionalContracts = kryo.readClassAndObject(input) as Set<ContractClassName>
|
||||
val uploader = input.readString()
|
||||
return ContractAttachment(attachment, contract, additionalContracts, uploader)
|
||||
|
@ -1,4 +1,5 @@
|
||||
@file:JvmName("KryoStreams")
|
||||
|
||||
package net.corda.nodeapi.internal.serialization.kryo
|
||||
|
||||
import com.esotericsoftware.kryo.io.Input
|
||||
|
@ -43,7 +43,7 @@ public final class ForbiddenLambdaSerializationTests {
|
||||
assertThat(throwable).isNotNull();
|
||||
assertThat(throwable).isInstanceOf(IllegalArgumentException.class);
|
||||
if (ctx != SerializationContext.UseCase.RPCServer && ctx != SerializationContext.UseCase.Storage) {
|
||||
assertThat(throwable).hasMessage(CordaClosureBlacklistSerializer.INSTANCE.getERROR_MESSAGE());
|
||||
assertThat(throwable).hasMessage(CordaClosureBlacklistSerializer.ERROR_MESSAGE);
|
||||
} else {
|
||||
assertThat(throwable).hasMessageContaining("RPC not allowed to deserialise internal classes");
|
||||
}
|
||||
@ -65,7 +65,7 @@ public final class ForbiddenLambdaSerializationTests {
|
||||
assertThat(throwable).isInstanceOf(IllegalArgumentException.class);
|
||||
assertThat(throwable).isInstanceOf(IllegalArgumentException.class);
|
||||
if (ctx != SerializationContext.UseCase.RPCServer && ctx != SerializationContext.UseCase.Storage) {
|
||||
assertThat(throwable).hasMessage(CordaClosureBlacklistSerializer.INSTANCE.getERROR_MESSAGE());
|
||||
assertThat(throwable).hasMessage(CordaClosureBlacklistSerializer.ERROR_MESSAGE);
|
||||
} else {
|
||||
assertThat(throwable).hasMessageContaining("RPC not allowed to deserialise internal classes");
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public final class LambdaCheckpointSerializationTest {
|
||||
|
||||
assertThat(throwable).isNotNull();
|
||||
assertThat(throwable).isInstanceOf(IllegalArgumentException.class);
|
||||
assertThat(throwable).hasMessage(CordaClosureSerializer.INSTANCE.getERROR_MESSAGE());
|
||||
assertThat(throwable).hasMessage(CordaClosureSerializer.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
private <T> SerializedBytes<T> serialize(final T target) {
|
||||
|
@ -2,7 +2,6 @@ package net.corda.nodeapi.internal.serialization.amqp;
|
||||
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist;
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.TestSerializationContext;
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.TestSerializationContextKt;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import kotlin.Suppress;
|
||||
import net.corda.core.contracts.ContractState;
|
||||
import net.corda.core.identity.AbstractParty;
|
||||
import net.corda.core.serialization.SerializedBytes;
|
||||
|
@ -1,21 +1,16 @@
|
||||
package net.corda.nodeapi.internal.serialization.amqp;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.corda.core.contracts.ContractState;
|
||||
import net.corda.core.identity.AbstractParty;
|
||||
import net.corda.core.serialization.ConstructorForDeserialization;
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist;
|
||||
import net.corda.core.serialization.SerializedBytes;
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.TestSerializationContext;
|
||||
import org.apache.qpid.proton.codec.DecoderImpl;
|
||||
import org.apache.qpid.proton.codec.EncoderImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.NotSerializableException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -11,7 +11,7 @@ import java.util.Map;
|
||||
|
||||
public class TestSerializationContext {
|
||||
|
||||
static private Map<Object, Object> serializationProperties = new HashMap<Object, Object>();
|
||||
private static Map<Object, Object> serializationProperties = new HashMap<>();
|
||||
|
||||
public static SerializationContext testSerializationContext = new SerializationContextImpl(
|
||||
ByteSequence.of(new byte[] { 'c', 'o', 'r', 'd', 'a', (byte)0, (byte)0, (byte)1}),
|
||||
|
@ -36,7 +36,7 @@ class AttachmentsClassLoaderStaticContractTests {
|
||||
|
||||
class AttachmentDummyContract : Contract {
|
||||
companion object {
|
||||
private val ATTACHMENT_PROGRAM_ID = "net.corda.nodeapi.internal.AttachmentsClassLoaderStaticContractTests\$AttachmentDummyContract"
|
||||
private const val ATTACHMENT_PROGRAM_ID = "net.corda.nodeapi.internal.AttachmentsClassLoaderStaticContractTests\$AttachmentDummyContract"
|
||||
}
|
||||
|
||||
data class State(val magicNumber: Int = 0) : ContractState {
|
||||
|
@ -10,7 +10,12 @@ import net.corda.core.internal.declaredField
|
||||
import net.corda.core.internal.toWireTransaction
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.AttachmentStorage
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.MissingAttachmentsException
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.SerializationFactory
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.ByteSequence
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.node.internal.cordapp.CordappLoader
|
||||
@ -28,10 +33,12 @@ import net.corda.testing.internal.kryoSpecific
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
import net.corda.testing.services.MockAttachmentStorage
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
@ -125,6 +132,7 @@ class AttachmentsClassLoaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Suppress("DEPRECATION")
|
||||
fun `test overlapping file exception`() {
|
||||
val storage = attachments
|
||||
val att0 = attachmentId
|
||||
@ -137,7 +145,8 @@ class AttachmentsClassLoaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `basic`() {
|
||||
@Suppress("DEPRECATION")
|
||||
fun basic() {
|
||||
val storage = attachments
|
||||
val att0 = attachmentId
|
||||
val att1 = storage.importAttachment(fakeAttachment("file1.txt", "some data").inputStream())
|
||||
@ -149,6 +158,7 @@ class AttachmentsClassLoaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Suppress("DEPRECATION")
|
||||
fun `Check platform independent path handling in attachment jars`() {
|
||||
val storage = MockAttachmentStorage()
|
||||
|
||||
@ -169,6 +179,7 @@ class AttachmentsClassLoaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Suppress("DEPRECATION")
|
||||
fun `loading class AnotherDummyContract`() {
|
||||
val storage = attachments
|
||||
val att0 = attachmentId
|
||||
@ -190,6 +201,7 @@ class AttachmentsClassLoaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Suppress("DEPRECATION")
|
||||
fun `testing Kryo with ClassLoader (with top level class name)`() {
|
||||
val contract = createContract2Cash()
|
||||
|
||||
@ -212,6 +224,7 @@ class AttachmentsClassLoaderTests {
|
||||
class Data(val contract: Contract)
|
||||
|
||||
@Test
|
||||
@Suppress("DEPRECATION")
|
||||
fun `testing Kryo with ClassLoader (without top level class name)`() {
|
||||
val data = Data(createContract2Cash())
|
||||
|
||||
|
@ -18,7 +18,6 @@ import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.security.KeyPair
|
||||
import java.security.PrivateKey
|
||||
import java.security.PublicKey
|
||||
import java.security.SignatureException
|
||||
|
||||
|
@ -18,32 +18,32 @@ import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
class ConfigParsingTest {
|
||||
@Test
|
||||
fun `String`() {
|
||||
fun String() {
|
||||
testPropertyType<StringData, StringListData, String>("hello world!", "bye")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Int`() {
|
||||
fun Int() {
|
||||
testPropertyType<IntData, IntListData, Int>(1, 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Long`() {
|
||||
fun Long() {
|
||||
testPropertyType<LongData, LongListData, Long>(Long.MAX_VALUE, Long.MIN_VALUE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Double`() {
|
||||
fun Double() {
|
||||
testPropertyType<DoubleData, DoubleListData, Double>(1.2, 3.4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Boolean`() {
|
||||
fun Boolean() {
|
||||
testPropertyType<BooleanData, BooleanListData, Boolean>(true, false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Enum`() {
|
||||
fun Enum() {
|
||||
testPropertyType<EnumData, EnumListData, TestEnum>(TestEnum.Value2, TestEnum.Value1, valuesToString = true)
|
||||
}
|
||||
|
||||
@ -56,17 +56,17 @@ class ConfigParsingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `LocalDate`() {
|
||||
fun LocalDate() {
|
||||
testPropertyType<LocalDateData, LocalDateListData, LocalDate>(LocalDate.now(), LocalDate.now().plusDays(1), valuesToString = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Instant`() {
|
||||
fun Instant() {
|
||||
testPropertyType<InstantData, InstantListData, Instant>(Instant.now(), Instant.now().plusMillis(100), valuesToString = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NetworkHostAndPort`() {
|
||||
fun NetworkHostAndPort() {
|
||||
testPropertyType<NetworkHostAndPortData, NetworkHostAndPortListData, NetworkHostAndPort>(
|
||||
NetworkHostAndPort("localhost", 2223),
|
||||
NetworkHostAndPort("localhost", 2225),
|
||||
@ -74,18 +74,18 @@ class ConfigParsingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Path`() {
|
||||
fun Path() {
|
||||
val path = "tmp" / "test"
|
||||
testPropertyType<PathData, PathListData, Path>(path, path / "file", valuesToString = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `URL`() {
|
||||
fun URL() {
|
||||
testPropertyType<URLData, URLListData, URL>(URL("http://localhost:1234"), URL("http://localhost:1235"), valuesToString = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `UUID`() {
|
||||
fun UUID() {
|
||||
testPropertyType<UUIDData, UUIDListData, UUID>(UUID.randomUUID(), UUID.randomUUID(), valuesToString = true)
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ class ConfigParsingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Set`() {
|
||||
fun Set() {
|
||||
val data = StringSetData(setOf("a", "b"))
|
||||
assertThat(config("values" to listOf("a", "a", "b")).parseAs<StringSetData>()).isEqualTo(data)
|
||||
assertThat(data.toConfig()).isEqualTo(config("values" to listOf("a", "b")))
|
||||
|
@ -14,7 +14,6 @@ import rx.schedulers.TestScheduler
|
||||
import java.nio.file.Path
|
||||
import java.time.Duration
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.streams.toList
|
||||
|
||||
class NodeInfoFilesCopierTest {
|
||||
companion object {
|
||||
@ -113,7 +112,7 @@ class NodeInfoFilesCopierTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clear`() {
|
||||
fun clear() {
|
||||
// Configure 2 nodes.
|
||||
nodeInfoFilesCopier.addConfig(node1RootPath)
|
||||
nodeInfoFilesCopier.addConfig(node2RootPath)
|
||||
|
@ -55,7 +55,7 @@ class MapsSerializationTest {
|
||||
val wrongPayloadType = WrongPayloadType(payload)
|
||||
assertThatThrownBy { wrongPayloadType.serialize() }
|
||||
.isInstanceOf(IllegalArgumentException::class.java).hasMessageContaining(
|
||||
"Map type class java.util.HashMap is unstable under iteration. Suggested fix: use java.util.LinkedHashMap instead.")
|
||||
"Map type class java.util.HashMap is unstable under iteration. Suggested fix: use java.util.LinkedHashMap instead.")
|
||||
}
|
||||
|
||||
@CordaSerializable
|
||||
|
@ -40,7 +40,6 @@ class PrivateKeySerializationTest(private val privateKey: PrivateKey, private va
|
||||
fun `failed with wrong UseCase`() {
|
||||
assertThatThrownBy { privateKey.serialize(context = SerializationDefaults.P2P_CONTEXT) }
|
||||
.isInstanceOf(IllegalStateException::class.java)
|
||||
.hasMessageContaining("UseCase '${P2P}' is not within")
|
||||
|
||||
.hasMessageContaining("UseCase '$P2P' is not within")
|
||||
}
|
||||
}
|
@ -397,6 +397,7 @@ class EnumEvolvabilityTests {
|
||||
val f = sf.javaClass.getDeclaredField("transformsCache")
|
||||
f.isAccessible = true
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val transformsCache = f.get(sf) as ConcurrentHashMap<String, EnumMap<TransformTypes, MutableList<Transform>>>
|
||||
|
||||
assertEquals(0, transformsCache.size)
|
||||
|
@ -15,7 +15,7 @@ class ErrorMessagesTests {
|
||||
val VERBOSE get() = false
|
||||
}
|
||||
|
||||
private fun errMsg(property:String, testname: String) =
|
||||
private fun errMsg(property: String, testname: String) =
|
||||
"Property '$property' or its getter is non public, this renders class 'class $testname\$C' unserializable -> class $testname\$C"
|
||||
|
||||
// Java allows this to be set at the class level yet Kotlin doesn't for some reason
|
||||
|
@ -7,7 +7,7 @@ import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.TestSerializationOutput
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.serializeAndReturnSchema
|
||||
|
||||
class FingerPrinterTesting : FingerPrinter {
|
||||
class FingerPrinterTesting : FingerPrinter {
|
||||
private var index = 0
|
||||
private val cache = mutableMapOf<Type, String>()
|
||||
|
||||
@ -29,18 +29,19 @@ class FingerPrinterTestingTests {
|
||||
companion object {
|
||||
const val VERBOSE = true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testingTest() {
|
||||
val fpt = FingerPrinterTesting()
|
||||
assertEquals ("0", fpt.fingerprint(Integer::class.java))
|
||||
assertEquals ("1", fpt.fingerprint(String::class.java))
|
||||
assertEquals ("0", fpt.fingerprint(Integer::class.java))
|
||||
assertEquals ("1", fpt.fingerprint(String::class.java))
|
||||
assertEquals("0", fpt.fingerprint(Integer::class.java))
|
||||
assertEquals("1", fpt.fingerprint(String::class.java))
|
||||
assertEquals("0", fpt.fingerprint(Integer::class.java))
|
||||
assertEquals("1", fpt.fingerprint(String::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun worksAsReplacement() {
|
||||
data class C (val a: Int, val b: Long)
|
||||
data class C(val a: Int, val b: Long)
|
||||
|
||||
val factory = SerializerFactory(
|
||||
AllWhitelist,
|
||||
@ -50,8 +51,7 @@ class FingerPrinterTestingTests {
|
||||
|
||||
val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L))
|
||||
|
||||
assertEquals (1, blob.schema.types.size)
|
||||
assertEquals ("<descriptor name=\"net.corda:0\"/>", blob.schema.types[0].descriptor.toString())
|
||||
assertEquals(1, blob.schema.types.size)
|
||||
assertEquals("<descriptor name=\"net.corda:0\"/>", blob.schema.types[0].descriptor.toString())
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@ class OverridePKSerializerTest {
|
||||
|
||||
override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput,
|
||||
context: SerializationContext
|
||||
) : PublicKey {
|
||||
): PublicKey {
|
||||
throw SerializerTestException("Custom read call")
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,10 @@ import org.junit.Test
|
||||
class RoundTripTests {
|
||||
@Test
|
||||
fun mutableBecomesImmutable() {
|
||||
data class C(val l : MutableList<String>)
|
||||
data class C(val l: MutableList<String>)
|
||||
|
||||
val factory = testDefaultFactoryNoEvolution()
|
||||
val bytes = SerializationOutput(factory).serialize(C(mutableListOf ("a", "b", "c")))
|
||||
val bytes = SerializationOutput(factory).serialize(C(mutableListOf("a", "b", "c")))
|
||||
val newC = DeserializationInput(factory).deserialize(bytes)
|
||||
|
||||
Assertions.assertThatThrownBy {
|
||||
@ -23,15 +24,16 @@ class RoundTripTests {
|
||||
@Test
|
||||
fun mutableStillMutable() {
|
||||
class C {
|
||||
val l : MutableList<String>
|
||||
val l: MutableList<String>
|
||||
|
||||
@Suppress("Unused")
|
||||
constructor (l : MutableList<String>) {
|
||||
constructor (l: MutableList<String>) {
|
||||
this.l = l.toMutableList()
|
||||
}
|
||||
}
|
||||
|
||||
val factory = testDefaultFactoryNoEvolution()
|
||||
val bytes = SerializationOutput(factory).serialize(C(mutableListOf ("a", "b", "c")))
|
||||
val bytes = SerializationOutput(factory).serialize(C(mutableListOf("a", "b", "c")))
|
||||
val newC = DeserializationInput(factory).deserialize(bytes)
|
||||
|
||||
newC.l.add("d")
|
||||
@ -39,14 +41,14 @@ class RoundTripTests {
|
||||
|
||||
@Test
|
||||
fun mutableStillMutable2() {
|
||||
data class C (val l : MutableList<String>){
|
||||
data class C(val l: MutableList<String>) {
|
||||
@ConstructorForDeserialization
|
||||
@Suppress("Unused")
|
||||
constructor (l : Collection<String>) : this (l.toMutableList())
|
||||
constructor (l: Collection<String>) : this(l.toMutableList())
|
||||
}
|
||||
|
||||
val factory = testDefaultFactoryNoEvolution()
|
||||
val bytes = SerializationOutput(factory).serialize(C(mutableListOf ("a", "b", "c")))
|
||||
val bytes = SerializationOutput(factory).serialize(C(mutableListOf("a", "b", "c")))
|
||||
val newC = DeserializationInput(factory).deserialize(bytes)
|
||||
|
||||
newC.l.add("d")
|
||||
@ -54,10 +56,11 @@ class RoundTripTests {
|
||||
|
||||
@Test
|
||||
fun mutableBecomesImmutable4() {
|
||||
data class C(val l : List<String>)
|
||||
data class C(val l: List<String>)
|
||||
|
||||
val factory = testDefaultFactoryNoEvolution()
|
||||
val bytes = SerializationOutput(factory).serialize(C(listOf ("a", "b", "c")))
|
||||
val bytes = SerializationOutput(factory).serialize(C(listOf("a", "b", "c")))
|
||||
val newC = DeserializationInput(factory).deserialize(bytes)
|
||||
val newC2 = newC.copy (l = (newC.l + "d"))
|
||||
val newC2 = newC.copy(l = (newC.l + "d"))
|
||||
}
|
||||
}
|
@ -7,7 +7,13 @@ import com.nhaarman.mockito_kotlin.whenever
|
||||
import net.corda.client.rpc.RPCException
|
||||
import net.corda.core.CordaException
|
||||
import net.corda.core.CordaRuntimeException
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.ContractAttachment
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.PrivacySalt
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionState
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.secureRandomBytes
|
||||
@ -16,25 +22,47 @@ import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.AbstractAttachment
|
||||
import net.corda.core.internal.x500Name
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.serialization.ConstructorForDeserialization
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.EncodingWhitelist
|
||||
import net.corda.core.serialization.MissingAttachmentsException
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.SerializationFactory
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.nodeapi.internal.DEV_INTERMEDIATE_CA
|
||||
import net.corda.nodeapi.internal.crypto.ContentSignerBuilder
|
||||
import net.corda.nodeapi.internal.serialization.*
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.CordaSerializationEncoding
|
||||
import net.corda.nodeapi.internal.serialization.EmptyWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.GeneratedAttachment
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.isPrimitive
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.*
|
||||
import net.corda.nodeapi.internal.serialization.carpenter.ClassCarpenterImpl
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.deserialize
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.serialize
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.testDefaultFactory
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.testDefaultFactoryNoEvolution
|
||||
import net.corda.nodeapi.internal.serialization.amqp.testutils.testSerializationContext
|
||||
import net.corda.nodeapi.internal.serialization.encodingNotPermittedFormat
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.core.BOB_NAME
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import net.corda.testing.core.TestIdentity
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
import org.apache.activemq.artemis.api.core.SimpleString
|
||||
import org.apache.qpid.proton.amqp.*
|
||||
import org.apache.qpid.proton.amqp.Decimal128
|
||||
import org.apache.qpid.proton.amqp.Decimal32
|
||||
import org.apache.qpid.proton.amqp.Decimal64
|
||||
import org.apache.qpid.proton.amqp.Symbol
|
||||
import org.apache.qpid.proton.amqp.UnsignedByte
|
||||
import org.apache.qpid.proton.amqp.UnsignedInteger
|
||||
import org.apache.qpid.proton.amqp.UnsignedLong
|
||||
import org.apache.qpid.proton.amqp.UnsignedShort
|
||||
import org.apache.qpid.proton.codec.DecoderImpl
|
||||
import org.apache.qpid.proton.codec.EncoderImpl
|
||||
import org.assertj.core.api.Assertions.*
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.assertj.core.api.Assertions.catchThrowable
|
||||
import org.bouncycastle.cert.X509v2CRLBuilder
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
@ -50,7 +78,20 @@ import java.io.NotSerializableException
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import java.security.cert.X509CRL
|
||||
import java.time.*
|
||||
import java.time.DayOfWeek
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalTime
|
||||
import java.time.Month
|
||||
import java.time.MonthDay
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.OffsetTime
|
||||
import java.time.Period
|
||||
import java.time.Year
|
||||
import java.time.YearMonth
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.*
|
||||
import kotlin.reflect.full.superclasses
|
||||
@ -233,7 +274,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
||||
}
|
||||
EncoderImpl(decoder)
|
||||
DeserializationInput.withDataBytes(bytes, encodingWhitelist) {
|
||||
decoder.setByteBuffer(it)
|
||||
decoder.byteBuffer = it
|
||||
// Check that a vanilla AMQP decoder can deserialize without schema.
|
||||
val result = decoder.readObject() as Envelope
|
||||
assertNotNull(result)
|
||||
@ -889,7 +930,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
||||
|
||||
@Test
|
||||
fun `test generic in constructor serialize`() {
|
||||
val obj = GenericSubclass(OtherGeneric<String>())
|
||||
val obj = GenericSubclass(OtherGeneric())
|
||||
serdes(obj)
|
||||
}
|
||||
|
||||
@ -1186,7 +1227,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.BigDecimalSerializer)
|
||||
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.CurrencySerializer)
|
||||
|
||||
val c = C(Amount<Currency>(100, BigDecimal("1.5"), Currency.getInstance("USD")))
|
||||
val c = C(Amount(100, BigDecimal("1.5"), Currency.getInstance("USD")))
|
||||
|
||||
// were the issue not fixed we'd blow up here
|
||||
SerializationOutput(factory, compression).serialize(c)
|
||||
|
@ -17,8 +17,8 @@ val TESTING_CONTEXT = SerializationContextImpl(amqpMagic,
|
||||
|
||||
// Test factory that lets us count the number of serializer registration attempts
|
||||
class TestSerializerFactory(
|
||||
wl : ClassWhitelist,
|
||||
cl : ClassLoader
|
||||
wl: ClassWhitelist,
|
||||
cl: ClassLoader
|
||||
) : SerializerFactory(wl, cl) {
|
||||
var registerCount = 0
|
||||
|
||||
@ -83,16 +83,17 @@ class TestSerializationFactory : SerializationFactory() {
|
||||
class SerializationSchemaTests {
|
||||
@Test
|
||||
fun onlyRegisterCustomSerializersOnce() {
|
||||
@CordaSerializable data class C(val a: Int)
|
||||
@CordaSerializable
|
||||
data class C(val a: Int)
|
||||
|
||||
val c = C(1)
|
||||
val testSerializationFactory = TestSerializationFactory()
|
||||
val expectedCustomSerializerCount = 40
|
||||
|
||||
assertEquals (0, testFactory.registerCount)
|
||||
c.serialize (testSerializationFactory, TESTING_CONTEXT)
|
||||
assertEquals (expectedCustomSerializerCount, testFactory.registerCount)
|
||||
c.serialize (testSerializationFactory, TESTING_CONTEXT)
|
||||
assertEquals (expectedCustomSerializerCount, testFactory.registerCount)
|
||||
assertEquals(0, testFactory.registerCount)
|
||||
c.serialize(testSerializationFactory, TESTING_CONTEXT)
|
||||
assertEquals(expectedCustomSerializerCount, testFactory.registerCount)
|
||||
c.serialize(testSerializationFactory, TESTING_CONTEXT)
|
||||
assertEquals(expectedCustomSerializerCount, testFactory.registerCount)
|
||||
}
|
||||
}
|
@ -68,7 +68,6 @@ class StaticInitialisationOfSerializedObjectTest {
|
||||
assertEquals(1, serialisersByType.size)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun deserializeTest() {
|
||||
data class D(val c: C2)
|
||||
@ -99,8 +98,7 @@ 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(ClassLoader.getSystemClassLoader(), wl2)) {
|
||||
}
|
||||
SerializerFactory(wl1, ClassCarpenterImpl(ClassLoader.getSystemClassLoader(), wl2))
|
||||
|
||||
// This time have the serialization factory and the carpenter use different whitelists
|
||||
@Test
|
||||
|
@ -27,7 +27,7 @@ class TestClassLoader(private var exclude: List<String>) : ClassLoader() {
|
||||
}
|
||||
|
||||
interface TestInterface {
|
||||
fun runThing() : Int
|
||||
fun runThing(): Int
|
||||
}
|
||||
|
||||
// Create a custom serialization factory where we need to be able to both specify a carpenter
|
||||
@ -63,10 +63,10 @@ class CarpenterExceptionTests {
|
||||
val a1 = CLA().loadClass(A::class.java.name)
|
||||
val a2 = CLB().loadClass(A::class.java.name)
|
||||
|
||||
assertTrue (TypeToken.of(a1).isSubtypeOf(a2))
|
||||
assertTrue (a1 is Type)
|
||||
assertTrue (a2 is Type)
|
||||
assertTrue (a3 is Type)
|
||||
assertTrue(TypeToken.of(a1).isSubtypeOf(a2))
|
||||
assertTrue(a1 is Type)
|
||||
assertTrue(a2 is Type)
|
||||
assertTrue(a3 is Type)
|
||||
assertEquals(a1, a2)
|
||||
assertEquals(a1, a3)
|
||||
assertEquals(a2, a3)
|
||||
@ -74,11 +74,11 @@ class CarpenterExceptionTests {
|
||||
|
||||
@Test
|
||||
fun carpenterExceptionRethrownAsNotSerializableException() {
|
||||
data class C2 (val i: Int) : TestInterface {
|
||||
data class C2(val i: Int) : TestInterface {
|
||||
override fun runThing() = 1
|
||||
}
|
||||
|
||||
data class C1 (val i: Int, val c: C2)
|
||||
data class C1(val i: Int, val c: C2)
|
||||
|
||||
// We need two factories to ensure when we deserialize the blob we don't just use the serializer
|
||||
// we built to serialise things
|
||||
|
@ -40,7 +40,7 @@ fun Schema.mangleNames(names: List<String>): Schema {
|
||||
* rather than have it create its own
|
||||
*/
|
||||
class SerializerFactoryExternalCarpenter(classCarpenter: ClassCarpenter)
|
||||
: SerializerFactory (classCarpenter.whitelist, classCarpenter)
|
||||
: SerializerFactory(classCarpenter.whitelist, classCarpenter)
|
||||
|
||||
open class AmqpCarpenterBase(whitelist: ClassWhitelist) {
|
||||
var cc = ClassCarpenterImpl(whitelist = whitelist)
|
||||
|
@ -53,7 +53,8 @@ class ClassCarpenterWhitelistTest {
|
||||
// it's marked as CordaSerializable
|
||||
@Test
|
||||
fun notWhitelistedButAnnotated() {
|
||||
@CordaSerializable data class A(val a: Int)
|
||||
@CordaSerializable
|
||||
data class A(val a: Int)
|
||||
|
||||
class WL : ClassWhitelist {
|
||||
override fun hasListed(type: Class<*>) = false
|
||||
|
@ -98,6 +98,5 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase(AllWhi
|
||||
assertEquals(pinochio.getMethod("getA").invoke(p), amqpObj.a)
|
||||
assertEquals(pinochio.getMethod("getB").invoke(p), amqpObj.b)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user