From 9a45d2171a6008aedeb3edc1e481cf7eafeabf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Mon, 27 May 2024 13:47:00 +0200 Subject: [PATCH 01/10] [WEJBHTTP-140] Introducing TXN RequestType enum. --- .../httpclient/transaction/RequestType.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java new file mode 100644 index 00000000..340c679a --- /dev/null +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java @@ -0,0 +1,36 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.httpclient.transaction; + +/** + * @author Richard Opalka + */ +enum RequestType { + + UT_BEGIN, + UT_COMMIT, + UT_ROLLBACK, + XA_BEFORE_COMPLETION, + XA_COMMIT, + XA_FORGET, + XA_PREPARE, + XA_RECOVER, + XA_ROLLBACK; + +} From 4924bf0e32a81366ac72f6a0240a0923faa250c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Mon, 27 May 2024 13:52:22 +0200 Subject: [PATCH 02/10] [WEJBHTTP-140] Introducing RequestBuilder class. --- .../transaction/RequestBuilder.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java new file mode 100644 index 00000000..d265a85f --- /dev/null +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java @@ -0,0 +1,66 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.httpclient.transaction; + +import io.undertow.client.ClientRequest; +import org.wildfly.httpclient.common.Protocol; + +/** + * @author Richard Opalka + */ +final class RequestBuilder { + + private RequestType requestType; + private int version = Protocol.LATEST; + + // setters + + RequestBuilder setRequestType(final RequestType requestType) { + this.requestType = requestType; + return this; + } + + RequestBuilder setVersion(final int version) { + this.version = version; + return this; + } + + // helper methods + + ClientRequest createRequest(final String prefix) { + final ClientRequest clientRequest = new ClientRequest(); + setRequestMethod(clientRequest); + setRequestPath(clientRequest, prefix); + setRequestHeaders(clientRequest); + return clientRequest; + } + + private void setRequestMethod(final ClientRequest request) { + throw new UnsupportedOperationException(); + } + + private void setRequestPath(final ClientRequest request, final String prefix) { + throw new UnsupportedOperationException(); + } + + private void setRequestHeaders(final ClientRequest request) { + throw new UnsupportedOperationException(); + } + +} From 7aa8d442c1d2c5bd72c1d9537387cc0297f88874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Mon, 27 May 2024 14:02:05 +0200 Subject: [PATCH 03/10] [WEJBHTTP-140] Adding HTTP request method parameter to RequestType enum. --- .../transaction/RequestBuilder.java | 2 +- .../httpclient/transaction/RequestType.java | 33 ++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java index d265a85f..6c84e016 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java @@ -52,7 +52,7 @@ ClientRequest createRequest(final String prefix) { } private void setRequestMethod(final ClientRequest request) { - throw new UnsupportedOperationException(); + request.setMethod(requestType.getMethod()); } private void setRequestPath(final ClientRequest request, final String prefix) { diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java index 340c679a..7efe3428 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java @@ -18,19 +18,34 @@ package org.wildfly.httpclient.transaction; +import static io.undertow.util.Methods.GET; +import static io.undertow.util.Methods.POST; + +import io.undertow.util.HttpString; + /** * @author Richard Opalka */ enum RequestType { - UT_BEGIN, - UT_COMMIT, - UT_ROLLBACK, - XA_BEFORE_COMPLETION, - XA_COMMIT, - XA_FORGET, - XA_PREPARE, - XA_RECOVER, - XA_ROLLBACK; + UT_BEGIN(POST), + UT_COMMIT(POST), + UT_ROLLBACK(POST), + XA_BEFORE_COMPLETION(POST), + XA_COMMIT(POST), + XA_FORGET(POST), + XA_PREPARE(POST), + XA_RECOVER(GET), + XA_ROLLBACK(POST); + + private final HttpString method; + + RequestType(final HttpString method) { + this.method = method; + } + + HttpString getMethod() { + return method; + } } From 7d43f45367e0e3dc48160b15c412d699bb6b9a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Mon, 27 May 2024 14:33:47 +0200 Subject: [PATCH 04/10] [WEJBHTTP-140] Refactoring - Use RequestBuilder class instead of directly calling i.u.c.ClientRequest constructor. Let RequestBuilder class configure the HTTP request methods. Rename 'cr' method variables to 'request'. --- .../HttpRemoteTransactionHandle.java | 31 +++++----- .../HttpRemoteTransactionPeer.java | 35 ++++++----- .../HttpSubordinateTransactionHandle.java | 59 ++++++++++--------- .../transaction/RequestBuilder.java | 4 +- 4 files changed, 67 insertions(+), 62 deletions(-) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java index 85de126a..f24acd1e 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java @@ -20,7 +20,6 @@ import io.undertow.client.ClientRequest; import io.undertow.util.Headers; -import io.undertow.util.Methods; import org.jboss.marshalling.Marshaller; import org.jboss.marshalling.Marshalling; import org.wildfly.httpclient.common.HttpTargetContext; @@ -87,14 +86,15 @@ public void commit() throws RollbackException, HeuristicMixedException, Heuristi } final CompletableFuture result = new CompletableFuture<>(); statusRef.set(Status.STATUS_COMMITTING); - ClientRequest cr = new ClientRequest() - .setMethod(Methods.POST) - .setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + + + RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_COMMIT).setVersion(targetContext.getProtocolVersion()); + final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); + request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + UT_COMMIT_PATH); - cr.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); - cr.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); - targetContext.sendRequest(cr, sslContext, authenticationConfiguration, output -> { - Marshaller marshaller = targetContext.getHttpMarshallerFactory(cr).createMarshaller(); + request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); + request.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); + targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { + Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); marshaller.writeInt(id.getFormatId()); final byte[] gtid = id.getGlobalTransactionId(); @@ -157,14 +157,15 @@ public void rollback() throws SecurityException, SystemException { final CompletableFuture result = new CompletableFuture<>(); statusRef.set(Status.STATUS_COMMITTING); - ClientRequest cr = new ClientRequest() - .setMethod(Methods.POST) - .setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + + RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_ROLLBACK).setVersion(targetContext.getProtocolVersion()); + final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); + request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + UT_ROLLBACK_PATH); - cr.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); - cr.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); - targetContext.sendRequest(cr, sslContext, authenticationConfiguration, output -> { - Marshaller marshaller = targetContext.getHttpMarshallerFactory(cr).createMarshaller(); + request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); + request.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); + targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { + Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); marshaller.writeInt(id.getFormatId()); final byte[] gtid = id.getGlobalTransactionId(); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java index 907c3cf2..911294ac 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java @@ -20,7 +20,6 @@ import io.undertow.client.ClientRequest; import io.undertow.util.Headers; -import io.undertow.util.Methods; import org.jboss.marshalling.InputStreamByteInput; import org.jboss.marshalling.Unmarshaller; import org.wildfly.httpclient.common.HttpTargetContext; @@ -87,13 +86,13 @@ public SubordinateTransactionControl lookupXid(Xid xid) throws XAException { public Xid[] recover(int flag, String parentName) throws XAException { final CompletableFuture xidList = new CompletableFuture<>(); - ClientRequest cr = new ClientRequest() - .setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + - XA_RECOVER_PATH + "/" + parentName) - .setMethod(Methods.GET); - cr.getRequestHeaders().put(Headers.ACCEPT, XID_LIST + "," + NEW_TRANSACTION); - cr.getRequestHeaders().put(RECOVERY_PARENT_NAME, parentName); - cr.getRequestHeaders().put(RECOVERY_FLAGS, Integer.toString(flag)); + RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.XA_RECOVER).setVersion(targetContext.getProtocolVersion()); + final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); + request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + + XA_RECOVER_PATH + "/" + parentName); + request.getRequestHeaders().put(Headers.ACCEPT, XID_LIST + "," + NEW_TRANSACTION); + request.getRequestHeaders().put(RECOVERY_PARENT_NAME, parentName); + request.getRequestHeaders().put(RECOVERY_FLAGS, Integer.toString(flag)); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); final SSLContext sslContext; @@ -105,9 +104,9 @@ public Xid[] recover(int flag, String parentName) throws XAException { throw xaException; } - targetContext.sendRequest(cr, sslContext, authenticationConfiguration,null, (result, response, closeable) -> { + targetContext.sendRequest(request, sslContext, authenticationConfiguration,null, (result, response, closeable) -> { try { - Unmarshaller unmarshaller = targetContext.getHttpMarshallerFactory(cr).createUnmarshaller(); + Unmarshaller unmarshaller = targetContext.getHttpMarshallerFactory(request).createUnmarshaller(); unmarshaller.start(new InputStreamByteInput(result)); int length = unmarshaller.readInt(); Xid[] ret = new Xid[length]; @@ -149,12 +148,12 @@ public Xid[] recover(int flag, String parentName) throws XAException { public SimpleTransactionControl begin(int timeout) throws SystemException { final CompletableFuture beginXid = new CompletableFuture<>(); - ClientRequest cr = new ClientRequest() - .setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + - targetContext.getProtocolVersion() + UT_BEGIN_PATH) - .setMethod(Methods.POST); - cr.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION + "," + NEW_TRANSACTION); - cr.getRequestHeaders().put(TIMEOUT, timeout); + RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_BEGIN).setVersion(targetContext.getProtocolVersion()); + final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); + request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + + targetContext.getProtocolVersion() + UT_BEGIN_PATH); + request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION + "," + NEW_TRANSACTION); + request.getRequestHeaders().put(TIMEOUT, timeout); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); final SSLContext sslContext; @@ -164,9 +163,9 @@ public SimpleTransactionControl begin(int timeout) throws SystemException { throw new SystemException(e.getMessage()); } - targetContext.sendRequest(cr, sslContext, authenticationConfiguration, null, (result, response, closeable) -> { + targetContext.sendRequest(request, sslContext, authenticationConfiguration, null, (result, response, closeable) -> { try { - Unmarshaller unmarshaller = targetContext.getHttpMarshallerFactory(cr).createUnmarshaller(); + Unmarshaller unmarshaller = targetContext.getHttpMarshallerFactory(request).createUnmarshaller(); unmarshaller.start(new InputStreamByteInput(result)); int formatId = unmarshaller.readInt(); int len = unmarshaller.readInt(); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java index 02c4e421..aa9fcb9a 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java @@ -18,10 +18,25 @@ package org.wildfly.httpclient.transaction; +import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; +import static org.wildfly.httpclient.transaction.RequestType.XA_BEFORE_COMPLETION; +import static org.wildfly.httpclient.transaction.RequestType.XA_COMMIT; +import static org.wildfly.httpclient.transaction.RequestType.XA_FORGET; +import static org.wildfly.httpclient.transaction.RequestType.XA_PREPARE; +import static org.wildfly.httpclient.transaction.RequestType.XA_ROLLBACK; +import static org.wildfly.httpclient.transaction.TransactionConstants.EXCEPTION; +import static org.wildfly.httpclient.transaction.TransactionConstants.READ_ONLY; +import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_BC_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_COMMIT_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_FORGET_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_PREP_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_ROLLBACK_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XID; + import io.undertow.client.ClientRequest; import io.undertow.client.ClientResponse; import io.undertow.util.Headers; -import io.undertow.util.Methods; import org.jboss.marshalling.Marshaller; import org.jboss.marshalling.Marshalling; import org.wildfly.httpclient.common.HttpTargetContext; @@ -37,17 +52,6 @@ import java.util.concurrent.ExecutionException; import java.util.function.Function; -import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.EXCEPTION; -import static org.wildfly.httpclient.transaction.TransactionConstants.READ_ONLY; -import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_BC_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_COMMIT_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_FORGET_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_PREP_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_ROLLBACK_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XID; - /** * Represents a remote subordinate transaction that is managed over HTTP protocol. * @@ -74,12 +78,12 @@ Xid getId() { @Override public void commit(boolean onePhase) throws XAException { String operationPath = XA_COMMIT_PATH + (onePhase ? "?opc=true" : ""); - processOperation(operationPath); + processOperation(XA_COMMIT, operationPath); } @Override public void rollback() throws XAException { - processOperation(XA_ROLLBACK_PATH); + processOperation(XA_ROLLBACK, XA_ROLLBACK_PATH); } @Override @@ -89,12 +93,12 @@ public void end(int flags) throws XAException { @Override public void beforeCompletion() throws XAException { - processOperation(XA_BC_PATH); + processOperation(XA_BEFORE_COMPLETION, XA_BC_PATH); } @Override public int prepare() throws XAException { - boolean readOnly = processOperation(XA_PREP_PATH, (result) -> { + boolean readOnly = processOperation(XA_PREPARE, XA_PREP_PATH, (result) -> { String header = result.getResponseHeaders().getFirst(READ_ONLY); return header != null && Boolean.parseBoolean(header); }); @@ -103,22 +107,23 @@ public int prepare() throws XAException { @Override public void forget() throws XAException { - processOperation(XA_FORGET_PATH); + processOperation(XA_FORGET, XA_FORGET_PATH); } - private void processOperation(String operationPath) throws XAException { - processOperation(operationPath, null); + private void processOperation(RequestType requestType, String operationPath) throws XAException { + processOperation(requestType, operationPath, null); } - private T processOperation(String operationPath, Function resultFunction) throws XAException { + private T processOperation(RequestType requestType, String operationPath, Function resultFunction) throws XAException { final CompletableFuture result = new CompletableFuture<>(); - ClientRequest cr = new ClientRequest() - .setMethod(Methods.POST) - .setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + operationPath); - cr.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); - cr.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); - targetContext.sendRequest(cr, sslContext, authenticationConfiguration, output -> { - Marshaller marshaller = targetContext.getHttpMarshallerFactory(cr).createMarshaller(); + + RequestBuilder builder = new RequestBuilder().setRequestType(requestType).setVersion(targetContext.getProtocolVersion()); + final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); + request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + operationPath); + request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); + request.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); + targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { + Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); marshaller.writeInt(id.getFormatId()); final byte[] gtid = id.getGlobalTransactionId(); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java index 6c84e016..3e5bc118 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java @@ -56,11 +56,11 @@ private void setRequestMethod(final ClientRequest request) { } private void setRequestPath(final ClientRequest request, final String prefix) { - throw new UnsupportedOperationException(); + // NOOP } private void setRequestHeaders(final ClientRequest request) { - throw new UnsupportedOperationException(); + // NOOP } } From 624da20ee36ee67f84bc00c61cc1206ce35b26c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Mon, 27 May 2024 15:12:35 +0200 Subject: [PATCH 05/10] [WEJBHTTP-140] Refactoring - Let RequestBuilder configure HTTP request headers. --- .../HttpRemoteTransactionHandle.java | 7 --- .../HttpRemoteTransactionPeer.java | 13 +----- .../HttpSubordinateTransactionHandle.java | 5 --- .../transaction/RequestBuilder.java | 44 ++++++++++++++++++- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java index f24acd1e..50c64961 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java @@ -19,7 +19,6 @@ package org.wildfly.httpclient.transaction; import io.undertow.client.ClientRequest; -import io.undertow.util.Headers; import org.jboss.marshalling.Marshaller; import org.jboss.marshalling.Marshalling; import org.wildfly.httpclient.common.HttpTargetContext; @@ -39,11 +38,9 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.EXCEPTION; import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; import static org.wildfly.httpclient.transaction.TransactionConstants.UT_COMMIT_PATH; import static org.wildfly.httpclient.transaction.TransactionConstants.UT_ROLLBACK_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XID; /** * Represents a remote transaction that is managed over HTTP protocol. @@ -91,8 +88,6 @@ public void commit() throws RollbackException, HeuristicMixedException, Heuristi final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + UT_COMMIT_PATH); - request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); - request.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); @@ -162,8 +157,6 @@ public void rollback() throws SecurityException, SystemException { final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + UT_ROLLBACK_PATH); - request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); - request.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java index 911294ac..13a5eb39 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java @@ -19,7 +19,6 @@ package org.wildfly.httpclient.transaction; import io.undertow.client.ClientRequest; -import io.undertow.util.Headers; import org.jboss.marshalling.InputStreamByteInput; import org.jboss.marshalling.Unmarshaller; import org.wildfly.httpclient.common.HttpTargetContext; @@ -43,15 +42,10 @@ import static java.security.AccessController.doPrivileged; import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.EXCEPTION; import static org.wildfly.httpclient.transaction.TransactionConstants.NEW_TRANSACTION; -import static org.wildfly.httpclient.transaction.TransactionConstants.RECOVERY_FLAGS; -import static org.wildfly.httpclient.transaction.TransactionConstants.RECOVERY_PARENT_NAME; -import static org.wildfly.httpclient.transaction.TransactionConstants.TIMEOUT; import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; import static org.wildfly.httpclient.transaction.TransactionConstants.UT_BEGIN_PATH; import static org.wildfly.httpclient.transaction.TransactionConstants.XA_RECOVER_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XID_LIST; /** * @author Stuart Douglas @@ -90,9 +84,6 @@ public Xid[] recover(int flag, String parentName) throws XAException { final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + XA_RECOVER_PATH + "/" + parentName); - request.getRequestHeaders().put(Headers.ACCEPT, XID_LIST + "," + NEW_TRANSACTION); - request.getRequestHeaders().put(RECOVERY_PARENT_NAME, parentName); - request.getRequestHeaders().put(RECOVERY_FLAGS, Integer.toString(flag)); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); final SSLContext sslContext; @@ -148,12 +139,10 @@ public Xid[] recover(int flag, String parentName) throws XAException { public SimpleTransactionControl begin(int timeout) throws SystemException { final CompletableFuture beginXid = new CompletableFuture<>(); - RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_BEGIN).setVersion(targetContext.getProtocolVersion()); + RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_BEGIN).setVersion(targetContext.getProtocolVersion()).setTimeout(timeout); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + UT_BEGIN_PATH); - request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION + "," + NEW_TRANSACTION); - request.getRequestHeaders().put(TIMEOUT, timeout); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); final SSLContext sslContext; diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java index aa9fcb9a..9b85745f 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java @@ -24,7 +24,6 @@ import static org.wildfly.httpclient.transaction.RequestType.XA_FORGET; import static org.wildfly.httpclient.transaction.RequestType.XA_PREPARE; import static org.wildfly.httpclient.transaction.RequestType.XA_ROLLBACK; -import static org.wildfly.httpclient.transaction.TransactionConstants.EXCEPTION; import static org.wildfly.httpclient.transaction.TransactionConstants.READ_ONLY; import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; import static org.wildfly.httpclient.transaction.TransactionConstants.XA_BC_PATH; @@ -32,11 +31,9 @@ import static org.wildfly.httpclient.transaction.TransactionConstants.XA_FORGET_PATH; import static org.wildfly.httpclient.transaction.TransactionConstants.XA_PREP_PATH; import static org.wildfly.httpclient.transaction.TransactionConstants.XA_ROLLBACK_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XID; import io.undertow.client.ClientRequest; import io.undertow.client.ClientResponse; -import io.undertow.util.Headers; import org.jboss.marshalling.Marshaller; import org.jboss.marshalling.Marshalling; import org.wildfly.httpclient.common.HttpTargetContext; @@ -120,8 +117,6 @@ private T processOperation(RequestType requestType, String operationPath, Fu RequestBuilder builder = new RequestBuilder().setRequestType(requestType).setVersion(targetContext.getProtocolVersion()); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + operationPath); - request.getRequestHeaders().put(Headers.ACCEPT, EXCEPTION.toString()); - request.getRequestHeaders().put(Headers.CONTENT_TYPE, XID.toString()); targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java index 3e5bc118..df1e960d 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java @@ -18,7 +18,20 @@ package org.wildfly.httpclient.transaction; +import static io.undertow.util.Headers.ACCEPT; +import static io.undertow.util.Headers.CONTENT_TYPE; +import static org.wildfly.httpclient.transaction.RequestType.UT_BEGIN; +import static org.wildfly.httpclient.transaction.RequestType.XA_RECOVER; +import static org.wildfly.httpclient.transaction.TransactionConstants.EXCEPTION; +import static org.wildfly.httpclient.transaction.TransactionConstants.NEW_TRANSACTION; +import static org.wildfly.httpclient.transaction.TransactionConstants.RECOVERY_FLAGS; +import static org.wildfly.httpclient.transaction.TransactionConstants.RECOVERY_PARENT_NAME; +import static org.wildfly.httpclient.transaction.TransactionConstants.TIMEOUT; +import static org.wildfly.httpclient.transaction.TransactionConstants.XID; +import static org.wildfly.httpclient.transaction.TransactionConstants.XID_LIST; + import io.undertow.client.ClientRequest; +import io.undertow.util.HeaderMap; import org.wildfly.httpclient.common.Protocol; /** @@ -28,6 +41,9 @@ final class RequestBuilder { private RequestType requestType; private int version = Protocol.LATEST; + private int timeout; + private int flags; + private String parentName; // setters @@ -41,6 +57,21 @@ RequestBuilder setVersion(final int version) { return this; } + RequestBuilder setTimeout(final int timeout) { + this.timeout = timeout; + return this; + } + + RequestBuilder setFlags(final int flags) { + this.flags = flags; + return this; + } + + RequestBuilder setParent(final String parentName) { + this.parentName = parentName; + return this; + } + // helper methods ClientRequest createRequest(final String prefix) { @@ -60,7 +91,18 @@ private void setRequestPath(final ClientRequest request, final String prefix) { } private void setRequestHeaders(final ClientRequest request) { - // NOOP + final HeaderMap headers = request.getRequestHeaders(); + if (requestType == UT_BEGIN) { + headers.put(ACCEPT, EXCEPTION + "," + NEW_TRANSACTION); + headers.put(TIMEOUT, timeout); + } else if (requestType == XA_RECOVER) { + headers.put(ACCEPT, XID_LIST + "," + NEW_TRANSACTION); + headers.put(RECOVERY_PARENT_NAME, parentName); + headers.put(RECOVERY_FLAGS, Integer.toString(flags)); + } else { + headers.add(ACCEPT, EXCEPTION.toString()); + headers.put(CONTENT_TYPE, XID.toString()); + } } } From c338886c468386cb6d4c4a681f547f8c8a6f6d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Mon, 27 May 2024 15:54:41 +0200 Subject: [PATCH 06/10] [WEJBHTTP-140] Adding HTTP request path parameter to RequestType enum. --- .../httpclient/transaction/RequestType.java | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java index 7efe3428..1a257928 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java @@ -20,6 +20,15 @@ import static io.undertow.util.Methods.GET; import static io.undertow.util.Methods.POST; +import static org.wildfly.httpclient.transaction.TransactionConstants.UT_BEGIN_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.UT_COMMIT_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.UT_ROLLBACK_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_BC_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_COMMIT_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_FORGET_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_PREP_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_RECOVER_PATH; +import static org.wildfly.httpclient.transaction.TransactionConstants.XA_ROLLBACK_PATH; import io.undertow.util.HttpString; @@ -28,24 +37,30 @@ */ enum RequestType { - UT_BEGIN(POST), - UT_COMMIT(POST), - UT_ROLLBACK(POST), - XA_BEFORE_COMPLETION(POST), - XA_COMMIT(POST), - XA_FORGET(POST), - XA_PREPARE(POST), - XA_RECOVER(GET), - XA_ROLLBACK(POST); + UT_BEGIN(POST, UT_BEGIN_PATH), + UT_COMMIT(POST, UT_COMMIT_PATH), + UT_ROLLBACK(POST, UT_ROLLBACK_PATH), + XA_BEFORE_COMPLETION(POST, XA_BC_PATH), + XA_COMMIT(POST, XA_COMMIT_PATH), + XA_FORGET(POST, XA_FORGET_PATH), + XA_PREPARE(POST, XA_PREP_PATH), + XA_RECOVER(GET, XA_RECOVER_PATH), + XA_ROLLBACK(POST, XA_ROLLBACK_PATH); private final HttpString method; + private final String path; - RequestType(final HttpString method) { + RequestType(final HttpString method, final String path) { this.method = method; + this.path = path; } HttpString getMethod() { return method; } + String getPath() { + return path; + } + } From 2debcaa099529403aed203bf8d999951ac0bccb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Mon, 27 May 2024 16:24:07 +0200 Subject: [PATCH 07/10] [WEJBHTTP-140] Refactoring - Let RequestBuilder configure HTTP request paths. --- .../HttpRemoteTransactionHandle.java | 11 ++----- .../HttpRemoteTransactionPeer.java | 10 +----- .../HttpSubordinateTransactionHandle.java | 29 ++++++---------- .../transaction/RequestBuilder.java | 33 ++++++++++++++++++- 4 files changed, 45 insertions(+), 38 deletions(-) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java index 50c64961..4ad2749b 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java @@ -37,11 +37,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicInteger; -import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; -import static org.wildfly.httpclient.transaction.TransactionConstants.UT_COMMIT_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.UT_ROLLBACK_PATH; - /** * Represents a remote transaction that is managed over HTTP protocol. * @@ -86,8 +81,7 @@ public void commit() throws RollbackException, HeuristicMixedException, Heuristi RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_COMMIT).setVersion(targetContext.getProtocolVersion()); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); - request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + - targetContext.getProtocolVersion() + UT_COMMIT_PATH); + targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); @@ -155,8 +149,7 @@ public void rollback() throws SecurityException, SystemException { RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_ROLLBACK).setVersion(targetContext.getProtocolVersion()); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); - request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() - + UT_ROLLBACK_PATH); + targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java index 13a5eb39..864a2d9d 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java @@ -41,11 +41,7 @@ import java.util.concurrent.ExecutionException; import static java.security.AccessController.doPrivileged; -import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; import static org.wildfly.httpclient.transaction.TransactionConstants.NEW_TRANSACTION; -import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; -import static org.wildfly.httpclient.transaction.TransactionConstants.UT_BEGIN_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_RECOVER_PATH; /** * @author Stuart Douglas @@ -80,10 +76,8 @@ public SubordinateTransactionControl lookupXid(Xid xid) throws XAException { public Xid[] recover(int flag, String parentName) throws XAException { final CompletableFuture xidList = new CompletableFuture<>(); - RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.XA_RECOVER).setVersion(targetContext.getProtocolVersion()); + RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.XA_RECOVER).setVersion(targetContext.getProtocolVersion()).setFlags(flag).setParent(parentName); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); - request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + - XA_RECOVER_PATH + "/" + parentName); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); final SSLContext sslContext; @@ -141,8 +135,6 @@ public SimpleTransactionControl begin(int timeout) throws SystemException { RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_BEGIN).setVersion(targetContext.getProtocolVersion()).setTimeout(timeout); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); - request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + - targetContext.getProtocolVersion() + UT_BEGIN_PATH); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); final SSLContext sslContext; diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java index 9b85745f..6c0bd2dd 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java @@ -18,19 +18,12 @@ package org.wildfly.httpclient.transaction; -import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; import static org.wildfly.httpclient.transaction.RequestType.XA_BEFORE_COMPLETION; import static org.wildfly.httpclient.transaction.RequestType.XA_COMMIT; import static org.wildfly.httpclient.transaction.RequestType.XA_FORGET; import static org.wildfly.httpclient.transaction.RequestType.XA_PREPARE; import static org.wildfly.httpclient.transaction.RequestType.XA_ROLLBACK; import static org.wildfly.httpclient.transaction.TransactionConstants.READ_ONLY; -import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_BC_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_COMMIT_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_FORGET_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_PREP_PATH; -import static org.wildfly.httpclient.transaction.TransactionConstants.XA_ROLLBACK_PATH; import io.undertow.client.ClientRequest; import io.undertow.client.ClientResponse; @@ -74,13 +67,12 @@ Xid getId() { @Override public void commit(boolean onePhase) throws XAException { - String operationPath = XA_COMMIT_PATH + (onePhase ? "?opc=true" : ""); - processOperation(XA_COMMIT, operationPath); + processOperation(XA_COMMIT, null, onePhase ? Boolean.TRUE : null); } @Override public void rollback() throws XAException { - processOperation(XA_ROLLBACK, XA_ROLLBACK_PATH); + processOperation(XA_ROLLBACK); } @Override @@ -90,33 +82,32 @@ public void end(int flags) throws XAException { @Override public void beforeCompletion() throws XAException { - processOperation(XA_BEFORE_COMPLETION, XA_BC_PATH); + processOperation(XA_BEFORE_COMPLETION); } @Override public int prepare() throws XAException { - boolean readOnly = processOperation(XA_PREPARE, XA_PREP_PATH, (result) -> { + boolean readOnly = processOperation(XA_PREPARE, (result) -> { String header = result.getResponseHeaders().getFirst(READ_ONLY); return header != null && Boolean.parseBoolean(header); - }); + }, null); return readOnly ? XAResource.XA_RDONLY : XAResource.XA_OK; } @Override public void forget() throws XAException { - processOperation(XA_FORGET, XA_FORGET_PATH); + processOperation(XA_FORGET); } - private void processOperation(RequestType requestType, String operationPath) throws XAException { - processOperation(requestType, operationPath, null); + private void processOperation(RequestType requestType) throws XAException { + processOperation(requestType, null, null); } - private T processOperation(RequestType requestType, String operationPath, Function resultFunction) throws XAException { + private T processOperation(RequestType requestType, Function resultFunction, Boolean onePhase) throws XAException { final CompletableFuture result = new CompletableFuture<>(); - RequestBuilder builder = new RequestBuilder().setRequestType(requestType).setVersion(targetContext.getProtocolVersion()); + RequestBuilder builder = new RequestBuilder().setRequestType(requestType).setVersion(targetContext.getProtocolVersion()).setOnePhase(onePhase); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); - request.setPath(targetContext.getUri().getPath() + TXN_CONTEXT + VERSION_PATH + targetContext.getProtocolVersion() + operationPath); targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller(); marshaller.start(Marshalling.createByteOutput(output)); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java index df1e960d..4b3af7b8 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java @@ -20,13 +20,18 @@ import static io.undertow.util.Headers.ACCEPT; import static io.undertow.util.Headers.CONTENT_TYPE; +import static java.net.URLEncoder.encode; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.wildfly.httpclient.common.Protocol.VERSION_PATH; import static org.wildfly.httpclient.transaction.RequestType.UT_BEGIN; +import static org.wildfly.httpclient.transaction.RequestType.XA_COMMIT; import static org.wildfly.httpclient.transaction.RequestType.XA_RECOVER; import static org.wildfly.httpclient.transaction.TransactionConstants.EXCEPTION; import static org.wildfly.httpclient.transaction.TransactionConstants.NEW_TRANSACTION; import static org.wildfly.httpclient.transaction.TransactionConstants.RECOVERY_FLAGS; import static org.wildfly.httpclient.transaction.TransactionConstants.RECOVERY_PARENT_NAME; import static org.wildfly.httpclient.transaction.TransactionConstants.TIMEOUT; +import static org.wildfly.httpclient.transaction.TransactionConstants.TXN_CONTEXT; import static org.wildfly.httpclient.transaction.TransactionConstants.XID; import static org.wildfly.httpclient.transaction.TransactionConstants.XID_LIST; @@ -44,6 +49,7 @@ final class RequestBuilder { private int timeout; private int flags; private String parentName; + private Boolean onePhase; // setters @@ -67,6 +73,11 @@ RequestBuilder setFlags(final int flags) { return this; } + RequestBuilder setOnePhase(final Boolean onePhase) { + this.onePhase = onePhase; + return this; + } + RequestBuilder setParent(final String parentName) { this.parentName = parentName; return this; @@ -87,9 +98,22 @@ private void setRequestMethod(final ClientRequest request) { } private void setRequestPath(final ClientRequest request, final String prefix) { - // NOOP + final StringBuilder sb = new StringBuilder(); + if (prefix != null) { + sb.append(prefix); + } + appendPath(sb, TXN_CONTEXT, false); + appendPath(sb, VERSION_PATH + version, false); + appendPath(sb, requestType.getPath(), false); + if (requestType == XA_COMMIT) { + sb.append(onePhase != null && onePhase ? "?opc=true" : ""); + } else if (requestType == XA_RECOVER) { + appendPath(sb, parentName, false); + } + request.setPath(sb.toString()); } + private void setRequestHeaders(final ClientRequest request) { final HeaderMap headers = request.getRequestHeaders(); if (requestType == UT_BEGIN) { @@ -105,4 +129,11 @@ private void setRequestHeaders(final ClientRequest request) { } } + private static void appendPath(final StringBuilder sb, final String path, final boolean encode) { + if (!path.startsWith("/")) { + sb.append("/"); + } + sb.append(encode ? encode(path, UTF_8) : path); + } + } From 2e03945b8623b264316a6234a812a454e05f596c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Tue, 10 Sep 2024 12:58:35 +0200 Subject: [PATCH 08/10] [WEJBHTTP-140] Adding Javadoc for RequestType enum. --- .../httpclient/transaction/RequestType.java | 84 ++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java index 1a257928..50a36dd4 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestType.java @@ -33,18 +33,80 @@ import io.undertow.util.HttpString; /** + * HTTP TXN module invocation types. Each invocation type has {@linkplain #getName() name}, {@linkplain #getMethod() method} + * and {@linkplain #getPath() path}. An invocation can be one of the following types: + *
    + *
  • {@link #UT_BEGIN}
    + * Establishes a remote user-controlled transaction. + *
  • + *
  • {@link #UT_COMMIT}
    + * Commits a remote user-controlled transaction. + *
  • + *
  • {@link #UT_ROLLBACK}
    + * Rolls back a remote user-controlled transaction. + *
  • + *
  • {@link #XA_RECOVER}
    + * Acquires a list of all unresolved subordinate remote user-controlled transactions. + *
  • + *
  • {@link #XA_BEFORE_COMPLETION}
    + * Performs before-commit operations, including running all transaction synchronizations on subordinate transaction. + *
  • + *
  • {@link #XA_COMMIT}
    + * Commits a subordinate transaction. + *
  • + *
  • {@link #XA_FORGET}
    + * Forgets the (previously prepared) subordinate transaction. + *
  • + *
  • {@link #XA_PREPARE}
    + * Prepares the subordinate transaction. + *
  • + *
  • {@link #XA_ROLLBACK}
    + * Rolls back the subordinate transaction. + *
  • + *
+ * * @author Richard Opalka */ enum RequestType { + /** + * {@code UT_BEGIN} invocation type: used to establish a remote user-controlled transaction via HTTP protocol. + */ UT_BEGIN(POST, UT_BEGIN_PATH), + /** + * {@code UT_COMMIT} invocation type: used to commit remote user-controlled transaction via HTTP protocol. + */ UT_COMMIT(POST, UT_COMMIT_PATH), + /** + * {@code UT_ROLLBACK} invocation type: used to rollback remote user-controlled transaction via HTTP protocol. + */ UT_ROLLBACK(POST, UT_ROLLBACK_PATH), + /** + * {@code XA_RECOVER} invocation type: used to acquire a list of all unresolved subordinate remote user-controlled + * transactions from the location associated with this provider via HTTP protocol. + */ + // TODO: THIS IS BUG. The name must be UT_RECOVER & request path must contain 'ut' instead of 'xa' prefix + XA_RECOVER(GET, XA_RECOVER_PATH), + /** + * {@code XA_BEFORE_COMPLETION} invocation type: used to perform before-commit operations, + * including running all transaction synchronizations on given subordinate transaction via HTTP protocol. + */ XA_BEFORE_COMPLETION(POST, XA_BC_PATH), + /** + * {@code XA_COMMIT} invocation type: used to commit the subordinate transaction via HTTP protocol. + */ XA_COMMIT(POST, XA_COMMIT_PATH), + /** + * {@code XA_FORGET} invocation type: used to forget the (previously prepared) subordinate transaction via HTTP protocol. + */ XA_FORGET(POST, XA_FORGET_PATH), + /** + * {@code XA_PREPARE} invocation type: used to prepare the subordinate transaction via HTTP protocol. + */ XA_PREPARE(POST, XA_PREP_PATH), - XA_RECOVER(GET, XA_RECOVER_PATH), + /** + * {@code XA_ROLLBACK} invocation type: used to roll back the subordinate transaction via HTTP protocol. + */ XA_ROLLBACK(POST, XA_ROLLBACK_PATH); private final HttpString method; @@ -55,11 +117,27 @@ enum RequestType { this.path = path; } - HttpString getMethod() { + /** + * Returns the name of this invocation. + * @return this invocation {@linkplain #name()}. + */ + final String getName() { + return name(); + } + + /** + * Returns the HTTP request method used by this invocation. + * @return this invocation HTTP request method. + */ + final HttpString getMethod() { return method; } - String getPath() { + /** + * Returns the HTTP request subpath used by this invocation. + * @return this invocation HTTP request subpath. + */ + final String getPath() { return path; } From b355868a7202efe37c9156ed7f916e7439b2339e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Tue, 10 Sep 2024 13:01:06 +0200 Subject: [PATCH 09/10] [WEJBHTTP-140] Initial Javadoc for RequestBuilder class. --- .../org/wildfly/httpclient/transaction/RequestBuilder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java index 4b3af7b8..08bb4c98 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/RequestBuilder.java @@ -40,6 +40,10 @@ import org.wildfly.httpclient.common.Protocol; /** + * HTTP TXN module client request builder. Encapsulates all information needed to create HTTP TXN client requests. + * Use setter methods (those returning {@link RequestBuilder}) to configure the builder. + * Once configured {@link #createRequest(String)} method must be called to build HTTP client request. + * * @author Richard Opalka */ final class RequestBuilder { From 36add25afa00d4778f9433ee1f255e63f1a848e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Op=C3=A1lka?= Date: Wed, 25 Sep 2024 13:40:04 +0200 Subject: [PATCH 10/10] [WEJBHTTP-140] Make all RequestBuilder instances final. --- .../httpclient/transaction/HttpRemoteTransactionHandle.java | 4 ++-- .../httpclient/transaction/HttpRemoteTransactionPeer.java | 4 ++-- .../transaction/HttpSubordinateTransactionHandle.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java index 4ad2749b..fe4b560a 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionHandle.java @@ -79,7 +79,7 @@ public void commit() throws RollbackException, HeuristicMixedException, Heuristi final CompletableFuture result = new CompletableFuture<>(); statusRef.set(Status.STATUS_COMMITTING); - RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_COMMIT).setVersion(targetContext.getProtocolVersion()); + final RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_COMMIT).setVersion(targetContext.getProtocolVersion()); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { @@ -147,7 +147,7 @@ public void rollback() throws SecurityException, SystemException { final CompletableFuture result = new CompletableFuture<>(); statusRef.set(Status.STATUS_COMMITTING); - RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_ROLLBACK).setVersion(targetContext.getProtocolVersion()); + final RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_ROLLBACK).setVersion(targetContext.getProtocolVersion()); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java index 864a2d9d..87bfc9bb 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpRemoteTransactionPeer.java @@ -76,7 +76,7 @@ public SubordinateTransactionControl lookupXid(Xid xid) throws XAException { public Xid[] recover(int flag, String parentName) throws XAException { final CompletableFuture xidList = new CompletableFuture<>(); - RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.XA_RECOVER).setVersion(targetContext.getProtocolVersion()).setFlags(flag).setParent(parentName); + final RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.XA_RECOVER).setVersion(targetContext.getProtocolVersion()).setFlags(flag).setParent(parentName); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); @@ -133,7 +133,7 @@ public Xid[] recover(int flag, String parentName) throws XAException { public SimpleTransactionControl begin(int timeout) throws SystemException { final CompletableFuture beginXid = new CompletableFuture<>(); - RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_BEGIN).setVersion(targetContext.getProtocolVersion()).setTimeout(timeout); + final RequestBuilder builder = new RequestBuilder().setRequestType(RequestType.UT_BEGIN).setVersion(targetContext.getProtocolVersion()).setTimeout(timeout); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); final AuthenticationConfiguration authenticationConfiguration = getAuthenticationConfiguration(targetContext.getUri()); diff --git a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java index 6c0bd2dd..f34cc271 100644 --- a/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java +++ b/transaction/src/main/java/org/wildfly/httpclient/transaction/HttpSubordinateTransactionHandle.java @@ -106,7 +106,7 @@ private void processOperation(RequestType requestType) throws XAException { private T processOperation(RequestType requestType, Function resultFunction, Boolean onePhase) throws XAException { final CompletableFuture result = new CompletableFuture<>(); - RequestBuilder builder = new RequestBuilder().setRequestType(requestType).setVersion(targetContext.getProtocolVersion()).setOnePhase(onePhase); + final RequestBuilder builder = new RequestBuilder().setRequestType(requestType).setVersion(targetContext.getProtocolVersion()).setOnePhase(onePhase); final ClientRequest request = builder.createRequest(targetContext.getUri().getPath()); targetContext.sendRequest(request, sslContext, authenticationConfiguration, output -> { Marshaller marshaller = targetContext.getHttpMarshallerFactory(request).createMarshaller();