Corda: add FlowResult class
refactor ActionFlow
This commit is contained in:
parent
218482034d
commit
7df57cb4d2
@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
import djmil.cordacheckers.contracts.GameProposalContract;
|
import djmil.cordacheckers.contracts.GameProposalContract;
|
||||||
import net.corda.v5.base.annotations.ConstructorForDeserialization;
|
import net.corda.v5.base.annotations.ConstructorForDeserialization;
|
||||||
import net.corda.v5.base.annotations.CordaSerializable;
|
import net.corda.v5.base.annotations.CordaSerializable;
|
||||||
|
import net.corda.v5.base.types.MemberX500Name;
|
||||||
import net.corda.v5.ledger.utxo.BelongsToContract;
|
import net.corda.v5.ledger.utxo.BelongsToContract;
|
||||||
import net.corda.v5.ledger.utxo.ContractState;
|
import net.corda.v5.ledger.utxo.ContractState;
|
||||||
|
|
||||||
@ -22,6 +23,14 @@ public class GameProposalResolutionState implements ContractState {
|
|||||||
public final Resolution outcome;
|
public final Resolution outcome;
|
||||||
public final List<PublicKey> participants;
|
public final List<PublicKey> participants;
|
||||||
|
|
||||||
|
public GameProposalResolutionState(
|
||||||
|
Resolution outcome,
|
||||||
|
GameProposalState gameProposal
|
||||||
|
) {
|
||||||
|
this.outcome = outcome;
|
||||||
|
this.participants = gameProposal.getParticipants();
|
||||||
|
}
|
||||||
|
|
||||||
@ConstructorForDeserialization
|
@ConstructorForDeserialization
|
||||||
public GameProposalResolutionState(
|
public GameProposalResolutionState(
|
||||||
Resolution outcome,
|
Resolution outcome,
|
||||||
@ -38,5 +47,17 @@ public class GameProposalResolutionState implements ContractState {
|
|||||||
public List<PublicKey> getParticipants() {
|
public List<PublicKey> getParticipants() {
|
||||||
return this.participants;
|
return this.participants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MemberX500Name getRecipient(GameProposalState gameProposal) {
|
||||||
|
switch (outcome) {
|
||||||
|
case ACCEPT:
|
||||||
|
case REJECT:
|
||||||
|
return gameProposal.getSender();
|
||||||
|
case CANCEL:
|
||||||
|
return gameProposal.getRecipient();
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unknown Resolution value: "+outcome.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package djmil.cordacheckers;
|
||||||
|
|
||||||
|
import net.corda.v5.application.marshalling.JsonMarshallingService;
|
||||||
|
|
||||||
|
public class FlowResult {
|
||||||
|
public final Object successStatus;
|
||||||
|
public final String failureStatus;
|
||||||
|
|
||||||
|
public FlowResult(Object success) {
|
||||||
|
this.successStatus = success;
|
||||||
|
this.failureStatus = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlowResult(Exception exception) {
|
||||||
|
this.successStatus = null;
|
||||||
|
this.failureStatus = exception.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toJsonEncodedString(JsonMarshallingService jsonMarshallingService) {
|
||||||
|
return jsonMarshallingService.format(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,11 +3,16 @@ package djmil.cordacheckers.gameproposal;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.FlowResult;
|
||||||
import djmil.cordacheckers.contracts.GameProposalContract;
|
import djmil.cordacheckers.contracts.GameProposalContract;
|
||||||
import djmil.cordacheckers.states.GameProposalResolutionState;
|
import djmil.cordacheckers.states.GameProposalResolutionState;
|
||||||
import djmil.cordacheckers.states.GameProposalState;
|
import djmil.cordacheckers.states.GameProposalState;
|
||||||
import djmil.cordacheckers.states.GameProposalResolutionState.Resolution;
|
|
||||||
import net.corda.v5.application.flows.ClientRequestBody;
|
import net.corda.v5.application.flows.ClientRequestBody;
|
||||||
import net.corda.v5.application.flows.ClientStartableFlow;
|
import net.corda.v5.application.flows.ClientStartableFlow;
|
||||||
import net.corda.v5.application.flows.CordaInject;
|
import net.corda.v5.application.flows.CordaInject;
|
||||||
@ -18,22 +23,21 @@ import net.corda.v5.application.messaging.FlowMessaging;
|
|||||||
import net.corda.v5.application.messaging.FlowSession;
|
import net.corda.v5.application.messaging.FlowSession;
|
||||||
import net.corda.v5.base.annotations.Suspendable;
|
import net.corda.v5.base.annotations.Suspendable;
|
||||||
import net.corda.v5.base.exceptions.CordaRuntimeException;
|
import net.corda.v5.base.exceptions.CordaRuntimeException;
|
||||||
|
import net.corda.v5.base.types.MemberX500Name;
|
||||||
import net.corda.v5.ledger.utxo.Command;
|
import net.corda.v5.ledger.utxo.Command;
|
||||||
import net.corda.v5.ledger.utxo.StateAndRef;
|
import net.corda.v5.ledger.utxo.StateAndRef;
|
||||||
import net.corda.v5.ledger.utxo.TransactionState;
|
|
||||||
import net.corda.v5.ledger.utxo.UtxoLedgerService;
|
import net.corda.v5.ledger.utxo.UtxoLedgerService;
|
||||||
import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction;
|
import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction;
|
||||||
import net.corda.v5.ledger.utxo.transaction.UtxoTransactionBuilder;
|
import net.corda.v5.ledger.utxo.transaction.UtxoTransactionBuilder;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
@InitiatingFlow(protocol = "game-proposal-action")
|
@InitiatingFlow(protocol = "game-proposal-action")
|
||||||
public class ActionFlow implements ClientStartableFlow {
|
public class ActionFlow implements ClientStartableFlow {
|
||||||
|
|
||||||
|
private final static Logger log = LoggerFactory.getLogger(CreateFlow.class);
|
||||||
|
|
||||||
@CordaInject
|
@CordaInject
|
||||||
public JsonMarshallingService jsonMarshallingService;
|
public JsonMarshallingService jsonMarshallingService;
|
||||||
|
|
||||||
@ -47,62 +51,77 @@ public class ActionFlow implements ClientStartableFlow {
|
|||||||
public MemberLookup memberLookup;
|
public MemberLookup memberLookup;
|
||||||
|
|
||||||
private final static Map<GameProposalResolutionState.Resolution, Command> resoultion2command = Map.ofEntries(
|
private final static Map<GameProposalResolutionState.Resolution, Command> resoultion2command = Map.ofEntries(
|
||||||
entry(GameProposalResolutionState.Resolution.CANCEL, new GameProposalContract.Cancel()),
|
Map.entry(GameProposalResolutionState.Resolution.CANCEL, new GameProposalContract.Cancel()),
|
||||||
entry(GameProposalResolutionState.Resolution.REJECT, new GameProposalContract.Reject()),
|
Map.entry(GameProposalResolutionState.Resolution.REJECT, new GameProposalContract.Reject()),
|
||||||
entry(GameProposalResolutionState.Resolution.ACCEPT, new GameProposalContract.Accept())
|
Map.entry(GameProposalResolutionState.Resolution.ACCEPT, new GameProposalContract.Accept())
|
||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Suspendable
|
@Suspendable
|
||||||
public String call(ClientRequestBody requestBody) {
|
public String call(ClientRequestBody requestBody) {
|
||||||
ActionFlowArgs args = requestBody.getRequestBodyAs(jsonMarshallingService, ActionFlowArgs.class);
|
try {
|
||||||
|
ActionFlowArgs args = requestBody.getRequestBodyAs(jsonMarshallingService, ActionFlowArgs.class);
|
||||||
|
|
||||||
|
StateAndRef<GameProposalState> inputState = findUnconsumedGameProposalState(args.getGameProposalUuid());
|
||||||
|
|
||||||
|
GameProposalResolutionState outputState = new GameProposalResolutionState(
|
||||||
|
args.getAction(),
|
||||||
|
inputState.getState().getContractState()
|
||||||
|
);
|
||||||
|
|
||||||
|
String trxResult = doTrunsaction(inputState, outputState);
|
||||||
|
|
||||||
|
return new FlowResult(trxResult).toJsonEncodedString(jsonMarshallingService);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.warn("GameProposalAction flow failed to process utxo request body " + requestBody +
|
||||||
|
" because: " + e.getMessage());
|
||||||
|
return new FlowResult(e).toJsonEncodedString(jsonMarshallingService);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suspendable
|
||||||
|
private StateAndRef<GameProposalState> findUnconsumedGameProposalState (UUID gameProposalUuid) {
|
||||||
/*
|
/*
|
||||||
* Look up the latest unconsumed ChatState with the given id.
|
* Get list of all unconsumed aka 'actuve' GameProposalStates, then filter by UUID.
|
||||||
* Note, this code brings all unconsumed states back, then filters them. This is an
|
* Note, this is an inefficient way to perform this operation if there are a large
|
||||||
* inefficient way to perform this operation when there are a large number of chats
|
* number of 'active' GameProposals exists in storage.
|
||||||
*/
|
*/
|
||||||
List<StateAndRef<GameProposalState>> stateAndRefs = this.ledgerService
|
List<StateAndRef<GameProposalState>> stateAndRefs = this.ledgerService
|
||||||
.findUnconsumedStatesByType(GameProposalState.class);
|
.findUnconsumedStatesByType(GameProposalState.class)
|
||||||
|
|
||||||
List<StateAndRef<GameProposalState>> stateAndRefsWithId = stateAndRefs
|
|
||||||
.stream()
|
.stream()
|
||||||
.filter(sar -> sar.getState().getContractState().getId().equals(args.gameProposalUuid))
|
.filter(sar -> sar.getState().getContractState().getId().equals(gameProposalUuid))
|
||||||
.collect(toList());
|
.collect(Collectors.toList());
|
||||||
if (stateAndRefsWithId.size() != 1)
|
|
||||||
throw new CordaRuntimeException("Multiple or zero GameProposal states with id " + args.gameProposalUuid + " found");
|
if (stateAndRefs.size() != 1) {
|
||||||
|
throw new CordaRuntimeException("Expected only one GameProposal state with id " + gameProposalUuid +
|
||||||
|
", but found " + stateAndRefs.size());
|
||||||
|
}
|
||||||
|
|
||||||
StateAndRef<GameProposalState> stateAndRef = stateAndRefsWithId.get(0);
|
return stateAndRefs.get(0);
|
||||||
TransactionState<GameProposalState> trxState = stateAndRef.getState();
|
}
|
||||||
GameProposalState state = trxState.getContractState();
|
|
||||||
|
|
||||||
GameProposalResolutionState outputState = new GameProposalResolutionState(
|
@Suspendable
|
||||||
GameProposalResolutionState.Resolution.valueOf(args.action),
|
private String doTrunsaction(StateAndRef<GameProposalState> inputState, GameProposalResolutionState outputState) {
|
||||||
state.getParticipants()
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build draft trx
|
|
||||||
*/
|
|
||||||
UtxoTransactionBuilder txBuilder = ledgerService.createTransactionBuilder()
|
UtxoTransactionBuilder txBuilder = ledgerService.createTransactionBuilder()
|
||||||
.setNotary(trxState.getNotaryName())
|
.setNotary(inputState.getState().getNotaryName())
|
||||||
.setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis()))
|
.setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis()))
|
||||||
.addInputState(stateAndRef.getRef())
|
.addInputState(inputState.getRef())
|
||||||
.addOutputState(outputState)
|
.addOutputState(outputState)
|
||||||
.addCommand(resoultion2command.get(outputState.outcome))
|
.addCommand(resoultion2command.get(outputState.outcome))
|
||||||
.addSignatories(state.getParticipants());
|
.addSignatories(outputState.getParticipants());
|
||||||
|
|
||||||
UtxoSignedTransaction signedTransaction = txBuilder.toSignedTransaction();
|
UtxoSignedTransaction signedTransaction = txBuilder.toSignedTransaction();
|
||||||
|
|
||||||
FlowSession session = flowMessaging.initiateFlow(
|
FlowSession session = flowMessaging.initiateFlow(
|
||||||
outputState.outcome == Resolution.CANCEL ? state.getRecipient() : state.getSender() // TODO: readability
|
outputState.getRecipient(inputState.getState().getContractState())
|
||||||
);
|
);
|
||||||
|
|
||||||
List<FlowSession> sessionsList = Arrays.asList(session);
|
List<FlowSession> sessionsList = Arrays.asList(session);
|
||||||
|
|
||||||
ledgerService.finalize(signedTransaction, sessionsList);
|
ledgerService.finalize(signedTransaction, sessionsList);
|
||||||
|
|
||||||
return args.action+"ED"; // REJECT+ED
|
return outputState.getOutcome()+"ED"; // REJECT+ED
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,12 @@ package djmil.cordacheckers.gameproposal;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.states.GameProposalResolutionState;
|
||||||
|
import djmil.cordacheckers.states.GameProposalResolutionState.Resolution;
|
||||||
|
|
||||||
public class ActionFlowArgs {
|
public class ActionFlowArgs {
|
||||||
public final UUID gameProposalUuid;
|
private UUID gameProposalUuid;
|
||||||
public final String action;
|
private String action;
|
||||||
|
|
||||||
// Serialisation service requires a default constructor
|
// Serialisation service requires a default constructor
|
||||||
public ActionFlowArgs() {
|
public ActionFlowArgs() {
|
||||||
@ -12,4 +15,11 @@ public class ActionFlowArgs {
|
|||||||
this.action = null;
|
this.action = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Resolution getAction() {
|
||||||
|
return GameProposalResolutionState.Resolution.valueOf(this.action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getGameProposalUuid() {
|
||||||
|
return this.gameProposalUuid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,9 @@ public class ActionResponder implements ResponderFlow {
|
|||||||
@Override
|
@Override
|
||||||
public void call(FlowSession session) {
|
public void call(FlowSession session) {
|
||||||
try {
|
try {
|
||||||
// Defines the lambda validator used in receiveFinality below.
|
|
||||||
UtxoTransactionValidator txValidator = ledgerTransaction -> {
|
UtxoTransactionValidator txValidator = ledgerTransaction -> {
|
||||||
GameProposalState gameProposal = (GameProposalState) ledgerTransaction.getInputContractStates().get(0);
|
GameProposalState gameProposal = (GameProposalState) ledgerTransaction.getInputContractStates().get(0);
|
||||||
// Uses checkForBannedWords() and checkMessageFromMatchesCounterparty() functions
|
|
||||||
// to check whether to sign the transaction.
|
|
||||||
|
|
||||||
Command command = ledgerTransaction.getCommands(Command.class).get(0);
|
Command command = ledgerTransaction.getCommands(Command.class).get(0);
|
||||||
|
|
||||||
if (!checkParticipants(gameProposal, session.getCounterparty(), command)) {
|
if (!checkParticipants(gameProposal, session.getCounterparty(), command)) {
|
||||||
@ -68,7 +65,7 @@ public class ActionResponder implements ResponderFlow {
|
|||||||
@Suspendable
|
@Suspendable
|
||||||
Boolean checkParticipants(GameProposalState gameProposal, MemberX500Name counterpartyName, Command command) {
|
Boolean checkParticipants(GameProposalState gameProposal, MemberX500Name counterpartyName, Command command) {
|
||||||
MemberX500Name myName = memberLookup.myInfo().getName();
|
MemberX500Name myName = memberLookup.myInfo().getName();
|
||||||
log.info("Responder validation:\n command "+command+"\n me " + myName.toString() + "\n opponent " + counterpartyName.toString());
|
|
||||||
if (command instanceof Reject || command instanceof Accept) {
|
if (command instanceof Reject || command instanceof Accept) {
|
||||||
if (gameProposal.getRecipient().compareTo(counterpartyName) == 0 &&
|
if (gameProposal.getRecipient().compareTo(counterpartyName) == 0 &&
|
||||||
gameProposal.getSender().compareTo(myName) == 0)
|
gameProposal.getSender().compareTo(myName) == 0)
|
||||||
|
@ -3,6 +3,7 @@ package djmil.cordacheckers.gameproposal;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.FlowResult;
|
||||||
import djmil.cordacheckers.contracts.GameProposalContract;
|
import djmil.cordacheckers.contracts.GameProposalContract;
|
||||||
import djmil.cordacheckers.states.GameProposalState;
|
import djmil.cordacheckers.states.GameProposalState;
|
||||||
import net.corda.v5.application.flows.ClientRequestBody;
|
import net.corda.v5.application.flows.ClientRequestBody;
|
||||||
@ -15,7 +16,6 @@ import net.corda.v5.application.membership.MemberLookup;
|
|||||||
import net.corda.v5.application.messaging.FlowMessaging;
|
import net.corda.v5.application.messaging.FlowMessaging;
|
||||||
import net.corda.v5.application.messaging.FlowSession;
|
import net.corda.v5.application.messaging.FlowSession;
|
||||||
import net.corda.v5.base.annotations.Suspendable;
|
import net.corda.v5.base.annotations.Suspendable;
|
||||||
import net.corda.v5.base.exceptions.CordaRuntimeException;
|
|
||||||
import net.corda.v5.base.types.MemberX500Name;
|
import net.corda.v5.base.types.MemberX500Name;
|
||||||
import net.corda.v5.ledger.common.NotaryLookup;
|
import net.corda.v5.ledger.common.NotaryLookup;
|
||||||
import net.corda.v5.ledger.utxo.UtxoLedgerService;
|
import net.corda.v5.ledger.utxo.UtxoLedgerService;
|
||||||
@ -62,13 +62,14 @@ public class CreateFlow implements ClientStartableFlow{
|
|||||||
log.info("flow: Create Game Proposal");
|
log.info("flow: Create Game Proposal");
|
||||||
|
|
||||||
GameProposalState gameProposal = buildGameProposalStateFrom(requestBody);
|
GameProposalState gameProposal = buildGameProposalStateFrom(requestBody);
|
||||||
String result = doTrunsaction(gameProposal);
|
String trxResult = doTrunsaction(gameProposal);
|
||||||
|
|
||||||
return result;
|
return new FlowResult(trxResult).toJsonEncodedString(jsonMarshallingService);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
log.warn("CreateGameProposal flow failed to process utxo request body " + requestBody + " because: " + e.getMessage());
|
log.warn("CreateGameProposal flow failed to process utxo request body " + requestBody +
|
||||||
throw new CordaRuntimeException(e.getMessage());
|
" because: " + e.getMessage());
|
||||||
|
return new FlowResult(e).toJsonEncodedString(jsonMarshallingService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,12 +117,7 @@ public class CreateFlow implements ClientStartableFlow{
|
|||||||
|
|
||||||
List<FlowSession> sessionsList = Arrays.asList(session);
|
List<FlowSession> sessionsList = Arrays.asList(session);
|
||||||
|
|
||||||
UtxoSignedTransaction finalizedSignedTransaction = ledgerService
|
ledgerService.finalize(signedTransaction, sessionsList);
|
||||||
.finalize(signedTransaction, sessionsList)
|
|
||||||
.getTransaction();
|
|
||||||
|
|
||||||
|
|
||||||
// final String trxId = finalizedSignedTransaction.getId().toString();
|
|
||||||
|
|
||||||
return gameProposal.id.toString();
|
return gameProposal.id.toString();
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
package djmil.cordacheckers.gameproposal;
|
package djmil.cordacheckers.gameproposal;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.FlowResult;
|
||||||
import djmil.cordacheckers.states.GameProposalState;
|
import djmil.cordacheckers.states.GameProposalState;
|
||||||
import net.corda.v5.application.flows.ClientRequestBody;
|
import net.corda.v5.application.flows.ClientRequestBody;
|
||||||
import net.corda.v5.application.flows.ClientStartableFlow;
|
import net.corda.v5.application.flows.ClientStartableFlow;
|
||||||
import net.corda.v5.application.flows.CordaInject;
|
import net.corda.v5.application.flows.CordaInject;
|
||||||
import net.corda.v5.application.marshalling.JsonMarshallingService;
|
import net.corda.v5.application.marshalling.JsonMarshallingService;
|
||||||
import net.corda.v5.ledger.utxo.StateAndRef;
|
import net.corda.v5.base.annotations.Suspendable;
|
||||||
import net.corda.v5.ledger.utxo.UtxoLedgerService;
|
import net.corda.v5.ledger.utxo.UtxoLedgerService;
|
||||||
|
|
||||||
public class ListFlow implements ClientStartableFlow {
|
public class ListFlow implements ClientStartableFlow {
|
||||||
@ -23,19 +25,25 @@ public class ListFlow implements ClientStartableFlow {
|
|||||||
@CordaInject
|
@CordaInject
|
||||||
public JsonMarshallingService jsonMarshallingService;
|
public JsonMarshallingService jsonMarshallingService;
|
||||||
|
|
||||||
|
@Suspendable
|
||||||
@Override
|
@Override
|
||||||
public String call(ClientRequestBody requestBody) {
|
public String call(ClientRequestBody requestBody) {
|
||||||
log.info("ListChatsFlow.call() called");
|
try {
|
||||||
|
log.info("ListChatsFlow.call() called");
|
||||||
|
|
||||||
// Queries the VNode's vault for unconsumed states and converts the result to a serializable DTO.
|
// Queries the VNode's vault for unconsumed states and converts the resulting
|
||||||
java.util.List<StateAndRef<GameProposalState>> states = utxoLedgerService.findUnconsumedStatesByType(GameProposalState.class);
|
// List<StateAndRef<GameProposalState>> to a _serializable_ List<ListItem> DTO
|
||||||
|
List<ListItem> unconsumedGameProposaList = utxoLedgerService
|
||||||
|
.findUnconsumedStatesByType(GameProposalState.class)
|
||||||
|
.stream()
|
||||||
|
.map( stateAndRef -> new ListItem(stateAndRef.getState().getContractState()) )
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
java.util.List<ListItem> results = states.stream().map( stateAndRef ->
|
return new FlowResult(unconsumedGameProposaList).toJsonEncodedString(jsonMarshallingService);
|
||||||
new ListItem(stateAndRef.getState().getContractState())
|
} catch (Exception e) {
|
||||||
).collect(Collectors.toList());
|
log.warn("CreateGameProposal flow failed to process utxo request body " + requestBody + " because: " + e.getMessage());
|
||||||
|
return new FlowResult(e).toJsonEncodedString(jsonMarshallingService);
|
||||||
// Uses the JsonMarshallingService's format() function to serialize the DTO to Json.
|
}
|
||||||
return jsonMarshallingService.format(results);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user