explorer: Map transactions by tx id as well

This commit is contained in:
Andras Slemmer 2016-09-12 14:17:50 +01:00
parent 50ceb9d155
commit 21a7707825
3 changed files with 60 additions and 20 deletions

View File

@ -1,6 +1,7 @@
package com.r3corda.client.model
import com.r3corda.client.fxutils.foldToObservableList
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.transactions.LedgerTransaction
import com.r3corda.node.services.monitor.ServiceToClientEvent
import com.r3corda.node.services.monitor.TransactionBuildResult
@ -9,6 +10,7 @@ import javafx.beans.property.SimpleObjectProperty
import javafx.beans.value.ObservableValue
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import org.jetbrains.exposed.sql.transactions.transaction
import rx.Observable
import java.time.Instant
import java.util.UUID
@ -59,7 +61,7 @@ class GatheredTransactionDataModel {
/**
* Aggregation of updates to transactions. We use the observable list as the only container and do linear search for
* matching transactions because we have two keys(fiber ID and UUID) and this way it's easier to avoid syncing issues.
* matching transactions because we have three keys(fiber ID, UUID, tx id) and this way it's easier to avoid syncing issues.
*
* The Fiber ID is used to identify events that relate to the same transaction server-side, whereas the UUID is
* generated on the UI and is used to identify events with the UI action that triggered them. Currently a UUID is
@ -75,13 +77,15 @@ class GatheredTransactionDataModel {
folderFun = { serviceToClientEvent, _unit, transactionStates ->
return@foldToObservableList when (serviceToClientEvent) {
is ServiceToClientEvent.Transaction -> {
// TODO handle this once we have some id to associate the tx with
newTransactionIdTransactionStateOrModify(transactionStates, serviceToClientEvent,
transaction = serviceToClientEvent.transaction,
tweak = {}
)
}
is ServiceToClientEvent.OutputState -> {}
is ServiceToClientEvent.StateMachine -> {
newFiberIdTransactionStateOrModify(transactionStates, serviceToClientEvent,
fiberId = serviceToClientEvent.fiberId,
lastUpdate = serviceToClientEvent.time,
tweak = {
stateMachineStatus.set(when (serviceToClientEvent.addOrRemove) {
AddOrRemove.ADD -> StateMachineStatus.Added(serviceToClientEvent.label)
@ -93,7 +97,6 @@ class GatheredTransactionDataModel {
is ServiceToClientEvent.Progress -> {
newFiberIdTransactionStateOrModify(transactionStates, serviceToClientEvent,
fiberId = serviceToClientEvent.fiberId,
lastUpdate = serviceToClientEvent.time,
tweak = {
protocolStatus.set(ProtocolStatus(serviceToClientEvent.message))
}
@ -107,7 +110,10 @@ class GatheredTransactionDataModel {
is TransactionBuildResult.ProtocolStarted -> state.fiberId
is TransactionBuildResult.Failed -> null
},
lastUpdate = serviceToClientEvent.time,
transactionId = when (state) {
is TransactionBuildResult.ProtocolStarted -> state.transaction?.id
is TransactionBuildResult.Failed -> null
},
tweak = {
return@newUuidTransactionStateOrModify when (state) {
is TransactionBuildResult.ProtocolStarted -> {
@ -126,25 +132,49 @@ class GatheredTransactionDataModel {
)
companion object {
private fun newFiberIdTransactionStateOrModify(
private fun newTransactionIdTransactionStateOrModify(
transactionStates: ObservableList<GatheredTransactionDataWritable>,
event: ServiceToClientEvent,
fiberId: Long,
lastUpdate: Instant,
transaction: LedgerTransaction,
tweak: GatheredTransactionDataWritable.() -> Unit
) {
val index = transactionStates.indexOfFirst { it.fiberId.value == fiberId }
val index = transactionStates.indexOfFirst { transaction.id == it.transaction.value?.id }
val state = if (index < 0) {
val newState = GatheredTransactionDataWritable(
fiberId = SimpleObjectProperty(fiberId),
lastUpdate = SimpleObjectProperty(lastUpdate)
transaction = SimpleObjectProperty(transaction),
lastUpdate = SimpleObjectProperty(event.time)
)
tweak(newState)
transactionStates.add(newState)
newState
} else {
val existingState = transactionStates[index]
existingState.lastUpdate.set(lastUpdate)
existingState.lastUpdate.set(event.time)
tweak(existingState)
existingState
}
state.allEvents.add(event)
}
private fun newFiberIdTransactionStateOrModify(
transactionStates: ObservableList<GatheredTransactionDataWritable>,
event: ServiceToClientEvent,
fiberId: Long,
tweak: GatheredTransactionDataWritable.() -> Unit
) {
val index = transactionStates.indexOfFirst { it.fiberId.value == fiberId }
val state = if (index < 0) {
val newState = GatheredTransactionDataWritable(
fiberId = SimpleObjectProperty(fiberId),
lastUpdate = SimpleObjectProperty(event.time)
)
tweak(newState)
transactionStates.add(newState)
newState
} else {
val existingState = transactionStates[index]
existingState.lastUpdate.set(event.time)
tweak(existingState)
existingState
}
@ -156,24 +186,26 @@ class GatheredTransactionDataModel {
event: ServiceToClientEvent,
uuid: UUID,
fiberId: Long?,
lastUpdate: Instant,
transactionId: SecureHash?,
tweak: GatheredTransactionDataWritable.() -> Unit
) {
val index = transactionStates.indexOfFirst {
it.uuid.value == uuid || (fiberId != null && it.fiberId.value == fiberId)
it.uuid.value == uuid ||
(fiberId != null && it.fiberId.value == fiberId) ||
(transactionId != null && it.transaction.value?.id == transactionId)
}
val state = if (index < 0) {
val newState = GatheredTransactionDataWritable(
uuid = SimpleObjectProperty(uuid),
fiberId = SimpleObjectProperty(fiberId),
lastUpdate = SimpleObjectProperty(lastUpdate)
lastUpdate = SimpleObjectProperty(event.time)
)
tweak(newState)
transactionStates.add(newState)
newState
} else {
val existingState = transactionStates[index]
existingState.lastUpdate.set(lastUpdate)
existingState.lastUpdate.set(event.time)
tweak(existingState)
existingState
}

View File

@ -8,6 +8,7 @@ import com.r3corda.core.contracts.CommandData
import com.r3corda.core.contracts.withoutIssuer
import com.r3corda.core.contracts.*
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.crypto.toStringShort
import com.r3corda.core.transactions.LedgerTransaction
import com.r3corda.explorer.AmountDiff
@ -45,6 +46,7 @@ class TransactionViewer: View() {
// Top half (transactions table)
private val transactionViewTable: TableView<ViewerNode> by fxid()
private val transactionViewTransactionId: TableColumn<ViewerNode, String> by fxid()
private val transactionViewFiberId: TableColumn<ViewerNode, String> by fxid()
private val transactionViewClientUuid: TableColumn<ViewerNode, String> by fxid()
private val transactionViewTransactionStatus: TableColumn<ViewerNode, TransactionCreateStatus?> by fxid()
@ -92,7 +94,9 @@ class TransactionViewer: View() {
private val myIdentity: ObservableValue<Party> by observableValue(IdentityModel::myIdentity)
data class ViewerNode(
val transactionId: ObservableValue<Pair<Long?, UUID?>>,
val transactionId: ObservableValue<SecureHash?>,
val fiberId: ObservableValue<Long?>,
val clientUuid: ObservableValue<UUID?>,
val originator: ObservableValue<String>,
val transactionStatus: ObservableValue<TransactionCreateStatus?>,
val stateMachineStatus: ObservableValue<StateMachineStatus?>,
@ -111,7 +115,9 @@ class TransactionViewer: View() {
private val viewerNodes = EasyBind.map(gatheredTransactionDataList) {
ViewerNode(
transactionId = EasyBind.combine(it.fiberId, it.uuid) { fiberId, uuid -> Pair(fiberId, uuid) },
transactionId = EasyBind.map(it.transaction) { it?.id },
fiberId = it.fiberId,
clientUuid = it.uuid,
originator = EasyBind.map(it.uuid) { uuid ->
if (uuid == null) {
"Someone"
@ -284,8 +290,9 @@ class TransactionViewer: View() {
Math.floor(tableWidthWithoutPaddingAndBorder.toDouble() / transactionViewTable.columns.size).toInt()
}
transactionViewFiberId.setCellValueFactory { EasyBind.map (it.value.transactionId) { "${it.first ?: ""}" } }
transactionViewClientUuid.setCellValueFactory { EasyBind.map (it.value.transactionId) { "${it.second ?: ""}" } }
transactionViewTransactionId.setCellValueFactory { EasyBind.map (it.value.transactionId) { "${it ?: ""}" } }
transactionViewFiberId.setCellValueFactory { EasyBind.map (it.value.fiberId) { "${it?: ""}" } }
transactionViewClientUuid.setCellValueFactory { EasyBind.map (it.value.clientUuid) { "${it ?: ""}" } }
transactionViewProtocolStatus.setCellValueFactory { EasyBind.map(it.value.protocolStatus) { "${it ?: ""}" } }
transactionViewTransactionStatus.setCellValueFactory { it.value.transactionStatus }
transactionViewTransactionStatus.setCellFactory {

View File

@ -44,6 +44,7 @@
<items>
<TableView fx:id="transactionViewTable" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn fx:id="transactionViewTransactionId" prefWidth="75.0" text="Transaction ID" />
<TableColumn fx:id="transactionViewFiberId" prefWidth="187.0" text="Fiber ID" />
<TableColumn fx:id="transactionViewClientUuid" prefWidth="75.0" text="Client UUID" />
<TableColumn fx:id="transactionViewTransactionStatus" prefWidth="75.0" text="Transaction status" />