Flow stack snapshot feature (#1094)

* flows: Add StackDump, debugStackDump, test (doesnt work)

* Polishing Quasar dump feature, extending it with persisting to a file, adding integration tests

* Addressing review comments

* Addressing 2nd round of review comments

* Refactoring implementation according to Shams suggestion

* Reverting changes and restoring the feature to be the part of the core API

* Switching to ServiceLoader
This commit is contained in:
mkit
2017-08-15 08:22:37 +01:00
committed by GitHub
parent 8f8a5ff774
commit 3ba42b4ccd
9 changed files with 646 additions and 21 deletions

View File

@ -227,14 +227,14 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
override fun checkFlowPermission(permissionName: String, extraAuditData: Map<String, String>) {
val permissionGranted = true // TODO define permission control service on ServiceHubInternal and actually check authorization.
val checkPermissionEvent = FlowPermissionAuditEvent(
serviceHub.clock.instant(),
flowInitiator,
"Flow Permission Required: $permissionName",
extraAuditData,
logic.javaClass,
id,
permissionName,
permissionGranted)
serviceHub.clock.instant(),
flowInitiator,
"Flow Permission Required: $permissionName",
extraAuditData,
logic.javaClass,
id,
permissionName,
permissionGranted)
serviceHub.auditService.recordAuditEvent(checkPermissionEvent)
if (!permissionGranted) {
throw FlowPermissionException("User $flowInitiator not permissioned for $permissionName on flow $id")
@ -242,18 +242,29 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
}
// TODO Dummy implementation of access to application specific audit logging
override fun recordAuditEvent(eventType: String, comment: String, extraAuditData: Map<String,String>) {
override fun recordAuditEvent(eventType: String, comment: String, extraAuditData: Map<String, String>): Unit {
val flowAuditEvent = FlowAppAuditEvent(
serviceHub.clock.instant(),
flowInitiator,
comment,
extraAuditData,
logic.javaClass,
serviceHub.clock.instant(),
flowInitiator,
comment,
extraAuditData,
logic.javaClass,
id,
eventType)
serviceHub.auditService.recordAuditEvent(flowAuditEvent)
}
@Suspendable
override fun flowStackSnapshot(flowClass: Class<*>): FlowStackSnapshot? {
val factory = FlowStackSnapshotFactory.instance
return factory.getFlowStackSnapshot(flowClass)
}
override fun persistFlowStackSnapshot(flowClass: Class<*>): Unit {
val factory = FlowStackSnapshotFactory.instance
factory.persistAsJsonFile(flowClass, serviceHub.configuration.baseDirectory, id.toString())
}
/**
* This method will suspend the state machine and wait for incoming session init response from other party.
*/

View File

@ -7,6 +7,7 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowContext
import net.corda.core.flows.FlowInitiator
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowStackSnapshot
import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.Party
import net.corda.core.internal.FlowStateMachine
@ -32,6 +33,7 @@ class InteractiveShellTest {
constructor(amount: Amount<Currency>) : this(amount.toString())
constructor(pair: Pair<Amount<Currency>, SecureHash.SHA256>) : this(pair.toString())
constructor(party: Party) : this(party.name.toString())
override fun call() = a
}
@ -99,5 +101,13 @@ class InteractiveShellTest {
override fun recordAuditEvent(eventType: String, comment: String, extraAuditData: Map<String, String>) {
// Do nothing
}
override fun flowStackSnapshot(flowClass: Class<*>): FlowStackSnapshot? {
return null
}
override fun persistFlowStackSnapshot(flowClass: Class<*>) {
// Do nothing
}
}
}