From 21a770782576553a1a9aac38410eb070de07d7e2 Mon Sep 17 00:00:00 2001 From: Andras Slemmer Date: Mon, 12 Sep 2016 14:17:50 +0100 Subject: [PATCH] explorer: Map transactions by tx id as well --- .../model/GatheredTransactionDataModel.kt | 64 ++++++++++++++----- .../explorer/views/TransactionViewer.kt | 15 +++-- .../explorer/views/TransactionViewer.fxml | 1 + 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/client/src/main/kotlin/com/r3corda/client/model/GatheredTransactionDataModel.kt b/client/src/main/kotlin/com/r3corda/client/model/GatheredTransactionDataModel.kt index a15e6f66a5..49e262f33b 100644 --- a/client/src/main/kotlin/com/r3corda/client/model/GatheredTransactionDataModel.kt +++ b/client/src/main/kotlin/com/r3corda/client/model/GatheredTransactionDataModel.kt @@ -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, 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, + 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 } diff --git a/explorer/src/main/kotlin/com/r3corda/explorer/views/TransactionViewer.kt b/explorer/src/main/kotlin/com/r3corda/explorer/views/TransactionViewer.kt index c249f4e2d3..4f0a0af951 100644 --- a/explorer/src/main/kotlin/com/r3corda/explorer/views/TransactionViewer.kt +++ b/explorer/src/main/kotlin/com/r3corda/explorer/views/TransactionViewer.kt @@ -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 by fxid() + private val transactionViewTransactionId: TableColumn by fxid() private val transactionViewFiberId: TableColumn by fxid() private val transactionViewClientUuid: TableColumn by fxid() private val transactionViewTransactionStatus: TableColumn by fxid() @@ -92,7 +94,9 @@ class TransactionViewer: View() { private val myIdentity: ObservableValue by observableValue(IdentityModel::myIdentity) data class ViewerNode( - val transactionId: ObservableValue>, + val transactionId: ObservableValue, + val fiberId: ObservableValue, + val clientUuid: ObservableValue, val originator: ObservableValue, val transactionStatus: ObservableValue, val stateMachineStatus: ObservableValue, @@ -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 { diff --git a/explorer/src/main/resources/com/r3corda/explorer/views/TransactionViewer.fxml b/explorer/src/main/resources/com/r3corda/explorer/views/TransactionViewer.fxml index 377fb41180..1b43458c58 100644 --- a/explorer/src/main/resources/com/r3corda/explorer/views/TransactionViewer.fxml +++ b/explorer/src/main/resources/com/r3corda/explorer/views/TransactionViewer.fxml @@ -44,6 +44,7 @@ +