mirror of
https://github.com/corda/corda.git
synced 2025-03-11 06:54:04 +00:00
Enabling logging in ExceptionSerialisingRpcOpsProxy. (#3212)
This commit is contained in:
parent
fb70c4b69c
commit
072cf0fa97
@ -10,7 +10,16 @@ import net.corda.core.concurrent.CordaFuture
|
|||||||
import net.corda.core.context.InvocationContext
|
import net.corda.core.context.InvocationContext
|
||||||
import net.corda.core.crypto.newSecureRandom
|
import net.corda.core.crypto.newSecureRandom
|
||||||
import net.corda.core.crypto.sign
|
import net.corda.core.crypto.sign
|
||||||
import net.corda.core.flows.*
|
import net.corda.core.flows.ContractUpgradeFlow
|
||||||
|
import net.corda.core.flows.FinalityFlow
|
||||||
|
import net.corda.core.flows.FlowLogic
|
||||||
|
import net.corda.core.flows.FlowLogicRefFactory
|
||||||
|
import net.corda.core.flows.FlowSession
|
||||||
|
import net.corda.core.flows.InitiatedBy
|
||||||
|
import net.corda.core.flows.InitiatingFlow
|
||||||
|
import net.corda.core.flows.NotaryChangeFlow
|
||||||
|
import net.corda.core.flows.NotaryFlow
|
||||||
|
import net.corda.core.flows.StartableByService
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
@ -21,15 +30,33 @@ import net.corda.core.internal.concurrent.map
|
|||||||
import net.corda.core.internal.concurrent.openFuture
|
import net.corda.core.internal.concurrent.openFuture
|
||||||
import net.corda.core.internal.notary.NotaryService
|
import net.corda.core.internal.notary.NotaryService
|
||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
import net.corda.core.messaging.*
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.node.*
|
import net.corda.core.messaging.FlowHandle
|
||||||
import net.corda.core.node.services.*
|
import net.corda.core.messaging.FlowHandleImpl
|
||||||
|
import net.corda.core.messaging.FlowProgressHandle
|
||||||
|
import net.corda.core.messaging.FlowProgressHandleImpl
|
||||||
|
import net.corda.core.messaging.RPCOps
|
||||||
|
import net.corda.core.node.AppServiceHub
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
|
import net.corda.core.node.NodeInfo
|
||||||
|
import net.corda.core.node.ServiceHub
|
||||||
|
import net.corda.core.node.ServicesForResolution
|
||||||
|
import net.corda.core.node.StatesToRecord
|
||||||
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
|
import net.corda.core.node.services.CordaService
|
||||||
|
import net.corda.core.node.services.IdentityService
|
||||||
|
import net.corda.core.node.services.KeyManagementService
|
||||||
|
import net.corda.core.node.services.TransactionVerifierService
|
||||||
import net.corda.core.serialization.SerializationWhitelist
|
import net.corda.core.serialization.SerializationWhitelist
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.utilities.*
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
|
import net.corda.core.utilities.days
|
||||||
|
import net.corda.core.utilities.debug
|
||||||
|
import net.corda.core.utilities.getOrThrow
|
||||||
|
import net.corda.core.utilities.minutes
|
||||||
import net.corda.node.CordaClock
|
import net.corda.node.CordaClock
|
||||||
import net.corda.node.VersionInfo
|
import net.corda.node.VersionInfo
|
||||||
import net.corda.node.internal.classloading.requireAnnotation
|
import net.corda.node.internal.classloading.requireAnnotation
|
||||||
@ -43,21 +70,58 @@ import net.corda.node.internal.security.RPCSecurityManager
|
|||||||
import net.corda.node.services.ContractUpgradeHandler
|
import net.corda.node.services.ContractUpgradeHandler
|
||||||
import net.corda.node.services.FinalityHandler
|
import net.corda.node.services.FinalityHandler
|
||||||
import net.corda.node.services.NotaryChangeHandler
|
import net.corda.node.services.NotaryChangeHandler
|
||||||
import net.corda.node.services.api.*
|
import net.corda.node.services.api.CheckpointStorage
|
||||||
import net.corda.node.services.config.*
|
import net.corda.node.services.api.DummyAuditService
|
||||||
|
import net.corda.node.services.api.FlowStarter
|
||||||
|
import net.corda.node.services.api.IdentityServiceInternal
|
||||||
|
import net.corda.node.services.api.MonitoringService
|
||||||
|
import net.corda.node.services.api.NetworkMapCacheBaseInternal
|
||||||
|
import net.corda.node.services.api.NetworkMapCacheInternal
|
||||||
|
import net.corda.node.services.api.NodePropertiesStore
|
||||||
|
import net.corda.node.services.api.SchedulerService
|
||||||
|
import net.corda.node.services.api.SchemaService
|
||||||
|
import net.corda.node.services.api.ServiceHubInternal
|
||||||
|
import net.corda.node.services.api.StartedNodeServices
|
||||||
|
import net.corda.node.services.api.VaultServiceInternal
|
||||||
|
import net.corda.node.services.api.WritableTransactionStorage
|
||||||
|
import net.corda.node.services.config.BFTSMaRtConfiguration
|
||||||
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
|
import net.corda.node.services.config.NotaryConfig
|
||||||
|
import net.corda.node.services.config.configureWithDevSSLCertificate
|
||||||
import net.corda.node.services.config.shell.toShellConfig
|
import net.corda.node.services.config.shell.toShellConfig
|
||||||
|
import net.corda.node.services.config.shouldInitCrashShell
|
||||||
import net.corda.node.services.events.NodeSchedulerService
|
import net.corda.node.services.events.NodeSchedulerService
|
||||||
import net.corda.node.services.events.ScheduledActivityObserver
|
import net.corda.node.services.events.ScheduledActivityObserver
|
||||||
import net.corda.node.services.identity.PersistentIdentityService
|
import net.corda.node.services.identity.PersistentIdentityService
|
||||||
import net.corda.node.services.keys.PersistentKeyManagementService
|
import net.corda.node.services.keys.PersistentKeyManagementService
|
||||||
import net.corda.node.services.messaging.DeduplicationHandler
|
import net.corda.node.services.messaging.DeduplicationHandler
|
||||||
import net.corda.node.services.messaging.MessagingService
|
import net.corda.node.services.messaging.MessagingService
|
||||||
import net.corda.node.services.network.*
|
import net.corda.node.services.network.NetworkMapCacheImpl
|
||||||
import net.corda.node.services.persistence.*
|
import net.corda.node.services.network.NetworkMapClient
|
||||||
|
import net.corda.node.services.network.NetworkMapUpdater
|
||||||
|
import net.corda.node.services.network.NodeInfoWatcher
|
||||||
|
import net.corda.node.services.network.PersistentNetworkMapCache
|
||||||
|
import net.corda.node.services.persistence.AbstractPartyDescriptor
|
||||||
|
import net.corda.node.services.persistence.AbstractPartyToX500NameAsStringConverter
|
||||||
|
import net.corda.node.services.persistence.DBCheckpointStorage
|
||||||
|
import net.corda.node.services.persistence.DBTransactionMappingStorage
|
||||||
|
import net.corda.node.services.persistence.DBTransactionStorage
|
||||||
|
import net.corda.node.services.persistence.NodeAttachmentService
|
||||||
|
import net.corda.node.services.persistence.NodePropertiesPersistentStore
|
||||||
import net.corda.node.services.schema.HibernateObserver
|
import net.corda.node.services.schema.HibernateObserver
|
||||||
import net.corda.node.services.schema.NodeSchemaService
|
import net.corda.node.services.schema.NodeSchemaService
|
||||||
import net.corda.node.services.statemachine.*
|
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
|
||||||
import net.corda.node.services.transactions.*
|
import net.corda.node.services.statemachine.SingleThreadedStateMachineManager
|
||||||
|
import net.corda.node.services.statemachine.StateMachineManager
|
||||||
|
import net.corda.node.services.statemachine.appName
|
||||||
|
import net.corda.node.services.statemachine.flowVersionAndInitiatingClass
|
||||||
|
import net.corda.node.services.transactions.BFTNonValidatingNotaryService
|
||||||
|
import net.corda.node.services.transactions.BFTSMaRt
|
||||||
|
import net.corda.node.services.transactions.RaftNonValidatingNotaryService
|
||||||
|
import net.corda.node.services.transactions.RaftUniquenessProvider
|
||||||
|
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||||
|
import net.corda.node.services.transactions.SimpleNotaryService
|
||||||
|
import net.corda.node.services.transactions.ValidatingNotaryService
|
||||||
import net.corda.node.services.upgrade.ContractUpgradeServiceImpl
|
import net.corda.node.services.upgrade.ContractUpgradeServiceImpl
|
||||||
import net.corda.node.services.vault.NodeVaultService
|
import net.corda.node.services.vault.NodeVaultService
|
||||||
import net.corda.node.utilities.AffinityExecutor
|
import net.corda.node.utilities.AffinityExecutor
|
||||||
@ -172,7 +236,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
|
|||||||
|
|
||||||
val ops: CordaRPCOps = CordaRPCOpsImpl(services, smm, database, flowStarter, { shutdownExecutor.submit { stop() } })
|
val ops: CordaRPCOps = CordaRPCOpsImpl(services, smm, database, flowStarter, { shutdownExecutor.submit { stop() } })
|
||||||
// Mind that order is relevant here.
|
// Mind that order is relevant here.
|
||||||
val proxies = listOf(::AuthenticatedRpcOpsProxy, ::ExceptionSerialisingRpcOpsProxy)
|
val proxies = listOf<(CordaRPCOps) -> CordaRPCOps>(::AuthenticatedRpcOpsProxy, { it -> ExceptionSerialisingRpcOpsProxy(it, true) })
|
||||||
return proxies.fold(ops) { delegate, decorate -> decorate(delegate) }
|
return proxies.fold(ops) { delegate, decorate -> decorate(delegate) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package net.corda.node.internal.rpc.proxies
|
|||||||
import net.corda.core.CordaRuntimeException
|
import net.corda.core.CordaRuntimeException
|
||||||
import net.corda.core.CordaThrowable
|
import net.corda.core.CordaThrowable
|
||||||
import net.corda.core.concurrent.CordaFuture
|
import net.corda.core.concurrent.CordaFuture
|
||||||
|
import net.corda.core.doOnError
|
||||||
|
import net.corda.core.internal.concurrent.doOnError
|
||||||
import net.corda.core.internal.concurrent.mapError
|
import net.corda.core.internal.concurrent.mapError
|
||||||
import net.corda.core.mapErrors
|
import net.corda.core.mapErrors
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
@ -12,25 +14,30 @@ import net.corda.core.messaging.FlowHandleImpl
|
|||||||
import net.corda.core.messaging.FlowProgressHandle
|
import net.corda.core.messaging.FlowProgressHandle
|
||||||
import net.corda.core.messaging.FlowProgressHandleImpl
|
import net.corda.core.messaging.FlowProgressHandleImpl
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.internal.InvocationHandlerTemplate
|
import net.corda.node.internal.InvocationHandlerTemplate
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.lang.reflect.Proxy.newProxyInstance
|
import java.lang.reflect.Proxy.newProxyInstance
|
||||||
|
|
||||||
internal class ExceptionSerialisingRpcOpsProxy(private val delegate: CordaRPCOps) : CordaRPCOps by proxy(delegate) {
|
internal class ExceptionSerialisingRpcOpsProxy(private val delegate: CordaRPCOps, doLog: Boolean) : CordaRPCOps by proxy(delegate, doLog) {
|
||||||
private companion object {
|
private companion object {
|
||||||
private fun proxy(delegate: CordaRPCOps): CordaRPCOps {
|
private val logger = loggerFor<ExceptionSerialisingRpcOpsProxy>()
|
||||||
val handler = ErrorSerialisingInvocationHandler(delegate)
|
|
||||||
|
private fun proxy(delegate: CordaRPCOps, doLog: Boolean): CordaRPCOps {
|
||||||
|
val handler = ErrorSerialisingInvocationHandler(delegate, doLog)
|
||||||
return newProxyInstance(delegate::class.java.classLoader, arrayOf(CordaRPCOps::class.java), handler) as CordaRPCOps
|
return newProxyInstance(delegate::class.java.classLoader, arrayOf(CordaRPCOps::class.java), handler) as CordaRPCOps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ErrorSerialisingInvocationHandler(override val delegate: CordaRPCOps) : InvocationHandlerTemplate {
|
private class ErrorSerialisingInvocationHandler(override val delegate: CordaRPCOps, private val doLog: Boolean) : InvocationHandlerTemplate {
|
||||||
override fun invoke(proxy: Any, method: Method, arguments: Array<out Any?>?): Any? {
|
override fun invoke(proxy: Any, method: Method, arguments: Array<out Any?>?): Any? {
|
||||||
try {
|
try {
|
||||||
val result = super.invoke(proxy, method, arguments)
|
val result = super.invoke(proxy, method, arguments)
|
||||||
return result?.let { ensureSerialisable(it) }
|
return result?.let { ensureSerialisable(it) }
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
|
// In this special case logging and re-throwing is the right approach.
|
||||||
|
log(exception)
|
||||||
throw ensureSerialisable(exception)
|
throw ensureSerialisable(exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,15 +67,15 @@ internal class ExceptionSerialisingRpcOpsProxy(private val delegate: CordaRPCOps
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun <ELEMENT> wrapObservable(observable: Observable<ELEMENT>): Observable<ELEMENT> {
|
private fun <ELEMENT> wrapObservable(observable: Observable<ELEMENT>): Observable<ELEMENT> {
|
||||||
return observable.mapErrors(::ensureSerialisable)
|
return observable.doOnError(::log).mapErrors(::ensureSerialisable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <SNAPSHOT, ELEMENT> wrapFeed(feed: DataFeed<SNAPSHOT, ELEMENT>): DataFeed<SNAPSHOT, ELEMENT> {
|
private fun <SNAPSHOT, ELEMENT> wrapFeed(feed: DataFeed<SNAPSHOT, ELEMENT>): DataFeed<SNAPSHOT, ELEMENT> {
|
||||||
return feed.mapErrors(::ensureSerialisable)
|
return feed.doOnError(::log).mapErrors(::ensureSerialisable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <RESULT> wrapFuture(future: CordaFuture<RESULT>): CordaFuture<RESULT> {
|
private fun <RESULT> wrapFuture(future: CordaFuture<RESULT>): CordaFuture<RESULT> {
|
||||||
return future.mapError(::ensureSerialisable)
|
return future.doOnError(::log).mapError(::ensureSerialisable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ensureSerialisable(error: Throwable): Throwable {
|
private fun ensureSerialisable(error: Throwable): Throwable {
|
||||||
@ -81,6 +88,12 @@ internal class ExceptionSerialisingRpcOpsProxy(private val delegate: CordaRPCOps
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun log(error: Throwable) {
|
||||||
|
if (doLog) {
|
||||||
|
logger.error("Error during RPC invocation", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun superclasses(clazz: Class<*>): List<Class<*>> {
|
private fun superclasses(clazz: Class<*>): List<Class<*>> {
|
||||||
val superclasses = mutableListOf<Class<*>>()
|
val superclasses = mutableListOf<Class<*>>()
|
||||||
var current: Class<*>?
|
var current: Class<*>?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user