mirror of
https://github.com/corda/corda.git
synced 2025-02-21 01:42:24 +00:00
CORDA-540: Add a property to make sending stacktraces optional in AMQP mode (#1458)
This commit is contained in:
parent
628d94c070
commit
0edaea81d2
@ -60,7 +60,7 @@ abstract class SerializationFactory {
|
||||
* Allow subclasses to temporarily mark themselves as the current factory for the current thread during serialization/deserialization.
|
||||
* Will restore the prior context on exiting the block.
|
||||
*/
|
||||
protected fun <T> asCurrent(block: SerializationFactory.() -> T): T {
|
||||
fun <T> asCurrent(block: SerializationFactory.() -> T): T {
|
||||
val priorContext = _currentFactory.get()
|
||||
_currentFactory.set(this)
|
||||
try {
|
||||
|
@ -2,6 +2,7 @@ package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import com.google.common.primitives.Primitives
|
||||
import com.google.common.reflect.TypeToken
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import org.apache.qpid.proton.codec.Data
|
||||
import java.beans.IndexedPropertyDescriptor
|
||||
import java.beans.Introspector
|
||||
@ -229,4 +230,11 @@ internal fun Type.isSubClassOf(type: Type): Boolean {
|
||||
internal fun suitableForObjectReference(type: Type): Boolean {
|
||||
val clazz = type.asClass()
|
||||
return type != ByteArray::class.java && (clazz != null && !clazz.isPrimitive && !Primitives.unwrap(clazz).isPrimitive)
|
||||
}
|
||||
|
||||
/**
|
||||
* Common properties that are to be used in the [SerializationContext.properties] to alter serialization behavior/content
|
||||
*/
|
||||
internal enum class CommonPropertyNames {
|
||||
IncludeInternalInfo,
|
||||
}
|
@ -2,11 +2,9 @@ package net.corda.nodeapi.internal.serialization.amqp.custom
|
||||
|
||||
import net.corda.core.CordaRuntimeException
|
||||
import net.corda.core.CordaThrowable
|
||||
import net.corda.core.serialization.SerializationFactory
|
||||
import net.corda.core.utilities.loggerFor
|
||||
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 net.corda.nodeapi.internal.serialization.amqp.*
|
||||
import java.io.NotSerializableException
|
||||
|
||||
class ThrowableSerializer(factory: SerializerFactory) : CustomSerializer.Proxy<Throwable, ThrowableSerializer.ThrowableProxy>(Throwable::class.java, ThrowableProxy::class.java, factory) {
|
||||
@ -33,7 +31,14 @@ class ThrowableSerializer(factory: SerializerFactory) : CustomSerializer.Proxy<T
|
||||
} else {
|
||||
obj.message
|
||||
}
|
||||
return ThrowableProxy(obj.javaClass.name, message, obj.stackTrace, obj.cause, obj.suppressed, extraProperties)
|
||||
val stackTraceToInclude = if (shouldIncludeInternalInfo()) obj.stackTrace else emptyArray()
|
||||
return ThrowableProxy(obj.javaClass.name, message, stackTraceToInclude, obj.cause, obj.suppressed, extraProperties)
|
||||
}
|
||||
|
||||
private fun shouldIncludeInternalInfo(): Boolean {
|
||||
val currentContext = SerializationFactory.currentFactory?.currentContext
|
||||
val includeInternalInfo = currentContext?.properties?.get(CommonPropertyNames.IncludeInternalInfo)
|
||||
return true == includeInternalInfo
|
||||
}
|
||||
|
||||
override fun fromProxy(proxy: ThrowableProxy): Throwable {
|
||||
|
@ -9,6 +9,7 @@ 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.SerializationFactory
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.nodeapi.RPCException
|
||||
import net.corda.nodeapi.internal.serialization.AbstractAMQPSerializationScheme
|
||||
@ -18,6 +19,7 @@ import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion
|
||||
import net.corda.testing.BOB_IDENTITY
|
||||
import net.corda.testing.MEGA_CORP
|
||||
import net.corda.testing.MEGA_CORP_PUBKEY
|
||||
import net.corda.testing.withTestSerialization
|
||||
import org.apache.qpid.proton.amqp.*
|
||||
import org.apache.qpid.proton.codec.DecoderImpl
|
||||
import org.apache.qpid.proton.codec.EncoderImpl
|
||||
@ -418,10 +420,18 @@ class SerializationOutputTests {
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
val t = IllegalAccessException("message").fillInStackTrace()
|
||||
val desThrowable = serdes(t, factory, factory2, false) as Throwable
|
||||
|
||||
val desThrowable = serdesThrowableWithInternalInfo(t, factory, factory2, false)
|
||||
assertSerializedThrowableEquivalent(t, desThrowable)
|
||||
}
|
||||
|
||||
private fun serdesThrowableWithInternalInfo(t: Throwable, factory: SerializerFactory, factory2: SerializerFactory, expectedEqual: Boolean = true): Throwable = withTestSerialization {
|
||||
val newContext = SerializationFactory.defaultFactory.defaultContext.withProperty(CommonPropertyNames.IncludeInternalInfo, true)
|
||||
|
||||
val deserializedObj = SerializationFactory.defaultFactory.asCurrent { withCurrentContext(newContext) { serdes(t, factory, factory2, expectedEqual) } }
|
||||
return deserializedObj
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test complex throwables serialize`() {
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
@ -437,7 +447,7 @@ class SerializationOutputTests {
|
||||
throw IllegalStateException("Layer 2", t)
|
||||
}
|
||||
} catch(t: Throwable) {
|
||||
val desThrowable = serdes(t, factory, factory2, false)
|
||||
val desThrowable = serdesThrowableWithInternalInfo(t, factory, factory2, false)
|
||||
assertSerializedThrowableEquivalent(t, desThrowable)
|
||||
}
|
||||
}
|
||||
@ -469,7 +479,7 @@ class SerializationOutputTests {
|
||||
throw e
|
||||
}
|
||||
} catch(t: Throwable) {
|
||||
val desThrowable = serdes(t, factory, factory2, false)
|
||||
val desThrowable = serdesThrowableWithInternalInfo(t, factory, factory2, false)
|
||||
assertSerializedThrowableEquivalent(t, desThrowable)
|
||||
}
|
||||
}
|
||||
@ -483,7 +493,7 @@ class SerializationOutputTests {
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
val obj = FlowException("message").fillInStackTrace()
|
||||
serdes(obj, factory, factory2)
|
||||
serdesThrowableWithInternalInfo(obj, factory, factory2)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -495,7 +505,7 @@ class SerializationOutputTests {
|
||||
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(factory2))
|
||||
|
||||
val obj = RPCException("message").fillInStackTrace()
|
||||
serdes(obj, factory, factory2)
|
||||
serdesThrowableWithInternalInfo(obj, factory, factory2)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user