From f15bb6a540da4317de2c99cab949de9bda9fc629 Mon Sep 17 00:00:00 2001 From: Ghareeb Falazi Date: Tue, 15 Oct 2024 22:40:48 +0200 Subject: [PATCH 1/3] make SCIP interface similar to dissertation specification --- .../uni/stuttgart/de/jsonrpc/BalService.java | 94 +++++++++---------- .../de/jsonrpc/model/MemberSignature.java | 13 +++ 2 files changed, 59 insertions(+), 48 deletions(-) create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/MemberSignature.java diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java index 4197dcf..a3e9246 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 Institute for the Architecture of Application System - University of Stuttgart + * Copyright (c) 2019-2024 Institute for the Architecture of Application System - University of Stuttgart * Author: Ghareeb Falazi * * This program and the accompanying materials are made available under the @@ -12,9 +12,11 @@ package blockchains.iaas.uni.stuttgart.de.jsonrpc; import java.util.List; +import java.util.Optional; import java.util.UUID; import blockchains.iaas.uni.stuttgart.de.api.exceptions.InvalidScipParameterException; +import blockchains.iaas.uni.stuttgart.de.jsonrpc.model.MemberSignature; import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; import blockchains.iaas.uni.stuttgart.de.api.model.QueryResult; @@ -48,66 +50,66 @@ public BalService(String blockchainType, String blockchainId, String smartContra @JsonRpcMethod public String Invoke( - @JsonRpcParam("functionIdentifier") String functionIdentifier, - @JsonRpcParam("inputs") List inputs, - @JsonRpcParam("outputs") List outputs, - @JsonRpcParam("doc") double requiredConfidence, + @JsonRpcParam("signature") MemberSignature memberSignature, + @JsonRpcParam("inputArguments") List inputs, + @JsonRpcParam("outputParams") List outputs, @JsonRpcParam("callbackUrl") String callbackUrl, - @JsonRpcParam("timeout") long timeoutMillis, - @JsonRpcParam("correlationIdentifier") String correlationId, - @JsonRpcParam("signature") String signature + @JsonRpcParam("correlationId") String correlationId, + @JsonRpcParam("callbackBinding") String callbackBinding, + @JsonRpcParam("sideEffects") boolean sideEffects, + @JsonRpcOptional @JsonRpcParam("degreeOfConfidence") double requiredConfidence, + @JsonRpcOptional @JsonRpcParam("timeout") Long timeoutMillis, + @JsonRpcOptional @JsonRpcParam("Nonce") Long nonce, + @JsonRpcOptional @JsonRpcParam("digitalSignature") String digitalSignature ) { log.info("SCIP Invoke method is executed!"); + + for(Parameter input : inputs) { + Optional fromSig = memberSignature.getParameters().stream().filter(p -> p.getName().equals(input.getName())).findFirst(); + input.setType(fromSig.orElseThrow(InvalidScipParameterException::new).getType()); + } + if (inputs.stream().anyMatch(p -> p.getName().equals(DTX_ID_FIELD_NAME))) { - dtxManager.invokeSc(blockchainId, smartContractPath, functionIdentifier, inputs, outputs, - requiredConfidence, callbackUrl, timeoutMillis, correlationId, signature); + dtxManager.invokeSc(blockchainId, smartContractPath, memberSignature.getName(), inputs, outputs, + requiredConfidence, callbackUrl, timeoutMillis, correlationId, digitalSignature); } else { - manager.invokeSmartContractFunction(blockchainId, smartContractPath, functionIdentifier, inputs, outputs, - requiredConfidence, callbackUrl, timeoutMillis, correlationId, signature); + manager.invokeSmartContractFunction(blockchainId, smartContractPath, memberSignature.getName(), inputs, outputs, + requiredConfidence, callbackUrl, timeoutMillis, correlationId, digitalSignature); } + return "OK"; } @JsonRpcMethod public String Subscribe( - @JsonRpcOptional @JsonRpcParam("functionIdentifier") String functionIdentifier, - @JsonRpcOptional @JsonRpcParam("eventIdentifier") String eventIdentifier, - @JsonRpcParam("parameters") List outputParameters, - @JsonRpcParam("doc") double degreeOfConfidence, - @JsonRpcParam("filter") String filter, + @JsonRpcParam("signature") MemberSignature memberSignature, @JsonRpcParam("callbackUrl") String callbackUrl, - @JsonRpcParam("correlationIdentifier") String correlationId) { + @JsonRpcParam("correlationId") String correlationId, + @JsonRpcOptional @JsonRpcParam("degreeOfConfidence") double degreeOfConfidence, + @JsonRpcOptional @JsonRpcParam("filter") String filter + ) { log.info("SCIP Subscribe method is executed!"); - if (!Strings.isNullOrEmpty(functionIdentifier) && !Strings.isNullOrEmpty(eventIdentifier)) { - throw new InvalidScipParameterException(); - } - if (!Strings.isNullOrEmpty(eventIdentifier)) { - manager.subscribeToEvent(blockchainId, smartContractPath, eventIdentifier, outputParameters, degreeOfConfidence, filter, callbackUrl, correlationId); + if (!memberSignature.isFunction()) { + manager.subscribeToEvent(blockchainId, smartContractPath, memberSignature.getName(), memberSignature.getParameters(), degreeOfConfidence, filter, callbackUrl, correlationId); + } else { + log.error("Not all SCIP adapters support subscribing to function occurrences. Cannot process request!"); + throw new InvalidScipParameterException(); } return "OK"; } @JsonRpcMethod - public String Unsubscribe(@JsonRpcOptional @JsonRpcParam("functionIdentifier") String functionIdentifier, - @JsonRpcOptional @JsonRpcParam("eventIdentifier") String eventIdentifier, - @JsonRpcParam("parameters") List parameters, - @JsonRpcParam("correlationIdentifier") String correlationId) { + public String Unsubscribe(@JsonRpcOptional @JsonRpcParam("signature") MemberSignature memberSignature, + @JsonRpcParam("correlationId") String correlationId) { log.info("SCIP Unsubscribe method is executed!"); - if (!Strings.isNullOrEmpty(functionIdentifier) && !Strings.isNullOrEmpty(eventIdentifier)) { - throw new InvalidScipParameterException(); - } - - if (Strings.isNullOrEmpty(functionIdentifier) && Strings.isNullOrEmpty(eventIdentifier) && parameters != null) { - throw new InvalidScipParameterException(); - } - if (!Strings.isNullOrEmpty(functionIdentifier)) { - manager.cancelFunctionSubscriptions(blockchainId, smartContractPath, correlationId, functionIdentifier, parameters); + if (memberSignature.isFunction()) { + manager.cancelFunctionSubscriptions(blockchainId, smartContractPath, correlationId, memberSignature.getName(), memberSignature.getParameters()); } else { - manager.cancelEventSubscriptions(blockchainId, smartContractPath, correlationId, eventIdentifier, parameters); + manager.cancelEventSubscriptions(blockchainId, smartContractPath, correlationId, memberSignature.getName(), memberSignature.getParameters()); } return "OK"; @@ -115,22 +117,18 @@ public String Unsubscribe(@JsonRpcOptional @JsonRpcParam("functionIdentifier") S @JsonRpcMethod public QueryResult Query( - @JsonRpcOptional @JsonRpcParam("functionIdentifier") String functionIdentifier, - @JsonRpcOptional @JsonRpcParam("eventIdentifier") String eventIdentifier, + @JsonRpcOptional @JsonRpcParam("signature") MemberSignature memberSignature, @JsonRpcOptional @JsonRpcParam("filter") String filter, - @JsonRpcOptional @JsonRpcParam("timeframe") TimeFrame timeFrame, - @JsonRpcParam("parameters") List outputParameters) { + @JsonRpcOptional @JsonRpcParam("timeframe") TimeFrame timeFrame) { log.info("SCIP Query method is executed!"); - - if (!Strings.isNullOrEmpty(functionIdentifier) && !Strings.isNullOrEmpty(eventIdentifier)) { + + if (!memberSignature.isFunction()) { + return manager.queryEvents(blockchainId, smartContractPath, memberSignature.getName(), memberSignature.getParameters(), filter, timeFrame); + } else { + log.error("Not all SCIP adapters support subscribing to function occurrences. Cannot process request!"); throw new InvalidScipParameterException(); } - if (!Strings.isNullOrEmpty(eventIdentifier)) { - return manager.queryEvents(blockchainId, smartContractPath, eventIdentifier, outputParameters, filter, timeFrame); - } - - throw new InvalidScipParameterException(); } @JsonRpcMethod diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/MemberSignature.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/MemberSignature.java new file mode 100644 index 0000000..f7d4d27 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/MemberSignature.java @@ -0,0 +1,13 @@ +package blockchains.iaas.uni.stuttgart.de.jsonrpc.model; + +import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; +import lombok.Data; + +import java.util.List; + +@Data +public class MemberSignature { + private String name; + private boolean isFunction; + private List parameters; +} From 5d0383846671e358d1ab01ec5c468e90485d6f38 Mon Sep 17 00:00:00 2001 From: Ghareeb Falazi Date: Fri, 18 Oct 2024 11:29:29 +0200 Subject: [PATCH 2/3] Change BlockchainManager & DistributedTransactionManager APIs for invoking smart contracts and subscribing to events Make API satisfy SCIP spec --- .../uni/stuttgart/de/jsonrpc/BalService.java | 30 +++++++++---------- .../de/management/BlockchainManager.java | 15 ++++++---- .../tccsci/DistributedTransactionManager.java | 17 ++++++----- .../DistributedTransactionManagerTest.java | 25 +++++++++------- 4 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java index a3e9246..87fd181 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java @@ -11,34 +11,32 @@ package blockchains.iaas.uni.stuttgart.de.jsonrpc; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - import blockchains.iaas.uni.stuttgart.de.api.exceptions.InvalidScipParameterException; -import blockchains.iaas.uni.stuttgart.de.jsonrpc.model.MemberSignature; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; import blockchains.iaas.uni.stuttgart.de.api.model.QueryResult; import blockchains.iaas.uni.stuttgart.de.api.model.TimeFrame; +import blockchains.iaas.uni.stuttgart.de.jsonrpc.model.MemberSignature; +import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; import blockchains.iaas.uni.stuttgart.de.management.tccsci.DistributedTransactionManager; -import blockchains.iaas.uni.stuttgart.de.management.tccsci.DistributedTransactionRepository; import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcMethod; import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcOptional; import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcParam; import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcService; -import com.google.common.base.Strings; import lombok.extern.log4j.Log4j2; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + @JsonRpcService @Log4j2 public class BalService { + private static final String DTX_ID_FIELD_NAME = "dtx_id"; private final String blockchainType; private final String blockchainId; private final String smartContractPath; private final BlockchainManager manager; private final DistributedTransactionManager dtxManager; - private static final String DTX_ID_FIELD_NAME = "dtx_id"; public BalService(String blockchainType, String blockchainId, String smartContractPath, BlockchainManager manager, DistributedTransactionManager dtxManager) { this.blockchainType = blockchainType; @@ -64,17 +62,17 @@ public String Invoke( ) { log.info("SCIP Invoke method is executed!"); - for(Parameter input : inputs) { + for (Parameter input : inputs) { Optional fromSig = memberSignature.getParameters().stream().filter(p -> p.getName().equals(input.getName())).findFirst(); input.setType(fromSig.orElseThrow(InvalidScipParameterException::new).getType()); } if (inputs.stream().anyMatch(p -> p.getName().equals(DTX_ID_FIELD_NAME))) { dtxManager.invokeSc(blockchainId, smartContractPath, memberSignature.getName(), inputs, outputs, - requiredConfidence, callbackUrl, timeoutMillis, correlationId, digitalSignature); + requiredConfidence, callbackBinding, sideEffects, nonce, callbackUrl, timeoutMillis, correlationId, digitalSignature); } else { manager.invokeSmartContractFunction(blockchainId, smartContractPath, memberSignature.getName(), inputs, outputs, - requiredConfidence, callbackUrl, timeoutMillis, correlationId, digitalSignature); + requiredConfidence, callbackBinding, sideEffects, nonce, callbackUrl, timeoutMillis, correlationId, digitalSignature); } return "OK"; @@ -85,14 +83,14 @@ public String Subscribe( @JsonRpcParam("signature") MemberSignature memberSignature, @JsonRpcParam("callbackUrl") String callbackUrl, @JsonRpcParam("correlationId") String correlationId, + @JsonRpcParam("callbackBinding") String callbackBinding, @JsonRpcOptional @JsonRpcParam("degreeOfConfidence") double degreeOfConfidence, @JsonRpcOptional @JsonRpcParam("filter") String filter - ) { + ) { log.info("SCIP Subscribe method is executed!"); - if (!memberSignature.isFunction()) { - manager.subscribeToEvent(blockchainId, smartContractPath, memberSignature.getName(), memberSignature.getParameters(), degreeOfConfidence, filter, callbackUrl, correlationId); + manager.subscribeToEvent(blockchainId, smartContractPath, memberSignature.getName(), memberSignature.getParameters(), degreeOfConfidence, filter, callbackBinding, callbackUrl, correlationId); } else { log.error("Not all SCIP adapters support subscribing to function occurrences. Cannot process request!"); throw new InvalidScipParameterException(); @@ -121,7 +119,7 @@ public QueryResult Query( @JsonRpcOptional @JsonRpcParam("filter") String filter, @JsonRpcOptional @JsonRpcParam("timeframe") TimeFrame timeFrame) { log.info("SCIP Query method is executed!"); - + if (!memberSignature.isFunction()) { return manager.queryEvents(blockchainId, smartContractPath, memberSignature.getName(), memberSignature.getParameters(), filter, timeFrame); } else { diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainManager.java index 5593356..c022150 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainManager.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainManager.java @@ -51,7 +51,7 @@ public BlockchainManager(AdapterManager adapterManager) { * The status of the result could be: *

* UNKNOWN: the blockchain network is not recognized, or connection to node is not possible. - * INVALID: the submitted transaction faild validation at the node + * INVALID: the submitted transaction failed validation at the node * CONFIRMED (along with the tx itself): the submitted transaction received the desired number of block-confirmations * * @param correlationId supplied by the remote application as a means for correlation @@ -328,6 +328,7 @@ public void ensureTransactionState(final String correlationId, final String tran // todo add support for timeouts // todo add support for signature checking + // todo add support for nonce /** * Invokes a smart contract function, and sends a callback message informing a remote endpoint of the result. @@ -345,10 +346,13 @@ public void ensureTransactionState(final String correlationId, final String tran * @param inputs the arguments to be passed to the smart contract function * @param outputs the types of output parameters expected from the function * @param requiredConfidence the minimum confidence that the submitted transaction must reach before returning a CONFIRMED response (percentage) + * @param callbackBinding the binding to use when sending asynchronous callback messages. + * @param nonce a monotonically increasing number for the invocation requests sent by the user + * @param sideEffects indicates whether the function being invoked might have side effects in the blockchain. * @param callbackUrl the url of the endpoint to send the callback message to * @param timeoutMillis the number of milliseconds during which the doc must be reached, otherwise a timeout error message has to be returned. * @param correlationId applied by the remote application as a means for correlation - * @param signature the user signature of the previous fields (apart from smart contract path) + * @param signature the user's digital signature of the previous fields (apart from smart contract path) */ public void invokeSmartContractFunction( final String blockchainIdentifier, @@ -357,6 +361,9 @@ public void invokeSmartContractFunction( final List inputs, final List outputs, final double requiredConfidence, + final String callbackBinding, + final boolean sideEffects, + final Long nonce, final String callbackUrl, final long timeoutMillis, final String correlationId, @@ -450,15 +457,13 @@ public void subscribeToEvent( final List outputParameters, final double degreeOfConfidence, final String filter, + final String callbackBinding, final String callbackUrl, final String correlationIdentifier) { - - // first, we cancel previous identical subscriptions. this.cancelEventSubscriptions(blockchainIdentifier, smartContractPath, correlationIdentifier, eventIdentifier, outputParameters); - Disposable result = this.subscribeToEvent(blockchainIdentifier, smartContractPath, eventIdentifier, outputParameters, degreeOfConfidence, filter) .doFinally(() -> { // remove subscription from subscription list diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManager.java index bfa1317..9d32a0e 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManager.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManager.java @@ -31,11 +31,16 @@ public class DistributedTransactionManager { private final AdapterManager adapterManager; private final BlockchainManager blockchainManager; - public DistributedTransactionManager(AdapterManager adapterManager, BlockchainManager blockchainManager){ + public DistributedTransactionManager(AdapterManager adapterManager, BlockchainManager blockchainManager) { this.adapterManager = adapterManager; this.blockchainManager = blockchainManager; } + private static String buildEventFilter(SmartContractEvent abortEvent, UUID txId) { + String param1Name = abortEvent.getOutputs().get(0).getName(); + return param1Name + "==\"" + txId.toString() + "\""; + } + public UUID startDtx() { DistributedTransaction tx = new DistributedTransaction(); DistributedTransactionRepository.getInstance().addDistributedTransaction(tx); @@ -50,6 +55,9 @@ public void invokeSc(final String blockchainIdentifier, final List inputs, final List outputs, final double requiredConfidence, + final String callbackBinding, + final boolean sideEffects, + final Long nonce, final String callbackUrl, final long timeoutMillis, final String correlationId, @@ -76,7 +84,7 @@ public void invokeSc(final String blockchainIdentifier, } blockchainManager.invokeSmartContractFunction(blockchainIdentifier, smartContractPath, functionIdentifier, inputs, - outputs, requiredConfidence, callbackUrl, timeoutMillis, correlationId, signature); + outputs, requiredConfidence, callbackBinding, sideEffects, nonce, callbackUrl, timeoutMillis, correlationId, signature); } } @@ -127,11 +135,6 @@ public void commitDtx(UUID txId) { } } - private static String buildEventFilter(SmartContractEvent abortEvent, UUID txId) { - String param1Name = abortEvent.getOutputs().get(0).getName(); - return param1Name + "==\"" + txId.toString() + "\""; - } - private void handleScError(Occurrence errorDetails) { String txIdString = errorDetails.getParameters().get(0).getValue(); log.info("Received an abort event for dtx: {}", txIdString); diff --git a/src/test/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManagerTest.java b/src/test/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManagerTest.java index 178560a..57e2a69 100644 --- a/src/test/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManagerTest.java +++ b/src/test/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManagerTest.java @@ -100,7 +100,7 @@ void testAwaitingRequestsState() { /* DtxInvoke 1 */ Parameter uuidParameter = new Parameter("txid", "string", uuid.toString()); dManager.invokeSc("bc1", "sc1", "userF1", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L, "callback-url", 0, "ABC", ""); DistributedTransaction dtx = DistributedTransactionRepository.getInstance().getById(uuid); assertEquals(1, dtx.getBlockchainIds().size()); assertTrue(dtx.getBlockchainIds().contains("bc1")); @@ -112,7 +112,7 @@ void testAwaitingRequestsState() { /* DtxInvoke 2 */ dManager.invokeSc("bc1", "sc2", "userF2", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); dtx = DistributedTransactionRepository.getInstance().getById(uuid); assertEquals(1, dtx.getBlockchainIds().size()); assertTrue(dtx.getBlockchainIds().contains("bc1")); @@ -124,7 +124,7 @@ void testAwaitingRequestsState() { /* DtxInvoke 3 */ dManager.invokeSc("bc2", "sc3", "userF3", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); dtx = DistributedTransactionRepository.getInstance().getById(uuid); assertEquals(2, dtx.getBlockchainIds().size()); assertTrue(dtx.getBlockchainIds().contains("bc1")); @@ -150,11 +150,11 @@ void testAwaitingVotesStateToCommit() { /* DtxInvoke bc1 */ Parameter uuidParameter = new Parameter("txid", "string", uuid.toString()); dManager.invokeSc("bc1", "sc1", "userF1", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* DtxInvoke bc2 */ dManager.invokeSc("bc2", "sc2", "userF2", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* DtxCommit */ dManager.commitDtx(uuid); @@ -191,11 +191,11 @@ void testAwaitingVotesStateToAbort() { /* DtxInvoke bc1 */ Parameter uuidParameter = new Parameter("txid", "string", uuid.toString()); dManager.invokeSc("bc1", "sc1", "userF1", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* DtxInvoke bc2 */ dManager.invokeSc("bc2", "sc2", "userF2", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* DtxCommit */ dManager.commitDtx(uuid); @@ -230,11 +230,11 @@ void testAbortViaError() { /* DtxInvoke bc1 */ Parameter uuidParameter = new Parameter("txid", "string", uuid.toString()); dManager.invokeSc("bc1", "sc1", "userF1", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* DtxInvoke bc2 */ dManager.invokeSc("bc2", "sc2", "userF2", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* SC Error */ manager.emitAborts(uuid, "bc2"); @@ -262,11 +262,11 @@ void testAbortViaDtxAbort() { /* DtxInvoke bc1 */ Parameter uuidParameter = new Parameter("txid", "string", uuid.toString()); dManager.invokeSc("bc1", "sc1", "userF1", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* DtxInvoke bc2 */ dManager.invokeSc("bc2", "sc2", "userF2", List.of(uuidParameter), List.of(), - 0, "callback-url", 0, "ABC", ""); + 0, "json-rpc", true, 0L,"callback-url", 0, "ABC", ""); /* SC Error */ dManager.abortDtx(uuid); @@ -325,6 +325,9 @@ public void invokeSmartContractFunction( final List inputs, final List outputs, final double requiredConfidence, + final String callbackBinding, + final boolean sideEffects, + final Long nonce, final String callbackUrl, final long timeoutMillis, final String correlationId, From 5a5438b1709142205cf55b7853f1d486c353e93a Mon Sep 17 00:00:00 2001 From: Ghareeb Falazi Date: Fri, 18 Oct 2024 15:03:46 +0200 Subject: [PATCH 3/3] finish refactoring --- pom.xml | 11 +- .../{management => }/BlockchainManager.java | 166 +++++++++----- .../de/adaptation/AdapterManager.java | 4 +- .../adaptation/BlockchainAdapterFactory.java | 6 +- .../de/jsonrpc/model/ScipResponse.java | 46 ---- .../management/callback/CallbackManager.java | 124 ----------- .../callback/ScipMessageTranslator.java | 50 ----- .../PluginManager.java} | 10 +- .../callback/CamundaMessageTranslator.java | 5 +- .../restapi/callback/RestCallbackManager.java | 67 ++++++ .../ConnectionProfilesController.java | 4 +- .../DistributedTransactionsController.java | 6 +- .../EnsureTransactionStateController.java | 9 +- ...InvokeSmartContractFunctionController.java | 11 +- .../OrphanedTransactionController.java | 8 +- .../PluginManagerController.java | 9 +- .../ReceiveTransactionController.java | 9 +- .../ReceiveTransactionsController.java | 8 +- .../RootController.java | 10 +- .../SubmitTransactionController.java | 8 +- .../SubscriptionController.java | 12 +- .../InvokeSmartContractFunctionRequest.java | 11 + .../BalService.java => scip/ScipService.java} | 12 +- .../de/scip/bindings/AbstractBinding.java | 27 +++ .../de/scip/bindings/BindingsManager.java | 61 ++++++ .../scip/bindings/camunda/CamundaBinding.java | 139 ++++++++++++ .../camunda/model/DoubleVariable.java | 24 +++ .../bindings/camunda/model/LongVariable.java | 24 +++ .../scip/bindings/camunda/model/Message.java | 31 +++ .../camunda/model/StringVariable.java | 27 +++ .../bindings/camunda/model/Variable.java} | 19 +- .../scip/bindings/jsonrpc/JsonRpcBinding.java | 113 ++++++++++ .../de/scip/callback/ScipCallbackManager.java | 58 +++++ .../model/MemberSignature.java | 7 +- .../exceptions/AsynchronousBalException.java | 40 ++++ .../de/scip/model/responses/Argument.java | 38 ++++ .../scip/model/responses/InvokeResponse.java | 37 ++++ .../de/scip/model/responses/Occurrence.java | 33 +++ .../scip/model/responses/QueryResponse.java | 33 +++ .../model/responses/SubscribeResponse.java | 37 ++++ .../SubscriptionManager.java | 12 +- .../model/CompletableFutureSubscription.java | 2 +- .../model/MonitorOccurrencesSubscription.java | 2 +- .../model/ObservableSubscription.java | 2 +- .../model/Subscription.java | 2 +- .../model/SubscriptionKey.java | 2 +- .../model/SubscriptionType.java | 2 +- .../tccsci/DistributedTransactionManager.java | 10 +- .../DistributedTransactionRepository.java | 8 +- .../model/DistributedTransaction.java | 3 +- .../model/DistributedTransactionState.java | 2 +- .../model/DistributedTransactionVerdict.java | 2 +- .../de/adaptation/TestLoadAdapter.java | 7 +- .../de/scip/bindings/BindingManagerTest.java | 39 ++++ .../bindings/camunda/CamundaBindingTest.java | 202 ++++++++++++++++++ .../bindings/jsonrpc/JsonRpcBindingTest.java | 169 +++++++++++++++ .../SubscriptionManagerTest.java | 7 +- .../DistributedTransactionManagerTest.java | 12 +- 58 files changed, 1443 insertions(+), 396 deletions(-) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => }/BlockchainManager.java (82%) delete mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/ScipResponse.java delete mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/CallbackManager.java delete mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/ScipMessageTranslator.java rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management/BlockchainPluginManager.java => plugin/PluginManager.java} (94%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => restapi}/callback/CamundaMessageTranslator.java (94%) create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/callback/RestCallbackManager.java rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/ConnectionProfilesController.java (93%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/DistributedTransactionsController.java (87%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/EnsureTransactionStateController.java (83%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/InvokeSmartContractFunctionController.java (84%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/OrphanedTransactionController.java (86%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/PluginManagerController.java (93%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/ReceiveTransactionController.java (84%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/ReceiveTransactionsController.java (86%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/RootController.java (80%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/SubmitTransactionController.java (87%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/{Controllers => controllers}/SubscriptionController.java (87%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{jsonrpc/BalService.java => scip/ScipService.java} (93%) create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/AbstractBinding.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingsManager.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBinding.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/DoubleVariable.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/LongVariable.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/Message.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/StringVariable.java rename src/main/java/blockchains/iaas/uni/stuttgart/de/{jsonrpc/model/Occurrence.java => scip/bindings/camunda/model/Variable.java} (58%) create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBinding.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/callback/ScipCallbackManager.java rename src/main/java/blockchains/iaas/uni/stuttgart/de/{jsonrpc => scip}/model/MemberSignature.java (52%) create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/exceptions/AsynchronousBalException.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Argument.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/InvokeResponse.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Occurrence.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/QueryResponse.java create mode 100644 src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/SubscribeResponse.java rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/SubscriptionManager.java (92%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/model/CompletableFutureSubscription.java (94%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/model/MonitorOccurrencesSubscription.java (94%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/model/ObservableSubscription.java (94%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/model/Subscription.java (92%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/model/SubscriptionKey.java (96%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/model/SubscriptionType.java (92%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => }/tccsci/DistributedTransactionManager.java (96%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => }/tccsci/DistributedTransactionRepository.java (88%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => tccsci}/model/DistributedTransaction.java (89%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => tccsci}/model/DistributedTransactionState.java (65%) rename src/main/java/blockchains/iaas/uni/stuttgart/de/{management => tccsci}/model/DistributedTransactionVerdict.java (58%) create mode 100644 src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingManagerTest.java create mode 100644 src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBindingTest.java create mode 100644 src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBindingTest.java rename src/test/java/blockchains/iaas/uni/stuttgart/de/{management => subscription}/SubscriptionManagerTest.java (83%) rename src/test/java/blockchains/iaas/uni/stuttgart/de/{management => }/tccsci/DistributedTransactionManagerTest.java (97%) diff --git a/pom.xml b/pom.xml index b7f9656..934fd97 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 3.3.2 + 3.3.4 blockchains.iaas.uni.stuttgart.de @@ -75,6 +75,9 @@ + + + org.springframework.boot spring-boot-starter-log4j2 @@ -97,6 +100,12 @@ spring-boot-starter-test test + + com.squareup.okhttp3 + mockwebserver + 4.12.0 + test + diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/BlockchainManager.java similarity index 82% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainManager.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/BlockchainManager.java index c022150..a6ea9be 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainManager.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/BlockchainManager.java @@ -9,35 +9,36 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; +package blockchains.iaas.uni.stuttgart.de; import blockchains.iaas.uni.stuttgart.de.adaptation.AdapterManager; import blockchains.iaas.uni.stuttgart.de.api.exceptions.*; -import blockchains.iaas.uni.stuttgart.de.api.model.*; -import blockchains.iaas.uni.stuttgart.de.management.callback.CallbackManager; -import blockchains.iaas.uni.stuttgart.de.management.callback.CamundaMessageTranslator; -import blockchains.iaas.uni.stuttgart.de.management.callback.ScipMessageTranslator; import blockchains.iaas.uni.stuttgart.de.api.interfaces.BlockchainAdapter; +import blockchains.iaas.uni.stuttgart.de.api.model.*; import blockchains.iaas.uni.stuttgart.de.api.utils.MathUtils; -import blockchains.iaas.uni.stuttgart.de.management.model.CompletableFutureSubscription; -import blockchains.iaas.uni.stuttgart.de.management.model.MonitorOccurrencesSubscription; -import blockchains.iaas.uni.stuttgart.de.management.model.ObservableSubscription; -import blockchains.iaas.uni.stuttgart.de.management.model.Subscription; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.restapi.callback.CamundaMessageTranslator; +import blockchains.iaas.uni.stuttgart.de.restapi.callback.RestCallbackManager; +import blockchains.iaas.uni.stuttgart.de.scip.callback.ScipCallbackManager; +import blockchains.iaas.uni.stuttgart.de.scip.model.exceptions.AsynchronousBalException; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.Argument; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.InvokeResponse; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.SubscribeResponse; +import blockchains.iaas.uni.stuttgart.de.subscription.SubscriptionManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.*; import com.google.common.base.Strings; import io.reactivex.Observable; import io.reactivex.disposables.Disposable; import lombok.extern.log4j.Log4j2; +import org.jetbrains.annotations.NotNull; import org.springframework.stereotype.Component; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + @Log4j2 @Component public class BlockchainManager { @@ -46,6 +47,21 @@ public class BlockchainManager { public BlockchainManager(AdapterManager adapterManager) { this.adapterManager = adapterManager; } + + private static @NotNull AsynchronousBalException generateAsynchronousBalException(String correlationId, Transaction tx) { + AsynchronousBalException exception; + if (tx.getState() == TransactionState.NOT_FOUND) { + TransactionNotFoundException txNotFoundException = + new TransactionNotFoundException("The transaction associated with a function invocation is invalidated after it was mined."); + exception = new AsynchronousBalException(txNotFoundException, correlationId); + } else { + InvokeSmartContractFunctionFailure invocationException = + new InvokeSmartContractFunctionFailure("The smart contract function invocation reported an error."); + exception = new AsynchronousBalException(invocationException, correlationId); + } + return exception; + } + /** * Submits a transaction to the blockchain, and sends a callback message informing a remote endpoint of the result. * The status of the result could be: @@ -71,10 +87,10 @@ public void submitNewTransaction(final String correlationId, final String to, fi thenAccept(tx -> { if (tx != null) { if (tx.getState() == TransactionState.CONFIRMED) { - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, tx, false)); } else {// it is NOT_FOUND - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, tx, true)); } } else @@ -83,10 +99,10 @@ public void submitNewTransaction(final String correlationId, final String to, fi exceptionally((e) -> { log.error("Failed to submit a transaction.", e); if (e.getCause() instanceof BlockchainNodeUnreachableException) - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, true, ((BlockchainNodeUnreachableException) e).getCode())); else if (e.getCause() instanceof InvalidTransactionException) - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.INVALID, true, ((InvalidTransactionException) e).getCode())); // ManualUnsubscriptionException is also captured here @@ -102,11 +118,11 @@ else if (e.getCause() instanceof InvalidTransactionException) SubscriptionManager.getInstance().createSubscription(correlationId, blockchainId, subscription); } catch (InvalidTransactionException e) { // This (should only) happen when something is wrong with the transaction data - CallbackManager.getInstance().sendCallbackAsync(epUrl, + RestCallbackManager.getInstance().sendCallbackAsync(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.INVALID, true, e.getCode())); } catch (BlockchainIdNotFoundException | NotSupportedException e) { // This (should only) happen when the blockchainId is not found - CallbackManager.getInstance().sendCallbackAsync(epUrl, + RestCallbackManager.getInstance().sendCallbackAsync(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, true, e.getCode())); } } @@ -138,7 +154,7 @@ public void receiveTransactions(final String correlationId, final String from, f .doOnError(throwable -> log.error("Failed to receive transaction.", throwable)) .subscribe(transaction -> { if (transaction != null) { - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, transaction, false)); } else { log.error("received transaction is null!"); @@ -186,7 +202,7 @@ public void receiveTransaction(final String correlationId, final String from, fi log.error("Failed to receive transaction.", throwable); if (throwable instanceof BlockchainNodeUnreachableException || throwable.getCause() instanceof BlockchainNodeUnreachableException) { - CallbackManager.getInstance().sendCallbackAsync(epUrl, + RestCallbackManager.getInstance().sendCallbackAsync(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, true, (new BlockchainNodeUnreachableException()).getCode())); } else { log.error("Unhandled exception.", throwable); @@ -195,7 +211,7 @@ public void receiveTransaction(final String correlationId, final String from, fi .take(1) .subscribe(transaction -> { if (transaction != null) { - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, transaction, false)); log.info("Usubscribing from receiveTransactions"); } else { @@ -209,7 +225,7 @@ public void receiveTransaction(final String correlationId, final String from, fi } catch (BlockchainIdNotFoundException | NotSupportedException e) { // This (should only) happen when the blockchainId is not found Or // if trying to receive a monetary transaction via, e.g., Fabric - CallbackManager.getInstance().sendCallbackAsync(epUrl, + RestCallbackManager.getInstance().sendCallbackAsync(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, true, e.getCode())); } } @@ -237,7 +253,7 @@ public void detectOrphanedTransaction(final String correlationId, final String t future. thenAccept(txState -> { if (txState != null) { - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, txState, false, 0)); } else // we should never reach here! log.error("Resulting transactionState is null"); @@ -246,7 +262,7 @@ public void detectOrphanedTransaction(final String correlationId, final String t log.info("Failed to monitor a transaction.", e); // This happens when a communication error, or an error with the tx exist. if (e.getCause() instanceof BlockchainNodeUnreachableException) - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, false, 0)); // ManualUnsubscriptionException is also captured here @@ -262,11 +278,15 @@ public void detectOrphanedTransaction(final String correlationId, final String t } catch (BlockchainIdNotFoundException | NotSupportedException e) { // This (should only) happen when the blockchainId is not found Or // if trying to receive a monetary transaction via, e.g., Fabric - CallbackManager.getInstance().sendCallbackAsync(epUrl, + RestCallbackManager.getInstance().sendCallbackAsync(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, false, 0)); } } + // todo add support for timeouts + // todo add support for signature checking + // todo add support for nonce + /** * Detects that a specific transasction got enough block-confirmations. It sends also sends a callback if the transaction * is not found (probably due to invalidation) @@ -293,10 +313,10 @@ public void ensureTransactionState(final String correlationId, final String tran thenAccept(txState -> { if (txState != null) { if (txState == TransactionState.CONFIRMED) - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, txState, false, 0)); else - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, txState, true, 0)); } else // we should never reach here! log.error("resulting transactionState is null"); @@ -305,7 +325,7 @@ public void ensureTransactionState(final String correlationId, final String tran log.info("Failed to monitor a transaction.", e); // This happens when a communication error, or an error with the tx exist. if (e.getCause() instanceof BlockchainNodeUnreachableException) - CallbackManager.getInstance().sendCallback(epUrl, + RestCallbackManager.getInstance().sendCallback(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, true, ((BlockchainNodeUnreachableException) e.getCause()).getCode())); // ManualUnsubscriptionException is also captured here @@ -321,15 +341,11 @@ public void ensureTransactionState(final String correlationId, final String tran } catch (BlockchainIdNotFoundException | NotSupportedException e) { // This (should only) happen when the blockchainId is not found Or // if trying to monitor a monetary transaction via, e.g., Fabric - CallbackManager.getInstance().sendCallbackAsync(epUrl, + RestCallbackManager.getInstance().sendCallbackAsync(epUrl, CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, true, e.getCode())); } } - // todo add support for timeouts - // todo add support for signature checking - // todo add support for nonce - /** * Invokes a smart contract function, and sends a callback message informing a remote endpoint of the result. * The invocation might require the submission of a transaction if the invoked function is not read-only. @@ -377,21 +393,29 @@ public void invokeSmartContractFunction( if (tx != null) { if (callbackUrl != null) { if (tx.getState() == TransactionState.CONFIRMED || tx.getState() == TransactionState.RETURN_VALUE) { - CallbackManager.getInstance().sendCallback(callbackUrl, - ScipMessageTranslator.getInvocationResponseMessage( - correlationId, - tx.getReturnValues())); + if (callbackBinding.isEmpty()) { + RestCallbackManager.getInstance().sendCallback(callbackUrl, + CamundaMessageTranslator.convert(correlationId, tx, false)); + } else { + InvokeResponse response = InvokeResponse + .builder() + .correlationId(correlationId) + .outputArguments(tx.getReturnValues().stream() + .map(p -> Argument.builder() + .name(p.getName()).value(p.getValue()) + .build() + ).toList()) + .build(); + ScipCallbackManager.getInstance().sendInvocationResponse(callbackUrl, callbackBinding, response); + } } else {// it is NOT_FOUND (it was dropped from the system due to invalidation) or ERRORED - if (tx.getState() == TransactionState.NOT_FOUND) { - CallbackManager.getInstance().sendCallback(callbackUrl, - ScipMessageTranslator.getAsynchronousErrorResponseMessage( - correlationId, - new TransactionNotFoundException("The transaction associated with a function invocation is invalidated after it was mined."))); + AsynchronousBalException exception = generateAsynchronousBalException(correlationId, tx); + + if (callbackBinding.isEmpty()) { + RestCallbackManager.getInstance().sendCallback(callbackUrl, + CamundaMessageTranslator.convert(correlationId, tx.getState(), true, exception.getCode())); } else { - CallbackManager.getInstance().sendCallback(callbackUrl, - ScipMessageTranslator.getAsynchronousErrorResponseMessage( - correlationId, - new InvokeSmartContractFunctionFailure("The smart contract function invocation reported an error."))); + ScipCallbackManager.getInstance().sendAsyncErrorResponse(callbackUrl, callbackBinding, exception); } } } else { @@ -404,9 +428,16 @@ public void invokeSmartContractFunction( exceptionally((e) -> { log.info("Failed to invoke smart contract function.", e); // happens if the node is unreachable, or something goes wrong while trying to invoke the sc function. - if (e.getCause() instanceof BalException) - CallbackManager.getInstance().sendCallback(callbackUrl, - ScipMessageTranslator.getAsynchronousErrorResponseMessage(correlationId, (BalException) e.getCause())); + if (e.getCause() instanceof BalException) { + AsynchronousBalException exception = + new AsynchronousBalException((BalException) e.getCause(), correlationId); + if (callbackBinding.isEmpty()) { + RestCallbackManager.getInstance().sendCallback(callbackUrl, + CamundaMessageTranslator.convert(correlationId, TransactionState.UNKNOWN, true, exception.getCode())); + } else { + ScipCallbackManager.getInstance().sendAsyncErrorResponse(callbackUrl, callbackBinding, exception); + } + } if (e instanceof ManualUnsubscriptionException || e.getCause() instanceof ManualUnsubscriptionException) { log.info("Manual unsubscription of SC invocation!"); @@ -472,8 +503,28 @@ public void subscribeToEvent( .doOnError(throwable -> log.error("Failed to detect an occurrence.", throwable)) .subscribe(occurrence -> { if (occurrence != null) { - CallbackManager.getInstance().sendCallback(callbackUrl, - ScipMessageTranslator.getSubscriptionResponseMessage(correlationIdentifier, occurrence.getParameters(), occurrence.getIsoTimestamp())); + if (callbackBinding.isEmpty()) { + LinearChainTransaction dummy = new LinearChainTransaction(); + dummy.setReturnValues(occurrence.getParameters()); + dummy.setState(TransactionState.RETURN_VALUE); + RestCallbackManager.getInstance().sendCallback(callbackUrl, + CamundaMessageTranslator.convert(correlationIdentifier, dummy, false)); + } else { + SubscribeResponse response = SubscribeResponse + .builder() + .correlationId(correlationIdentifier) + .timestamp(occurrence.getIsoTimestamp()) + .arguments(occurrence + .getParameters() + .stream() + .map(p -> Argument.builder() + .name(p.getName()) + .value(p.getValue()) + .build() + ).toList()) + .build(); + ScipCallbackManager.getInstance().sendSubscriptionResponse(callbackUrl, callbackBinding, response); + } } else { log.error("detected occurrence is null!"); } @@ -505,7 +556,6 @@ public Observable subscribeToEvent(String blockchainIdentifier, .subscribeToEvent(smartContractPath, eventIdentifier, outputParameters, minimumConfidenceAsProbability, filter); } - public void cancelEventSubscriptions(String blockchainId, String smartContractId, String correlationId, String eventIdentifier, List parameters) { // Validate scip parameters! if (Strings.isNullOrEmpty(blockchainId) || Strings.isNullOrEmpty(smartContractId)) { diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/AdapterManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/AdapterManager.java index b884338..dbc136f 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/AdapterManager.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/AdapterManager.java @@ -18,7 +18,7 @@ import blockchains.iaas.uni.stuttgart.de.connectionprofiles.ConnectionProfilesManager; import blockchains.iaas.uni.stuttgart.de.api.exceptions.BlockchainIdNotFoundException; import blockchains.iaas.uni.stuttgart.de.api.exceptions.BlockchainNodeUnreachableException; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainPluginManager; +import blockchains.iaas.uni.stuttgart.de.plugin.PluginManager; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -30,7 +30,7 @@ public class AdapterManager { private final Map> map = Collections.synchronizedMap(new HashMap<>()); private final BlockchainAdapterFactory factory; - private AdapterManager(BlockchainPluginManager pluginManager) { + private AdapterManager(PluginManager pluginManager) { this.factory = new BlockchainAdapterFactory(pluginManager); } diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/BlockchainAdapterFactory.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/BlockchainAdapterFactory.java index 64235e8..24aa35a 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/BlockchainAdapterFactory.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/adaptation/BlockchainAdapterFactory.java @@ -15,16 +15,16 @@ import blockchains.iaas.uni.stuttgart.de.api.IAdapterExtension; import blockchains.iaas.uni.stuttgart.de.api.connectionprofiles.AbstractConnectionProfile; import blockchains.iaas.uni.stuttgart.de.api.interfaces.BlockchainAdapter; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainPluginManager; +import blockchains.iaas.uni.stuttgart.de.plugin.PluginManager; import lombok.extern.log4j.Log4j2; import java.util.List; @Log4j2 public class BlockchainAdapterFactory { - private final BlockchainPluginManager manager; + private final PluginManager manager; - public BlockchainAdapterFactory(BlockchainPluginManager manager) { + public BlockchainAdapterFactory(PluginManager manager) { this.manager = manager; } diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/ScipResponse.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/ScipResponse.java deleted file mode 100644 index 4fa8cd7..0000000 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/ScipResponse.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019 Institute for the Architecture of Application System - University of Stuttgart - * Author: Ghareeb Falazi - * - * This program and the accompanying materials are made available under the - * terms the Apache Software License 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: Apache-2.0 - *******************************************************************************/ - -package blockchains.iaas.uni.stuttgart.de.jsonrpc.model; - -import java.util.List; -import java.util.stream.Collectors; - -import blockchains.iaas.uni.stuttgart.de.api.exceptions.BalException; -import blockchains.iaas.uni.stuttgart.de.restapi.model.response.CallbackMessage; -import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -@Builder -@Setter -@Getter -public class ScipResponse extends CallbackMessage { - private String correlationIdentifier; - private List parameters; - private String isoTimestamp; - private List occurrences; - private BalException exception; - - @Override - public String toString() { - return "ScipResponseMessage{" + - "correlationIdentifier='" + correlationIdentifier + '\'' + - ", parameters=[" + (parameters == null? "]": - parameters.stream().map(p-> "{ name: " + p.getName() + ", value: " + p.getValue() + ", type: " + p.getType() + " }").collect(Collectors.joining(",")) + "]") + - ", isoTimestamp='" + isoTimestamp + '\'' + - ", occurrences=" + occurrences + - ", exception=" + exception + - '}'; - } - -} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/CallbackManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/CallbackManager.java deleted file mode 100644 index 810ee7f..0000000 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/CallbackManager.java +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019-2024 Institute for the Architecture of Application System - University of Stuttgart - * Author: Ghareeb Falazi - * - * This program and the accompanying materials are made available under the - * terms the Apache Software License 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: Apache-2.0 - *******************************************************************************/ - -package blockchains.iaas.uni.stuttgart.de.management.callback; - -import blockchains.iaas.uni.stuttgart.de.api.exceptions.TimeoutException; -import blockchains.iaas.uni.stuttgart.de.jsonrpc.model.ScipResponse; -import blockchains.iaas.uni.stuttgart.de.restapi.model.response.CallbackMessage; -import blockchains.iaas.uni.stuttgart.de.restapi.model.response.CamundaMessage; -import com.github.arteam.simplejsonrpc.client.JsonRpcClient; -import com.github.arteam.simplejsonrpc.client.Transport; -import com.github.arteam.simplejsonrpc.client.builder.NotificationRequestBuilder; -import lombok.extern.log4j.Log4j2; -import org.jetbrains.annotations.NotNull; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestClient; - -import java.io.IOException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -@Log4j2 -public class CallbackManager { - private static CallbackManager instance = null; - private ExecutorService executorService = Executors.newFixedThreadPool(2); - - private CallbackManager() { - - } - - public static CallbackManager getInstance() { - if (instance == null) - instance = new CallbackManager(); - - return instance; - } - - public void sendCallback(final String endpointUrl, final CallbackMessage responseBody) { - log.info("Sending callback message {} to ({})", responseBody, endpointUrl); - if (responseBody instanceof CamundaMessage) { - this.sendRestCallback(endpointUrl, responseBody); - } else if (responseBody instanceof ScipResponse) { - this.sendJsonRpcCallback(endpointUrl, (ScipResponse) responseBody); - } else { - log.error("The sepcified response message has an unknown callback protocol."); - } - } - - private void sendRestCallback(final String endpointUrl, final CallbackMessage responseBody) { - ResponseEntity response = RestClient.create() - .post() - .uri(endpointUrl) - .contentType(MediaType.APPLICATION_JSON) - .body(responseBody) - .retrieve() - .toEntity(String.class); - - log.info("Callback client responded with {} (code: {})", - () -> response.getBody(), () -> response.getStatusCode()); - } - - private void sendJsonRpcCallback(final String endpointUrl, final ScipResponse response) { - final String METHOD_NAME = "ReceiveResponse"; - JsonRpcClient client = new JsonRpcClient(new Transport() { - @NotNull - @Override - public String pass(@NotNull String request) throws IOException { - ResponseEntity response = RestClient.create() - .post() - .uri(endpointUrl) - .contentType(MediaType.APPLICATION_JSON) - .body(request) - .retrieve() - .toEntity(String.class); - - log.info("Callback client responded with {} (code: {})", - () -> response.getBody(), () -> response.getStatusCode()); - - return response.getBody() != null ? response.getBody() : ""; - } - }); - - NotificationRequestBuilder builder = client.createNotification() - .method(METHOD_NAME) - .param("correlationIdentifier", response.getCorrelationIdentifier()); - - if (response.getException() == null) { - if (response.getParameters() != null) { - builder = builder.param("parameters", response.getParameters()); - } - - if (response.getIsoTimestamp() != null) { - builder = builder.param("timestamp", response.getIsoTimestamp()); - } - - if (response.getOccurrences() != null) { - builder = builder.param("occurrences", response.getOccurrences()); - } - } else { - builder = builder.param("errorCode", response.getException().getCode()); - builder = builder.param("errorMessage", response.getException().getMessage()); - - if (response.getException() instanceof TimeoutException) { - builder = builder.param("transactionHash", ((TimeoutException) response.getException()).getTransactionHash()); - builder = builder.param("reachedDoC", ((TimeoutException) response.getException()).getDoc()); - } - } - - builder.execute(); - } - - public void sendCallbackAsync(final String endpointUrl, final CallbackMessage responseBody) { - this.executorService.execute(() -> sendCallback(endpointUrl, responseBody)); - } -} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/ScipMessageTranslator.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/ScipMessageTranslator.java deleted file mode 100644 index adf014f..0000000 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/ScipMessageTranslator.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019 Institute for the Architecture of Application System - University of Stuttgart - * Author: Ghareeb Falazi - * - * This program and the accompanying materials are made available under the - * terms the Apache Software License 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: Apache-2.0 - *******************************************************************************/ - -package blockchains.iaas.uni.stuttgart.de.management.callback; - -import java.util.List; - -import blockchains.iaas.uni.stuttgart.de.api.exceptions.BalException; -import blockchains.iaas.uni.stuttgart.de.jsonrpc.model.Occurrence; -import blockchains.iaas.uni.stuttgart.de.jsonrpc.model.ScipResponse; -import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; - -public class ScipMessageTranslator { - public static ScipResponse getInvocationResponseMessage(String correlationId, List outputs) { - return ScipResponse.builder() - .correlationIdentifier(correlationId) - .parameters(outputs) - .build(); - } - - public static ScipResponse getSubscriptionResponseMessage(String correlationId, List parameters, String isoTimestamp) { - return ScipResponse.builder() - .correlationIdentifier(correlationId) - .parameters(parameters) - .isoTimestamp(isoTimestamp) - .build(); - } - - public static ScipResponse getQueryResultResponseMessage(String correlationId, List occurrences) { - return ScipResponse.builder() - .correlationIdentifier(correlationId) - .occurrences(occurrences) - .build(); - } - - public static ScipResponse getAsynchronousErrorResponseMessage(String correlationId, BalException exception) { - return ScipResponse.builder() - .correlationIdentifier(correlationId) - .exception(exception) - .build(); - } -} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainPluginManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/plugin/PluginManager.java similarity index 94% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainPluginManager.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/plugin/PluginManager.java index 25b6da0..b5a4e05 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/BlockchainPluginManager.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/plugin/PluginManager.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management; +package blockchains.iaas.uni.stuttgart.de.plugin; import blockchains.iaas.uni.stuttgart.de.Constants; import blockchains.iaas.uni.stuttgart.de.api.IAdapterExtension; @@ -28,12 +28,12 @@ @Log4j2 @Component -public class BlockchainPluginManager { - private PluginManager pluginManager = null; +public class PluginManager { + private org.pf4j.PluginManager pluginManager = null; private final String pluginDirStr; - private static final String DEFAULT_PLUGIN_DIR = Paths.get(System.getProperty("user.home"), ".bal").toString(); + private static final String DEFAULT_PLUGIN_DIR = Paths.get(System.getProperty("user.home"), ".bal", "plugins").toString(); - private BlockchainPluginManager(@Value("${" + Constants.PF4J_PLUGIN_DIR_PROPERTY + ":}") + private PluginManager(@Value("${" + Constants.PF4J_PLUGIN_DIR_PROPERTY + ":}") String pluginDir, @Value("${" + PF4J_AUTOLOAD_PROPERTY + ":false}") String strConf) { log.info("Initializing Blockchain Plugin Manager: pluginDir={}, autoLoadPlugins={}.", pluginDir, strConf); diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/CamundaMessageTranslator.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/callback/CamundaMessageTranslator.java similarity index 94% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/CamundaMessageTranslator.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/callback/CamundaMessageTranslator.java index 9bf0c0e..785f200 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/callback/CamundaMessageTranslator.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/callback/CamundaMessageTranslator.java @@ -9,7 +9,7 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.callback; +package blockchains.iaas.uni.stuttgart.de.restapi.callback; import java.util.Map; @@ -32,8 +32,7 @@ public static CallbackMessage convert(String subscriptionId, Transaction transac variables.put("status", new CamundaVariable(state.toString(), "String")); // todo handle communication between Camunda and Fabric - if (transaction instanceof LinearChainTransaction) { - LinearChainTransaction tx = (LinearChainTransaction) transaction; + if (transaction instanceof LinearChainTransaction tx) { if (state != TransactionState.RETURN_VALUE) { variables.put("from", new CamundaVariable(tx.getFrom(), "String")); diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/callback/RestCallbackManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/callback/RestCallbackManager.java new file mode 100644 index 0000000..1c8cd0f --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/callback/RestCallbackManager.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2019-2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.restapi.callback; + + +import blockchains.iaas.uni.stuttgart.de.restapi.model.response.CallbackMessage; +import blockchains.iaas.uni.stuttgart.de.restapi.model.response.CamundaMessage; + +import lombok.extern.log4j.Log4j2; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestClient; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Log4j2 +public class RestCallbackManager { + private static RestCallbackManager instance = null; + private final ExecutorService executorService = Executors.newFixedThreadPool(2); + + private RestCallbackManager() { + + } + + public static RestCallbackManager getInstance() { + if (instance == null) + instance = new RestCallbackManager(); + + return instance; + } + + public void sendCallback(final String endpointUrl, final CallbackMessage responseBody) { + log.info("Sending REST callback message {} to ({})", responseBody, endpointUrl); + if (responseBody instanceof CamundaMessage) { + this.sendRestCallback(endpointUrl, responseBody); + } else { + log.error("The specified response message has an unknown callback protocol."); + } + } + + private void sendRestCallback(final String endpointUrl, final CallbackMessage responseBody) { + ResponseEntity response = RestClient.create() + .post() + .uri(endpointUrl) + .contentType(MediaType.APPLICATION_JSON) + .body(responseBody) + .retrieve() + .toEntity(String.class); + + log.info("Callback client responded with {} (code: {})", + () -> response.getBody(), () -> response.getStatusCode()); + } + + public void sendCallbackAsync(final String endpointUrl, final CallbackMessage responseBody) { + this.executorService.execute(() -> sendCallback(endpointUrl, responseBody)); + } +} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ConnectionProfilesController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ConnectionProfilesController.java similarity index 93% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ConnectionProfilesController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ConnectionProfilesController.java index 0aa40bc..a618b8d 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ConnectionProfilesController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ConnectionProfilesController.java @@ -9,13 +9,13 @@ * * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; import java.util.Map; import blockchains.iaas.uni.stuttgart.de.api.connectionprofiles.AbstractConnectionProfile; import blockchains.iaas.uni.stuttgart.de.connectionprofiles.ConnectionProfilesManager; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.extern.log4j.Log4j2; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/DistributedTransactionsController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/DistributedTransactionsController.java similarity index 87% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/DistributedTransactionsController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/DistributedTransactionsController.java index 295c52c..b451d3e 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/DistributedTransactionsController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/DistributedTransactionsController.java @@ -11,10 +11,10 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransaction; -import blockchains.iaas.uni.stuttgart.de.management.tccsci.DistributedTransactionRepository; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransaction; +import blockchains.iaas.uni.stuttgart.de.tccsci.DistributedTransactionRepository; import lombok.extern.log4j.Log4j2; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/EnsureTransactionStateController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/EnsureTransactionStateController.java similarity index 83% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/EnsureTransactionStateController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/EnsureTransactionStateController.java index a1785c5..3b12966 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/EnsureTransactionStateController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/EnsureTransactionStateController.java @@ -7,13 +7,12 @@ * which is available at https://www.apache.org/licenses/LICENSE-2.0. * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import blockchains.iaas.uni.stuttgart.de.restapi.model.request.EnsureTransactionStateRequest; -import com.oracle.js.parser.ir.Block; import lombok.extern.log4j.Log4j2; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/InvokeSmartContractFunctionController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/InvokeSmartContractFunctionController.java similarity index 84% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/InvokeSmartContractFunctionController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/InvokeSmartContractFunctionController.java index a80874c..4a228d3 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/InvokeSmartContractFunctionController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/InvokeSmartContractFunctionController.java @@ -8,11 +8,11 @@ * * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import blockchains.iaas.uni.stuttgart.de.restapi.model.request.InvokeSmartContractFunctionRequest; import lombok.extern.log4j.Log4j2; import org.springframework.http.MediaType; @@ -45,6 +45,9 @@ public void invokeSCFunction(@RequestBody InvokeSmartContractFunctionRequest req request.getInputs().getArguments(), request.getOutputs().getArguments(), request.getConfidence(), + "", + request.isSideEffects(), + request.getNonce(), request.getEpUrl(), request.getTimeoutMillis(), request.getSubscriptionId(), diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/OrphanedTransactionController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/OrphanedTransactionController.java similarity index 86% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/OrphanedTransactionController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/OrphanedTransactionController.java index b1c72c1..5d99011 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/OrphanedTransactionController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/OrphanedTransactionController.java @@ -9,11 +9,11 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import blockchains.iaas.uni.stuttgart.de.restapi.model.request.DetectOrphanedTransactionRequest; import lombok.extern.log4j.Log4j2; import org.springframework.http.MediaType; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/PluginManagerController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/PluginManagerController.java similarity index 93% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/PluginManagerController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/PluginManagerController.java index a237629..69c0d05 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/PluginManagerController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/PluginManagerController.java @@ -10,16 +10,15 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainPluginManager; +import blockchains.iaas.uni.stuttgart.de.plugin.PluginManager; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.log4j.Log4j2; import org.pf4j.DependencyResolver.DependenciesNotFoundException; import org.pf4j.PluginWrapper; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -39,9 +38,9 @@ @Log4j2 public class PluginManagerController { final - BlockchainPluginManager blockchainPluginManager; + PluginManager blockchainPluginManager; - public PluginManagerController(BlockchainPluginManager blockchainPluginManager) { + public PluginManagerController(PluginManager blockchainPluginManager) { this.blockchainPluginManager = blockchainPluginManager; } diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ReceiveTransactionController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ReceiveTransactionController.java similarity index 84% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ReceiveTransactionController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ReceiveTransactionController.java index da40026..0696fdf 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ReceiveTransactionController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ReceiveTransactionController.java @@ -9,13 +9,12 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import blockchains.iaas.uni.stuttgart.de.restapi.model.request.ReceiveTransactionsRequest; -import com.oracle.js.parser.ir.Block; import lombok.extern.log4j.Log4j2; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ReceiveTransactionsController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ReceiveTransactionsController.java similarity index 86% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ReceiveTransactionsController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ReceiveTransactionsController.java index da49391..78803bd 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/ReceiveTransactionsController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/ReceiveTransactionsController.java @@ -9,11 +9,11 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import blockchains.iaas.uni.stuttgart.de.restapi.model.request.ReceiveTransactionsRequest; import lombok.extern.log4j.Log4j2; import org.springframework.http.MediaType; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/RootController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/RootController.java similarity index 80% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/RootController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/RootController.java index 72f3d28..51c9307 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/RootController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/RootController.java @@ -9,11 +9,11 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.jsonrpc.BalService; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.tccsci.DistributedTransactionManager; +import blockchains.iaas.uni.stuttgart.de.scip.ScipService; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.tccsci.DistributedTransactionManager; import com.github.arteam.simplejsonrpc.server.JsonRpcServer; import lombok.extern.log4j.Log4j2; import org.springframework.http.ResponseEntity; @@ -37,7 +37,7 @@ public ResponseEntity performJsonRpcCall(@RequestBody String jsonRequest @RequestParam(name = "blockchain") final String blockchainType, @RequestParam(name = "blockchain-id") final String blockchainId, @RequestParam(name = "address") final String smartContractAddress) { - BalService service = new BalService(blockchainType, blockchainId, smartContractAddress, manager, distributedTransactionManager); + ScipService service = new ScipService(blockchainType, blockchainId, smartContractAddress, manager, distributedTransactionManager); JsonRpcServer server = new JsonRpcServer(); String response = server.handle(jsonRequest, service); diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/SubmitTransactionController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/SubmitTransactionController.java similarity index 87% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/SubmitTransactionController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/SubmitTransactionController.java index 8fce48a..8af59d0 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/SubmitTransactionController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/SubmitTransactionController.java @@ -9,12 +9,12 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import blockchains.iaas.uni.stuttgart.de.restapi.model.request.SubmitTransactionRequest; import lombok.extern.log4j.Log4j2; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/SubscriptionController.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/SubscriptionController.java similarity index 87% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/SubscriptionController.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/SubscriptionController.java index 480d707..02d9d3c 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/Controllers/SubscriptionController.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/controllers/SubscriptionController.java @@ -9,13 +9,13 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.restapi.Controllers; +package blockchains.iaas.uni.stuttgart.de.restapi.controllers; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.SubscriptionManager; -import blockchains.iaas.uni.stuttgart.de.management.model.Subscription; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.subscription.SubscriptionManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.Subscription; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/model/request/InvokeSmartContractFunctionRequest.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/model/request/InvokeSmartContractFunctionRequest.java index af4de48..773c1b0 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/model/request/InvokeSmartContractFunctionRequest.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/restapi/model/request/InvokeSmartContractFunctionRequest.java @@ -22,6 +22,8 @@ public class InvokeSmartContractFunctionRequest { private String functionIdentifier; private double confidence; private String subscriptionId; + private boolean sideEffects; + private Long nonce; private String epUrl; private ParameterList inputs; private ParameterList outputs; @@ -78,4 +80,13 @@ public String getSignature() { return signature; } + @XmlElement(name = "SideEffects") + public boolean isSideEffects() { + return sideEffects; + } + + @XmlElement(name = "Nonce") + public Long getNonce() { + return nonce; + } } diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/ScipService.java similarity index 93% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/scip/ScipService.java index 87fd181..20b425e 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/BalService.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/ScipService.java @@ -9,15 +9,15 @@ * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.jsonrpc; +package blockchains.iaas.uni.stuttgart.de.scip; import blockchains.iaas.uni.stuttgart.de.api.exceptions.InvalidScipParameterException; import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; import blockchains.iaas.uni.stuttgart.de.api.model.QueryResult; import blockchains.iaas.uni.stuttgart.de.api.model.TimeFrame; -import blockchains.iaas.uni.stuttgart.de.jsonrpc.model.MemberSignature; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.tccsci.DistributedTransactionManager; +import blockchains.iaas.uni.stuttgart.de.scip.model.MemberSignature; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.tccsci.DistributedTransactionManager; import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcMethod; import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcOptional; import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcParam; @@ -30,7 +30,7 @@ @JsonRpcService @Log4j2 -public class BalService { +public class ScipService { private static final String DTX_ID_FIELD_NAME = "dtx_id"; private final String blockchainType; private final String blockchainId; @@ -38,7 +38,7 @@ public class BalService { private final BlockchainManager manager; private final DistributedTransactionManager dtxManager; - public BalService(String blockchainType, String blockchainId, String smartContractPath, BlockchainManager manager, DistributedTransactionManager dtxManager) { + public ScipService(String blockchainType, String blockchainId, String smartContractPath, BlockchainManager manager, DistributedTransactionManager dtxManager) { this.blockchainType = blockchainType; this.blockchainId = blockchainId; this.smartContractPath = smartContractPath; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/AbstractBinding.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/AbstractBinding.java new file mode 100644 index 0000000..290b2c7 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/AbstractBinding.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings; + +import blockchains.iaas.uni.stuttgart.de.scip.model.exceptions.AsynchronousBalException; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.InvokeResponse; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.SubscribeResponse; + + +public interface AbstractBinding { + String getBindingIdentifier(); + + void sendInvocationResponse(String endpointUrl, InvokeResponse response); + + void sendSubscriptionResponse(String endpointUrl, SubscribeResponse response); + + void sendAsyncErrorResponse(String endpointUrl, AsynchronousBalException exception); +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingsManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingsManager.java new file mode 100644 index 0000000..86bdfe7 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingsManager.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.CamundaBinding; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.jsonrpc.JsonRpcBinding; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +/** + * Manages the registered SCIP bindings + */ +public class BindingsManager { + private static BindingsManager instance = null; + private final Map bindings; + + private BindingsManager() { + final CamundaBinding camunda = new CamundaBinding(); + final JsonRpcBinding jsonrpc = new JsonRpcBinding(); + bindings = new HashMap<>(); + bindings.put(camunda.getBindingIdentifier(), camunda); + bindings.put(jsonrpc.getBindingIdentifier(), jsonrpc); + } + + public static BindingsManager getInstance() { + if (instance == null) + instance = new BindingsManager(); + + return instance; + } + + /** + * Retrieves the binding object that corresponds to the provided binding identifier + * @param bindingIdentifier the identifier of the binding to be retrieved + * @return the binding that corresponds to the provided identifier, or null if no binding is mapped to it. + */ + public AbstractBinding getBinding(String bindingIdentifier) { + return bindings.get(bindingIdentifier); + } + + /** + * Retrieves a collection of all the binding identifiers available. + * @return a collection of all the binding identifiers available. + */ + public Collection getAvailableBindingIdentifiers() { + return bindings.keySet(); + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBinding.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBinding.java new file mode 100644 index 0000000..a148588 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBinding.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2022 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +import blockchains.iaas.uni.stuttgart.de.api.exceptions.TimeoutException; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.AbstractBinding; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model.DoubleVariable; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model.LongVariable; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model.Message; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model.StringVariable; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model.Variable; +import blockchains.iaas.uni.stuttgart.de.scip.model.exceptions.AsynchronousBalException; + +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.Argument; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.InvokeResponse; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.SubscribeResponse; +import lombok.extern.log4j.Log4j2; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestClient; + +@Log4j2 +public class CamundaBinding implements AbstractBinding { + + @Override + public String getBindingIdentifier() { + return "camunda"; + } + + @Override + public void sendInvocationResponse(String endpointUrl, InvokeResponse response) { + try { + sendResultResponse(response.getOutputArguments(), + response.getTimeStamp(), + response.getCorrelationId(), + endpointUrl); + } catch (Exception e) { + log.error("Failed to send Invocation response to {}. Reason: {}", endpointUrl, e.getMessage()); + } + } + + @Override + public void sendSubscriptionResponse(String endpointUrl, SubscribeResponse response) { + try { + sendResultResponse(response.getArguments(), + response.getTimestamp(), + response.getCorrelationId(), + endpointUrl); + } catch (Exception e) { + log.error("Failed to send Subscription response to {}. Reason: {}", endpointUrl, e.getMessage()); + } + } + + @Override + public void sendAsyncErrorResponse(String endpointUrl, AsynchronousBalException exception) { + try { + final Map variables = new HashMap<>(); + + if (exception.getCause() instanceof TimeoutException) { + final Variable txHash = new StringVariable(((TimeoutException) exception.getCause()).getTransactionHash()); + final Variable doc = new DoubleVariable(((TimeoutException) exception.getCause()).getDoc()); + variables.put("reachedDoC", doc); + variables.put("transactionHash", txHash); + } + + final Variable errCode = new LongVariable(exception.getCode()); + final Variable errMessage = new StringVariable(exception.getMessage()); + final String messageName = "error_" + exception.getCorrelationIdentifier(); + variables.put("errorCode", errCode); + variables.put("errorMessage", errMessage); + Message message = Message + .builder() + .messageName(messageName) + .processVariables(variables).build(); + + sendCamundaMessage(message, endpointUrl); + } catch (Exception e) { + log.error("Failed to send asynchronous error to {}. Reason: {}", endpointUrl, e.getMessage()); + } + } + + private Map parseArguments(List parameterList) { + final Map variables = new HashMap<>(); + if (parameterList != null) { + parameterList.forEach(parameter -> { + Variable current = new StringVariable(parameter.getValue()); + variables.put(parameter.getName(), current); + }); + } + + return variables; + } + + private void sendResultResponse(List arguments, String timestamp, String correlationIdentifier, + String endpointUrl) { + final Map variables = parseArguments(arguments); + long timestampL = timestamp == null || timestamp.isEmpty() ? + 0 : Long.parseLong(timestamp); + variables.put("timestamp", new LongVariable(timestampL)); + + final Message message = Message + .builder() + .messageName("result_" + correlationIdentifier) + .processVariables(variables) + .build(); + + sendCamundaMessage(message, endpointUrl); + } + + private void sendCamundaMessage(Message message, String endpointUrl) { + + ResponseEntity response = RestClient.create() + .post() + .uri(endpointUrl) + .contentType(MediaType.APPLICATION_JSON) + .body(message) + .retrieve() + .toEntity(String.class); + + log.info("Callback client responded with {} (code: {})", + () -> response.getBody(), () -> response.getStatusCode()); + + + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/DoubleVariable.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/DoubleVariable.java new file mode 100644 index 0000000..d8b2b7e --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/DoubleVariable.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model; + +import lombok.Getter; + +@Getter +public class DoubleVariable extends Variable { + private final double value; + + public DoubleVariable(double value) { + super("Double"); + this.value = value; + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/LongVariable.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/LongVariable.java new file mode 100644 index 0000000..34b17b2 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/LongVariable.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model; + +import lombok.Getter; + +@Getter +public class LongVariable extends Variable { + private final long value; + + public LongVariable(long value) { + super("Long"); + this.value = value; + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/Message.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/Message.java new file mode 100644 index 0000000..cae3e01 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/Message.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2022-2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; +import lombok.extern.jackson.Jacksonized; + +@Data +@Builder +@Jacksonized +@JsonIgnoreProperties(ignoreUnknown = true) +public class Message { + @NonNull + private String messageName; + @NonNull + private Map processVariables; +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/StringVariable.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/StringVariable.java new file mode 100644 index 0000000..74d7b7c --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/StringVariable.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model; + +import lombok.Getter; +import lombok.NonNull; +import org.jetbrains.annotations.NotNull; + +@Getter +public class StringVariable extends Variable { + @NonNull + private final String value; + + public StringVariable(@NotNull String value) { + super("String"); + this.value = value; + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/Occurrence.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/Variable.java similarity index 58% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/Occurrence.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/Variable.java index 012e362..0451b8d 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/Occurrence.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/model/Variable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 Institute for the Architecture of Application System - University of Stuttgart + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart * Author: Ghareeb Falazi * * This program and the accompanying materials are made available under the @@ -9,15 +9,14 @@ * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.jsonrpc.model; +package blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.model; -import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; -import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; -import lombok.Data; +@Getter +@AllArgsConstructor +public abstract class Variable { + private final String type; -@Data -public class Occurrence { - private String isoTimestamp; - private List parameters; -} +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBinding.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBinding.java new file mode 100644 index 0000000..5c2773e --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBinding.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.jsonrpc; + +import blockchains.iaas.uni.stuttgart.de.api.exceptions.TimeoutException; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.AbstractBinding; +import blockchains.iaas.uni.stuttgart.de.scip.model.exceptions.AsynchronousBalException; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.InvokeResponse; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.SubscribeResponse; +import com.github.arteam.simplejsonrpc.client.JsonRpcClient; +import com.github.arteam.simplejsonrpc.client.Transport; +import com.github.arteam.simplejsonrpc.client.builder.NotificationRequestBuilder; +import lombok.extern.log4j.Log4j2; +import org.jetbrains.annotations.NotNull; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestClient; + +import java.io.IOException; + +@Log4j2 +public class JsonRpcBinding implements AbstractBinding { + + @Override + public String getBindingIdentifier() { + return "json-rpc"; + } + + @Override + public void sendInvocationResponse(String endpointUrl, InvokeResponse response) { + try { + NotificationRequestBuilder builder = createNotificationBuilder(endpointUrl); + + builder.param("correlationIdentifier", response.getCorrelationId()) + .param("parameters", response.getOutputArguments()) + .param("timestamp", response.getTimeStamp() == null ? "" : response.getTimeStamp()) + .execute(); + } catch (Exception e) { + log.error("Failed to send Invocation response to {}. Reason: {}", endpointUrl, e.getMessage()); + } + } + + @Override + public void sendSubscriptionResponse(String endpointUrl, SubscribeResponse response) { + try { + NotificationRequestBuilder builder = createNotificationBuilder(endpointUrl); + builder.param("correlationIdentifier", response.getCorrelationId()) + .param("parameters", response.getArguments()) + .param("timestamp", response.getTimestamp()) + .execute(); + } catch (Exception e) { + log.error("Failed to send Subscription response to {}. Reason: {}", endpointUrl, e.getMessage()); + } + } + + @Override + public void sendAsyncErrorResponse(String endpointUrl, AsynchronousBalException exception) { + try { + NotificationRequestBuilder builder = createNotificationBuilder(endpointUrl); + + builder = builder.param("errorCode", exception.getCode()); + builder = builder.param("errorMessage", exception.getMessage()); + builder = builder.param("correlationIdentifier", exception.getCorrelationIdentifier()); + + if (exception.getCause() instanceof TimeoutException) { + builder = builder.param("transactionHash", + ((TimeoutException) exception.getCause()).getTransactionHash()); + builder = builder.param("reachedDoC", + ((TimeoutException) exception.getCause()).getDoc()); + } + + builder.execute(); + } catch (Exception e) { + log.error("Failed to send asynchronous error to {}. Reason: {}", endpointUrl, e.getMessage()); + } + } + + private NotificationRequestBuilder createNotificationBuilder(final String endpointUrl) { + final String METHOD_NAME = "ReceiveResponse"; + JsonRpcClient client = new JsonRpcClient(new Transport() { + @NotNull + @Override + public String pass(@NotNull String request) throws IOException { + ResponseEntity response = RestClient.create() + .post() + .uri(endpointUrl) + .contentType(MediaType.APPLICATION_JSON) + .body(request) + .retrieve() + .toEntity(String.class); + + log.info("Callback client responded with {} (code: {})", + () -> response.getBody(), () -> response.getStatusCode()); + + return response.getBody() != null ? response.getBody() : ""; + } + + }); + + return client.createNotification() + .method(METHOD_NAME); + + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/callback/ScipCallbackManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/callback/ScipCallbackManager.java new file mode 100644 index 0000000..b6d7e99 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/callback/ScipCallbackManager.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.callback; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + + +import blockchains.iaas.uni.stuttgart.de.scip.bindings.AbstractBinding; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.BindingsManager; +import blockchains.iaas.uni.stuttgart.de.scip.model.exceptions.AsynchronousBalException; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.InvokeResponse; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.SubscribeResponse; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +public class ScipCallbackManager { + private static ScipCallbackManager instance = null; + private final ExecutorService executorService = Executors.newFixedThreadPool(2); + + private ScipCallbackManager() { + + } + + public static ScipCallbackManager getInstance() { + if (instance == null) + instance = new ScipCallbackManager(); + + return instance; + } + + public void sendInvocationResponse(String endpointUrl, String bindingName, InvokeResponse response) { + log.info("Sending SCIP InvokeResponse to {} using binding {}. Response body: {}", endpointUrl, bindingName, response); + AbstractBinding binding = BindingsManager.getInstance().getBinding(bindingName); + this.executorService.execute(() -> binding.sendInvocationResponse(endpointUrl, response)); + } + + public void sendSubscriptionResponse(String endpointUrl, String bindingName, SubscribeResponse response) { + log.info("Sending SCIP SubscribeResponse to {} using binding {}. Response body: {}", endpointUrl, bindingName, response); + AbstractBinding binding = BindingsManager.getInstance().getBinding(bindingName); + this.executorService.execute(() -> binding.sendSubscriptionResponse(endpointUrl, response)); + } + + public void sendAsyncErrorResponse(String endpointUrl, String bindingName, AsynchronousBalException exception) { + log.info("Sending asynchronous SCIP error to {} using binding {}. Exception body: {}", endpointUrl, bindingName, exception); + AbstractBinding binding = BindingsManager.getInstance().getBinding(bindingName); + this.executorService.execute(() -> binding.sendAsyncErrorResponse(endpointUrl, exception)); + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/MemberSignature.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/MemberSignature.java similarity index 52% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/MemberSignature.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/MemberSignature.java index f7d4d27..f3c5b60 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/jsonrpc/model/MemberSignature.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/MemberSignature.java @@ -1,13 +1,14 @@ -package blockchains.iaas.uni.stuttgart.de.jsonrpc.model; +package blockchains.iaas.uni.stuttgart.de.scip.model; import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; import lombok.Data; +import lombok.NonNull; import java.util.List; @Data public class MemberSignature { - private String name; + @NonNull private String name; private boolean isFunction; - private List parameters; + @NonNull private List parameters; } diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/exceptions/AsynchronousBalException.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/exceptions/AsynchronousBalException.java new file mode 100644 index 0000000..13d28c6 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/exceptions/AsynchronousBalException.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.model.exceptions; + + +import blockchains.iaas.uni.stuttgart.de.api.exceptions.BalException; +import lombok.Getter; + +@Getter +public final class AsynchronousBalException extends BalException { + final private String correlationIdentifier; + + public AsynchronousBalException(BalException cause, String correlationIdentifier) { + super(cause.getMessage(), cause); + this.correlationIdentifier = correlationIdentifier; + } + + @Override + public int getCode() { + return ((BalException)getCause()).getCode(); + } + + @Override + public String toString() { + return "AsynchronousBalException{" + + "message='" + getMessage() + '\'' + + "cause=" + getCause().getClass().getName() + + "correlationIdentifier='" + correlationIdentifier + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Argument.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Argument.java new file mode 100644 index 0000000..5436ef3 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Argument.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.model.responses; + +import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class Argument { + @NonNull private String name; + @NonNull private String value; + + public static Argument fromParameter(Parameter parameter) { + return Argument.builder().name(parameter.getName()).value(parameter.getValue()).build(); + } + + @Override + public String toString() { + return "Argument{" + + "name='" + name + '\'' + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/InvokeResponse.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/InvokeResponse.java new file mode 100644 index 0000000..8901d75 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/InvokeResponse.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.model.responses; + +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; + +import java.util.List; + +@Builder +@Setter +@Getter +public class InvokeResponse { + @NonNull private String correlationId; + private String timeStamp; + @NonNull private List outputArguments; + + @Override + public String toString() { + return "InvokeResponse{" + + "correlationId='" + correlationId + '\'' + + ", timeStamp='" + timeStamp + '\'' + + ", outputArguments=" + outputArguments + + '}'; + } +} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Occurrence.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Occurrence.java new file mode 100644 index 0000000..b9edc8c --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/Occurrence.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2019-2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.model.responses; + +import java.util.List; + +import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; +import lombok.*; + +@Builder +@Setter +@Getter +public class Occurrence { + @NonNull private String timestamp; + @NonNull private List arguments; + + @Override + public String toString() { + return "Occurrence{" + + "timestamp='" + timestamp + '\'' + + ", arguments=" + arguments + + '}'; + } +} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/QueryResponse.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/QueryResponse.java new file mode 100644 index 0000000..2a2355a --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/QueryResponse.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.model.responses; + +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; + +import java.util.List; + +@Builder +@Setter +@Getter +public class QueryResponse { + @NonNull private List occurrences; + + @Override + public String toString() { + return "QueryResponse{" + + "occurrences=" + occurrences + + '}'; + } +} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/SubscribeResponse.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/SubscribeResponse.java new file mode 100644 index 0000000..2544cc1 --- /dev/null +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/scip/model/responses/SubscribeResponse.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.model.responses; + +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; + +import java.util.List; + +@Builder +@Setter +@Getter +public class SubscribeResponse { + @NonNull private String correlationId; + @NonNull private String timestamp; + @NonNull private List arguments; + + @Override + public String toString() { + return "SubscribeResponse{" + + "correlationId='" + correlationId + '\'' + + ", timestamp='" + timestamp + '\'' + + ", arguments=" + arguments + + '}'; + } +} diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/SubscriptionManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/SubscriptionManager.java similarity index 92% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/SubscriptionManager.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/SubscriptionManager.java index 26ca099..598a42a 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/SubscriptionManager.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/SubscriptionManager.java @@ -10,7 +10,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management; +package blockchains.iaas.uni.stuttgart.de.subscription; import java.util.Collection; import java.util.Collections; @@ -19,11 +19,11 @@ import java.util.Map; import java.util.stream.Collectors; -import blockchains.iaas.uni.stuttgart.de.management.model.MonitorOccurrencesSubscription; -import blockchains.iaas.uni.stuttgart.de.management.model.Subscription; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionKey; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; import blockchains.iaas.uni.stuttgart.de.api.model.Parameter; +import blockchains.iaas.uni.stuttgart.de.subscription.model.MonitorOccurrencesSubscription; +import blockchains.iaas.uni.stuttgart.de.subscription.model.Subscription; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionKey; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import lombok.extern.log4j.Log4j2; // todo this class should persist subscriptions to stable storage! @@ -31,7 +31,7 @@ @Log4j2 public class SubscriptionManager { private static SubscriptionManager instance = null; - private Map subscriptions = Collections.synchronizedMap(new HashMap<>()); + private final Map subscriptions = Collections.synchronizedMap(new HashMap<>()); private SubscriptionManager() { diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/CompletableFutureSubscription.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/CompletableFutureSubscription.java similarity index 94% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/CompletableFutureSubscription.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/CompletableFutureSubscription.java index 9e98d8e..7821324 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/CompletableFutureSubscription.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/CompletableFutureSubscription.java @@ -9,7 +9,7 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.subscription.model; import java.util.concurrent.CompletableFuture; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/MonitorOccurrencesSubscription.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/MonitorOccurrencesSubscription.java similarity index 94% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/MonitorOccurrencesSubscription.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/MonitorOccurrencesSubscription.java index abc9cda..e853623 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/MonitorOccurrencesSubscription.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/MonitorOccurrencesSubscription.java @@ -9,7 +9,7 @@ * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.subscription.model; import java.util.List; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/ObservableSubscription.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/ObservableSubscription.java similarity index 94% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/ObservableSubscription.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/ObservableSubscription.java index f6e75f4..f6ac276 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/ObservableSubscription.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/ObservableSubscription.java @@ -9,7 +9,7 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.subscription.model; import io.reactivex.disposables.Disposable; import lombok.Getter; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/Subscription.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/Subscription.java similarity index 92% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/Subscription.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/Subscription.java index 9d9034c..c0eeb5f 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/Subscription.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/Subscription.java @@ -9,7 +9,7 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.subscription.model; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/SubscriptionKey.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/SubscriptionKey.java similarity index 96% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/SubscriptionKey.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/SubscriptionKey.java index f25a96f..3b0f868 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/SubscriptionKey.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/SubscriptionKey.java @@ -9,7 +9,7 @@ * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.subscription.model; import java.util.Objects; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/SubscriptionType.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/SubscriptionType.java similarity index 92% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/SubscriptionType.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/SubscriptionType.java index 159ce9a..2d513b2 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/SubscriptionType.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/subscription/model/SubscriptionType.java @@ -9,7 +9,7 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.subscription.model; public enum SubscriptionType { SUBMIT_TRANSACTION, diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManager.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionManager.java similarity index 96% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManager.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionManager.java index 9d32a0e..7725587 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManager.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionManager.java @@ -10,14 +10,14 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.tccsci; +package blockchains.iaas.uni.stuttgart.de.tccsci; import blockchains.iaas.uni.stuttgart.de.adaptation.AdapterManager; import blockchains.iaas.uni.stuttgart.de.api.model.*; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransaction; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransactionState; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransactionVerdict; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransaction; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransactionState; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransactionVerdict; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Component; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionRepository.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionRepository.java similarity index 88% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionRepository.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionRepository.java index 44876f6..98ea70a 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionRepository.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionRepository.java @@ -10,11 +10,11 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management.tccsci; +package blockchains.iaas.uni.stuttgart.de.tccsci; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransaction; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransactionState; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransactionVerdict; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransaction; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransactionState; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransactionVerdict; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransaction.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransaction.java similarity index 89% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransaction.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransaction.java index 541e5aa..d152f4a 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransaction.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransaction.java @@ -1,6 +1,5 @@ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.tccsci.model; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransactionState.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransactionState.java similarity index 65% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransactionState.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransactionState.java index 932782e..11f5550 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransactionState.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransactionState.java @@ -1,4 +1,4 @@ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.tccsci.model; public enum DistributedTransactionState { AWAITING_REQUESTS, diff --git a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransactionVerdict.java b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransactionVerdict.java similarity index 58% rename from src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransactionVerdict.java rename to src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransactionVerdict.java index 8b05b96..7e05d29 100644 --- a/src/main/java/blockchains/iaas/uni/stuttgart/de/management/model/DistributedTransactionVerdict.java +++ b/src/main/java/blockchains/iaas/uni/stuttgart/de/tccsci/model/DistributedTransactionVerdict.java @@ -1,4 +1,4 @@ -package blockchains.iaas.uni.stuttgart.de.management.model; +package blockchains.iaas.uni.stuttgart.de.tccsci.model; public enum DistributedTransactionVerdict { NOT_DECIDED, diff --git a/src/test/java/blockchains/iaas/uni/stuttgart/de/adaptation/TestLoadAdapter.java b/src/test/java/blockchains/iaas/uni/stuttgart/de/adaptation/TestLoadAdapter.java index 991ed29..3da247a 100644 --- a/src/test/java/blockchains/iaas/uni/stuttgart/de/adaptation/TestLoadAdapter.java +++ b/src/test/java/blockchains/iaas/uni/stuttgart/de/adaptation/TestLoadAdapter.java @@ -10,12 +10,11 @@ *******************************************************************************/ package blockchains.iaas.uni.stuttgart.de.adaptation; -import blockchains.iaas.uni.stuttgart.de.Constants; import blockchains.iaas.uni.stuttgart.de.api.IAdapterExtension; import blockchains.iaas.uni.stuttgart.de.api.connectionprofiles.AbstractConnectionProfile; import blockchains.iaas.uni.stuttgart.de.api.interfaces.BlockchainAdapter; import blockchains.iaas.uni.stuttgart.de.connectionprofiles.ConnectionProfilesManager; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainPluginManager; +import blockchains.iaas.uni.stuttgart.de.plugin.PluginManager; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.*; import org.pf4j.PluginState; @@ -26,13 +25,11 @@ import java.io.File; import java.io.IOException; import java.net.URISyntaxException; -import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.Objects; -import java.util.concurrent.ExecutionException; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -47,7 +44,7 @@ public class TestLoadAdapter { private final Path pluginPath = Paths.get(Objects.requireNonNull(TestLoadAdapter.class.getClassLoader().getResource("plugins/ethereum.jar")).toURI()); private final static String KEYSTORE_PATH_KEY = "ethereum.keystorePath"; @Autowired - private BlockchainPluginManager pluginManager; + private PluginManager pluginManager; @Autowired private AdapterManager adapterManager; diff --git a/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingManagerTest.java b/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingManagerTest.java new file mode 100644 index 0000000..1854c3f --- /dev/null +++ b/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/BindingManagerTest.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2022 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings; + +import java.util.Collection; + +import blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda.CamundaBinding; +import blockchains.iaas.uni.stuttgart.de.scip.bindings.jsonrpc.JsonRpcBinding; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class BindingsManagerTest { + + @Test + void getBinding() { + AbstractBinding binding = BindingsManager.getInstance().getBinding("camunda"); + assertInstanceOf(CamundaBinding.class, binding); + binding = BindingsManager.getInstance().getBinding("json-rpc"); + assertInstanceOf(JsonRpcBinding.class, binding); + } + + @Test + void getAvailableBindingIdentifiers() { + Collection bindingIds = BindingsManager.getInstance().getAvailableBindingIdentifiers(); + Assertions.assertTrue(bindingIds.contains("camunda")); + Assertions.assertTrue(bindingIds.contains("json-rpc")); + } +} \ No newline at end of file diff --git a/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBindingTest.java b/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBindingTest.java new file mode 100644 index 0000000..038f579 --- /dev/null +++ b/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/camunda/CamundaBindingTest.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2022-2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.camunda; + +import java.io.IOException; +import java.util.Collections; +import java.util.stream.Stream; + +import blockchains.iaas.uni.stuttgart.de.api.exceptions.InvokeSmartContractFunctionFailure; +import blockchains.iaas.uni.stuttgart.de.api.exceptions.TimeoutException; +import blockchains.iaas.uni.stuttgart.de.scip.model.exceptions.AsynchronousBalException; + +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.Argument; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.InvokeResponse; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.SubscribeResponse; +import lombok.extern.log4j.Log4j2; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@Log4j2 +class CamundaBindingTest { + private MockWebServer mockWebServer; + + @BeforeEach + void init() { + this.mockWebServer = new MockWebServer(); + this.mockWebServer.enqueue(new MockResponse().setResponseCode(200)); + this.mockWebServer.enqueue(new MockResponse().setResponseCode(200)); + this.mockWebServer.enqueue(new MockResponse().setResponseCode(200)); + this.mockWebServer.enqueue(new MockResponse().setResponseCode(200)); + } + + @AfterEach + void destroy() throws IOException { + this.mockWebServer.close(); + } + + @Test + void getBindingIdentifier() { + CamundaBinding biniding = new CamundaBinding(); + Assertions.assertEquals("camunda", biniding.getBindingIdentifier()); + } + + @ParameterizedTest + @MethodSource + void sendInvocationResponse(InvokeResponse response) throws InterruptedException { + String endpointUrl = this.mockWebServer.url("/").toString(); + CamundaBinding binding = new CamundaBinding(); + binding.sendInvocationResponse(endpointUrl, response); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + // todo test contents of request message + } + + @ParameterizedTest + @MethodSource + void sendSubscriptionResponse(SubscribeResponse response) throws InterruptedException { + String endpointUrl = this.mockWebServer.url("/").toString(); + CamundaBinding binding = new CamundaBinding(); + binding.sendSubscriptionResponse(endpointUrl, response); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + // todo test contents of request message + } + + @Test + void sendErrorResponse() throws InterruptedException { + AsynchronousBalException e1 = new AsynchronousBalException( + new InvokeSmartContractFunctionFailure("The first Exception occurred"), + "654321ABC"); + AsynchronousBalException e2 = new AsynchronousBalException( + new TimeoutException("The first Exception occurred", "CRAZYHASH123", 0.3), + "XXX654321ABC"); + String endpointUrl = this.mockWebServer.url("/").toString(); + CamundaBinding binding = new CamundaBinding(); + binding.sendAsyncErrorResponse(endpointUrl, e1); + binding.sendAsyncErrorResponse(endpointUrl, e2); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + + // todo test contents of request message + } + + private static Stream sendInvocationResponse() { + Argument param1 = Argument + .builder() + .name("param1") + .value("Great Test!") + .build(); + Argument param2 = Argument + .builder() + .name("param2") + .value("Super Test!") + .build(); + // here everything is provided + InvokeResponse response1 = InvokeResponse + .builder() + .correlationId("1234") + .timeStamp("654321") + .outputArguments(Stream + .of(param1, param2) + .toList()) + .build(); + // a missing corrId throws an exception + // here the timestamp is missing + InvokeResponse response3 = InvokeResponse + .builder() + .correlationId("1234") + .outputArguments(Stream + .of(param1, param2) + .toList()) + .build(); + // here the parameters are missing + assertThrows(NullPointerException.class, () -> InvokeResponse + .builder() + .correlationId("1234") + .timeStamp("654321") + .build()); + // here the parameters are provided as an empty collection + InvokeResponse response4 = InvokeResponse + .builder() + .correlationId("1234") + .timeStamp("654321") + .outputArguments(Collections.emptyList()) + .build(); + + return Stream.of( + Arguments.of(response1), + Arguments.of(response3), + Arguments.of(response4) + ); + } + + private static Stream sendSubscriptionResponse() { + Argument param1 = Argument + .builder() + .name("param1") + .value("Great Test!") + .build(); + Argument param2 = Argument + .builder() + .name("param2") + .value("Super Test!") + .build(); + // here everything is provided + SubscribeResponse response1 = SubscribeResponse + .builder() + .correlationId("1234") + .timestamp("654321") + .arguments(Stream + .of(param1, param2) + .toList()) + .build(); + // a missing corrId throws an exception + // here the timestamp is missing + assertThrows(NullPointerException.class, () -> SubscribeResponse + .builder() + .correlationId("1234") + .arguments(Stream + .of(param1, param2) + .toList()) + .build()); + // here the parameters are missing + assertThrows(NullPointerException.class, () -> SubscribeResponse + .builder() + .correlationId("1234") + .timestamp("654321") + .build()); + // here the parameters are provided as an empty collection + SubscribeResponse response2 = SubscribeResponse + .builder() + .correlationId("1234") + .timestamp("654321") + .arguments(Collections.emptyList()) + .build(); + + return Stream.of( + Arguments.of(response1), + Arguments.of(response2) + ); + } +} \ No newline at end of file diff --git a/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBindingTest.java b/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBindingTest.java new file mode 100644 index 0000000..90591ff --- /dev/null +++ b/src/test/java/blockchains/iaas/uni/stuttgart/de/scip/bindings/jsonrpc/JsonRpcBindingTest.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2024 Institute for the Architecture of Application System - University of Stuttgart + * Author: Ghareeb Falazi + * + * This program and the accompanying materials are made available under the + * terms the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package blockchains.iaas.uni.stuttgart.de.scip.bindings.jsonrpc; + +import java.io.IOException; +import java.util.Collections; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import blockchains.iaas.uni.stuttgart.de.api.exceptions.InvokeSmartContractFunctionFailure; +import blockchains.iaas.uni.stuttgart.de.api.exceptions.TimeoutException; +import blockchains.iaas.uni.stuttgart.de.scip.model.exceptions.AsynchronousBalException; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.InvokeResponse; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.Argument; +import blockchains.iaas.uni.stuttgart.de.scip.model.responses.SubscribeResponse; +import lombok.extern.log4j.Log4j2; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +@Log4j2 +class JsonRpcBindingTest { + private MockWebServer mockWebServer; + + @BeforeEach + void init() { + this.mockWebServer = new MockWebServer(); + this.mockWebServer.enqueue(new MockResponse().setResponseCode(200)); + this.mockWebServer.enqueue(new MockResponse().setResponseCode(200)); + } + + @AfterEach + void destroy() throws IOException { + this.mockWebServer.close(); + } + + @Test + void getBindingIdentifier() { + JsonRpcBinding binding = new JsonRpcBinding(); + Assertions.assertEquals("json-rpc", binding.getBindingIdentifier()); + } + + @ParameterizedTest + @MethodSource + void sendInvokeResponse(InvokeResponse response) throws InterruptedException { + String endpointUrl = this.mockWebServer.url("/").toString(); + JsonRpcBinding binding = new JsonRpcBinding(); + binding.sendInvocationResponse(endpointUrl, response); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + // todo test contents of request message + } + + @ParameterizedTest + @MethodSource + void sendSubscribeResponse(SubscribeResponse response) throws InterruptedException { + String endpointUrl = this.mockWebServer.url("/").toString(); + JsonRpcBinding binding = new JsonRpcBinding(); + binding.sendSubscriptionResponse(endpointUrl, response); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + // todo test contents of request message + } + + @Test + void sendErrorResponses() throws InterruptedException { + AsynchronousBalException e1 = new AsynchronousBalException( + new InvokeSmartContractFunctionFailure("The first Exception occurred"), + "654321ABC"); + AsynchronousBalException e2 = new AsynchronousBalException( + new TimeoutException("The first Exception occurred", "CRAZYHASH123", 0.3), + "XXX654321ABC"); + String endpointUrl = this.mockWebServer.url("/").toString(); + JsonRpcBinding binding = new JsonRpcBinding(); + binding.sendAsyncErrorResponse(endpointUrl, e1); + binding.sendAsyncErrorResponse(endpointUrl, e2); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + recordedRequest = this.mockWebServer.takeRequest(); + log.debug(recordedRequest.getBody().readUtf8()); + // todo test contents of request message + } + + private static Stream sendInvokeResponse() { + Argument param1 = Argument + .builder() + .name("param1") + .value("Great Test!") + .build(); + Argument param2 = Argument + .builder() + .name("param2") + .value("Super Test!") + .build(); + // here everything is provided + InvokeResponse response1 = InvokeResponse + .builder() + .correlationId("1234") + .timeStamp("654321") + .outputArguments(Stream + .of(param1, param2) + .collect(Collectors.toList())) + .build(); + + // here the parameters are provided as an empty collection + InvokeResponse response2 = InvokeResponse + .builder() + .correlationId("1234") + .timeStamp("654321") + .outputArguments(Collections.emptyList()) + .build(); + + return Stream.of( + Arguments.of(response1), + Arguments.of(response2) + ); + } + + private static Stream sendSubscribeResponse() { + Argument param1 = Argument + .builder() + .name("param1") + .value("Great Test!") + .build(); + Argument param2 = Argument + .builder() + .name("param2") + .value("Super Test!") + .build(); + // here everything is provided + SubscribeResponse response1 = SubscribeResponse + .builder() + .correlationId("1234") + .timestamp("654321") + .arguments(Stream + .of(param1, param2) + .collect(Collectors.toList())) + .build(); + + // here the parameters are provided as an empty collection + SubscribeResponse response3 = SubscribeResponse + .builder() + .correlationId("1234") + .timestamp("654321") + .arguments(Collections.emptyList()) + .build(); + + return Stream.of( + Arguments.of(response1), + Arguments.of(response3) + ); + } +} \ No newline at end of file diff --git a/src/test/java/blockchains/iaas/uni/stuttgart/de/management/SubscriptionManagerTest.java b/src/test/java/blockchains/iaas/uni/stuttgart/de/subscription/SubscriptionManagerTest.java similarity index 83% rename from src/test/java/blockchains/iaas/uni/stuttgart/de/management/SubscriptionManagerTest.java rename to src/test/java/blockchains/iaas/uni/stuttgart/de/subscription/SubscriptionManagerTest.java index e27aa09..2dd277b 100644 --- a/src/test/java/blockchains/iaas/uni/stuttgart/de/management/SubscriptionManagerTest.java +++ b/src/test/java/blockchains/iaas/uni/stuttgart/de/subscription/SubscriptionManagerTest.java @@ -9,12 +9,13 @@ * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ -package blockchains.iaas.uni.stuttgart.de.management; +package blockchains.iaas.uni.stuttgart.de.subscription; import java.util.Collections; -import blockchains.iaas.uni.stuttgart.de.management.model.MonitorOccurrencesSubscription; -import blockchains.iaas.uni.stuttgart.de.management.model.SubscriptionType; +import blockchains.iaas.uni.stuttgart.de.subscription.model.MonitorOccurrencesSubscription; +import blockchains.iaas.uni.stuttgart.de.subscription.SubscriptionManager; +import blockchains.iaas.uni.stuttgart.de.subscription.model.SubscriptionType; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; diff --git a/src/test/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManagerTest.java b/src/test/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionManagerTest.java similarity index 97% rename from src/test/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManagerTest.java rename to src/test/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionManagerTest.java index 57e2a69..bb38974 100644 --- a/src/test/java/blockchains/iaas/uni/stuttgart/de/management/tccsci/DistributedTransactionManagerTest.java +++ b/src/test/java/blockchains/iaas/uni/stuttgart/de/tccsci/DistributedTransactionManagerTest.java @@ -1,13 +1,15 @@ -package blockchains.iaas.uni.stuttgart.de.management.tccsci; +package blockchains.iaas.uni.stuttgart.de.tccsci; import blockchains.iaas.uni.stuttgart.de.adaptation.AdapterManager; import blockchains.iaas.uni.stuttgart.de.api.exceptions.BalException; import blockchains.iaas.uni.stuttgart.de.api.interfaces.BlockchainAdapter; import blockchains.iaas.uni.stuttgart.de.api.model.*; -import blockchains.iaas.uni.stuttgart.de.management.BlockchainManager; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransaction; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransactionState; -import blockchains.iaas.uni.stuttgart.de.management.model.DistributedTransactionVerdict; +import blockchains.iaas.uni.stuttgart.de.BlockchainManager; +import blockchains.iaas.uni.stuttgart.de.tccsci.DistributedTransactionManager; +import blockchains.iaas.uni.stuttgart.de.tccsci.DistributedTransactionRepository; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransaction; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransactionState; +import blockchains.iaas.uni.stuttgart.de.tccsci.model.DistributedTransactionVerdict; import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import lombok.extern.log4j.Log4j2;