From 1c631bf2ab1fd63edd9578bfe1937823979c3f61 Mon Sep 17 00:00:00 2001 From: alaskowski <alaskowski@ethz.ch> Date: Mon, 3 Apr 2023 15:06:48 +0200 Subject: [PATCH] SSDM-13251: Added missing transaction api methods handling to server, java-client and javascript-client --- .../ethz/sis/afsclient/client/AfsClient.java | 47 +++++++++-- .../server/impl/ApiServerAdapter.java | 26 +++++-- .../javascript/server-data-store-facade.js | 77 +++++++++++++++++++ 3 files changed, 139 insertions(+), 11 deletions(-) diff --git a/api-data-store-server-java/src/main/java/ch/ethz/sis/afsclient/client/AfsClient.java b/api-data-store-server-java/src/main/java/ch/ethz/sis/afsclient/client/AfsClient.java index f2eed8819c9..991bfd26bdc 100644 --- a/api-data-store-server-java/src/main/java/ch/ethz/sis/afsclient/client/AfsClient.java +++ b/api-data-store-server-java/src/main/java/ch/ethz/sis/afsclient/client/AfsClient.java @@ -37,6 +37,10 @@ public final class AfsClient implements PublicAPI private String sessionToken; + private String interactiveSessionKey; + + private String transactionManagerKey; + private final URI serverUri; private final JsonObjectMapper jsonObjectMapper; @@ -74,6 +78,26 @@ public final class AfsClient implements PublicAPI this.sessionToken = sessionToken; } + public String getInteractiveSessionKey() + { + return interactiveSessionKey; + } + + public void setInteractiveSessionKey(String interactiveSessionKey) + { + this.interactiveSessionKey = interactiveSessionKey; + } + + public String getTransactionManagerKey() + { + return transactionManagerKey; + } + + public void setTransactionManagerKey(String transactionManagerKey) + { + this.transactionManagerKey = transactionManagerKey; + } + private static String urlEncode(final String s) { return URLEncoder.encode(s, StandardCharsets.UTF_8); @@ -189,8 +213,9 @@ public final class AfsClient implements PublicAPI { validateSessionToken(); Map<String, Object> parameters = - Map.of("transactionId", transactionId, - "sessionToken", getSessionToken()); + Map.of("transactionId", transactionId.toString(), + "sessionToken", getSessionToken(), + "interactiveSessionKey", getInteractiveSessionKey()); request("POST", "begin", Map.of(), jsonObjectMapper.writeValue(parameters)); } @@ -198,28 +223,38 @@ public final class AfsClient implements PublicAPI public Boolean prepare() throws Exception { validateSessionToken(); - return request("POST", "prepare", Map.of()); + Map<String, Object> parameters = + Map.of("interactiveSessionKey", getInteractiveSessionKey(), + "transactionManagerKey", getTransactionManagerKey()); + return request("POST", "prepare", Map.of(), jsonObjectMapper.writeValue(parameters)); } @Override public void commit() throws Exception { validateSessionToken(); - request("POST", "commit", Map.of()); + Map<String, Object> parameters = + Map.of("interactiveSessionKey", getInteractiveSessionKey()); + request("POST", "commit", Map.of(), jsonObjectMapper.writeValue(parameters)); } @Override public void rollback() throws Exception { validateSessionToken(); - request("POST", "rollback", Map.of()); + Map<String, Object> parameters = + Map.of("interactiveSessionKey", getInteractiveSessionKey()); + request("POST", "rollback", Map.of(), jsonObjectMapper.writeValue(parameters)); } @Override public List<UUID> recover() throws Exception { validateSessionToken(); - return request("POST", "recover", Map.of()); + Map<String, Object> parameters = + Map.of("interactiveSessionKey", getInteractiveSessionKey(), + "transactionManagerKey", getTransactionManagerKey()); + return request("POST", "recover", Map.of(), jsonObjectMapper.writeValue(parameters)); } private <T> T request(@NonNull final String httpMethod, @NonNull final String apiMethod, diff --git a/server-data-store/src/main/java/ch/ethz/sis/afsserver/server/impl/ApiServerAdapter.java b/server-data-store/src/main/java/ch/ethz/sis/afsserver/server/impl/ApiServerAdapter.java index d0a5c3ad106..312d301a683 100644 --- a/server-data-store/src/main/java/ch/ethz/sis/afsserver/server/impl/ApiServerAdapter.java +++ b/server-data-store/src/main/java/ch/ethz/sis/afsserver/server/impl/ApiServerAdapter.java @@ -64,6 +64,11 @@ public class ApiServerAdapter<CONNECTION, API> implements HttpServerHandler case "copy": case "login": case "logout": + case "begin": + case "prepare": + case "commit": + case "rollback": + case "recover": return HttpMethod.POST; // all parameters from POST methods come on the body case "delete": return HttpMethod.DELETE; // all parameters from DELETE methods come on the body @@ -179,12 +184,23 @@ public class ApiServerAdapter<CONNECTION, API> implements HttpServerHandler for (Map.Entry<String, Object> entry : bodyParameterMap.entrySet()) { - if (entry.getKey().equals("sessionToken")) + switch (entry.getKey()) { - sessionToken = (String) entry.getValue(); - } else - { - methodParameters.put(entry.getKey(), entry.getValue()); + case "sessionToken": + sessionToken = (String) entry.getValue(); + break; + case "interactiveSessionKey": + interactiveSessionKey = (String) entry.getValue(); + break; + case "transactionManagerKey": + transactionManagerKey = (String) entry.getValue(); + break; + case "transactionId": + methodParameters.put(entry.getKey(), + UUID.fromString((String) entry.getValue())); + break; + default: + methodParameters.put(entry.getKey(), entry.getValue()); } } } else diff --git a/server-data-store/src/test/javascript/server-data-store-facade.js b/server-data-store/src/test/javascript/server-data-store-facade.js index e486da9d9b3..963b05d00b7 100644 --- a/server-data-store/src/test/javascript/server-data-store-facade.js +++ b/server-data-store/src/test/javascript/server-data-store-facade.js @@ -443,10 +443,87 @@ datastore.prototype.move = function(sourceOwner, source, targetOwner, target, ac } +/** + * ================================================================================== + * ch.ethz.sis.afsapi.api.TwoPhaseTransactionAPI methods + * ================================================================================== + */ +datastore.prototype.begin = function(transactionId, interactiveSessionKey, action){ + const body = { + "transactionId" : ["java.lang.String", transactionId], + "sessionToken" : ["java.lang.String", this.getSession()], + "interactiveSessionKey": ["java.lang.String", interactiveSessionKey] + }; + this._internal.sendHttpRequest( + "POST", + "application/json", + this._internal.getUrlForMethod("begin"), + body, + (response) => parseJsonResponse(response, action) + ); + +} +datastore.prototype.prepare = function(interactiveSessionKey, transactionManagerKey, action){ + const body = { + "sessionToken" : ["java.lang.String", this.getSession()], + "interactiveSessionKey": ["java.lang.String", interactiveSessionKey], + "transactionManagerKey": ["java.lang.String", transactionManagerKey] + }; + this._internal.sendHttpRequest( + "POST", + "application/json", + this._internal.getUrlForMethod("prepare"), + body, + (response) => parseJsonResponse(response, action) + ); + +} +datastore.prototype.commit = function(interactiveSessionKey, action){ + const body = { + "sessionToken" : ["java.lang.String", this.getSession()], + "interactiveSessionKey": ["java.lang.String", interactiveSessionKey], + }; + this._internal.sendHttpRequest( + "POST", + "application/json", + this._internal.getUrlForMethod("commit"), + body, + (response) => parseJsonResponse(response, action) + ); + +} +datastore.prototype.rollback = function(interactiveSessionKey, action){ + const body = { + "sessionToken" : ["java.lang.String", this.getSession()], + "interactiveSessionKey": ["java.lang.String", interactiveSessionKey] + }; + this._internal.sendHttpRequest( + "POST", + "application/json", + this._internal.getUrlForMethod("rollback"), + body, + (response) => parseJsonResponse(response, action) + ); +} +datastore.prototype.recover = function(interactiveSessionKey, transactionManagerKey, action){ + const body = { + "sessionToken" : ["java.lang.String", this.getSession()], + "interactiveSessionKey": ["java.lang.String", interactiveSessionKey], + "transactionManagerKey": ["java.lang.String", transactionManagerKey] + }; + this._internal.sendHttpRequest( + "POST", + "application/json", + this._internal.getUrlForMethod("recover"), + body, + (response) => parseJsonResponse(response, action) + ); + +} -- GitLab