diff --git a/.github/workflows/verify-format.yml b/.github/workflows/verify-format.yml new file mode 100644 index 0000000000..7142525d80 --- /dev/null +++ b/.github/workflows/verify-format.yml @@ -0,0 +1,22 @@ +name: LRA-FORMATTING + +on: + workflow_dispatch: + pull_request: + branches: + - main + +jobs: + verify-format: + name: Verify format + timeout-minutes: 5 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-java@v1 + with: + java-version: 17 # minimum supported JDK + + - name: Verify pull request format + run: ./mvnw formatter:validate diff --git a/.gitignore b/.gitignore index fced0225a9..9ee92ba725 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ CosServices.cfg audit.log *.zip *.db -*.json \ No newline at end of file +*.json +.cache + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31e5c52990..8f52c9d5d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,6 +14,8 @@ But first, read this page. We use a four step process for contributions: 1. Fork the project repository to your own GitHub account. +1. Make your changes. +1. Build the project (`./mvnw clean package -DskipTests`) to apply the formatting rules. 1. Commit your changes to your fork. 1. Create a GitHub Pull Request for your change, following the instructions in the pull request template. 1. Perform a Code Review with the project maintainers on the pull request. diff --git a/client/src/main/java/io/narayana/lra/client/internal/NarayanaLRAClient.java b/client/src/main/java/io/narayana/lra/client/internal/NarayanaLRAClient.java index 3ffae0c139..831ba52e46 100644 --- a/client/src/main/java/io/narayana/lra/client/internal/NarayanaLRAClient.java +++ b/client/src/main/java/io/narayana/lra/client/internal/NarayanaLRAClient.java @@ -5,6 +5,31 @@ package io.narayana.lra.client.internal; +import static io.narayana.lra.LRAConstants.AFTER; +import static io.narayana.lra.LRAConstants.CLIENT_ID_PARAM_NAME; +import static io.narayana.lra.LRAConstants.COMPENSATE; +import static io.narayana.lra.LRAConstants.COMPLETE; +import static io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME; +import static io.narayana.lra.LRAConstants.FORGET; +import static io.narayana.lra.LRAConstants.LEAVE; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_LINK_HEADER_NAME; +import static io.narayana.lra.LRAConstants.PARENT_LRA_PARAM_NAME; +import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; +import static io.narayana.lra.LRAConstants.STATUS; +import static io.narayana.lra.LRAConstants.TIMELIMIT_PARAM_NAME; +import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; +import static jakarta.ws.rs.core.Response.Status.GONE; +import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import static jakarta.ws.rs.core.Response.Status.NO_CONTENT; +import static jakarta.ws.rs.core.Response.Status.OK; +import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; +import static jakarta.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; + import io.narayana.lra.Current; import io.narayana.lra.LRAConstants; import io.narayana.lra.LRAData; @@ -29,14 +54,6 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilder; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.Forget; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.Status; -import org.eclipse.microprofile.lra.annotation.ws.rs.Leave; - import java.io.Closeable; import java.lang.annotation.Annotation; import java.lang.reflect.Method; @@ -55,33 +72,13 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - -import static io.narayana.lra.LRAConstants.AFTER; -import static io.narayana.lra.LRAConstants.CLIENT_ID_PARAM_NAME; -import static io.narayana.lra.LRAConstants.COMPENSATE; -import static io.narayana.lra.LRAConstants.COMPLETE; -import static io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME; -import static io.narayana.lra.LRAConstants.FORGET; -import static io.narayana.lra.LRAConstants.LEAVE; -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME; -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_LINK_HEADER_NAME; -import static io.narayana.lra.LRAConstants.PARENT_LRA_PARAM_NAME; -import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; -import static io.narayana.lra.LRAConstants.STATUS; -import static io.narayana.lra.LRAConstants.TIMELIMIT_PARAM_NAME; - -import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; -import static jakarta.ws.rs.core.Response.Status.GONE; -import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; -import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE; -import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; -import static jakarta.ws.rs.core.Response.Status.NO_CONTENT; -import static jakarta.ws.rs.core.Response.Status.OK; -import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; - -import static jakarta.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.Forget; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.Status; +import org.eclipse.microprofile.lra.annotation.ws.rs.Leave; /** * WARNING: NarayanaLRAClient is an internal utility class and is subject to change @@ -128,7 +125,7 @@ public class NarayanaLRAClient implements Closeable { * If not defined as default value is taken {@code http://localhost:8080/lra-coordinator}. * The LRA recovery coordinator will be searched at the sub-path {@value LRAConstants#RECOVERY_COORDINATOR_PATH_NAME}. * - * @throws IllegalStateException thrown when the URL taken from the system property value is not a URL format + * @throws IllegalStateException thrown when the URL taken from the system property value is not a URL format */ public NarayanaLRAClient() { this(System.getProperty(NarayanaLRAClient.LRA_COORDINATOR_URL_KEY, @@ -139,9 +136,9 @@ public NarayanaLRAClient() { * Creating LRA client where expecting LRA coordinator being available through * protocol protocol at host:port/coordinatorPath. * - * @param protocol protocol used to contact the LRA coordinator - * @param host hostname where the LRA coordinator will be contacted - * @param port port where the LRA coordinator will be contacted + * @param protocol protocol used to contact the LRA coordinator + * @param host hostname where the LRA coordinator will be contacted + * @param port port where the LRA coordinator will be contacted * @param coordinatorPath path where the LRA coordinator will be contacted */ public NarayanaLRAClient(String protocol, String host, int port, String coordinatorPath) { @@ -153,7 +150,7 @@ public NarayanaLRAClient(String protocol, String host, int port, String coordina * at the provided uri. * The LRA recovery coordinator will be searched at the sub-path {@value LRAConstants#RECOVERY_COORDINATOR_PATH_NAME}. * - * @param coordinatorUrl uri of the LRA coordinator + * @param coordinatorUrl uri of the LRA coordinator */ public NarayanaLRAClient(URI coordinatorUrl) { this.coordinatorUrl = coordinatorUrl; @@ -164,8 +161,8 @@ public NarayanaLRAClient(URI coordinatorUrl) { * at the provided URL defined by String. * The LRA recovery coordinator will be searched at the sub-path {@value LRAConstants#RECOVERY_COORDINATOR_PATH_NAME}. * - * @param coordinatorUrl url of the LRA coordinator - * @throws IllegalStateException thrown when the provided URL String is not a URL format + * @param coordinatorUrl url of the LRA coordinator + * @throws IllegalStateException thrown when the provided URL String is not a URL format */ public NarayanaLRAClient(String coordinatorUrl) { try { @@ -183,7 +180,7 @@ public NarayanaLRAClient(String coordinatorUrl) { * It takes the provided URI and tries to derive the URL path of the coordinator responsible * for the LRA id. The URL is then used as endpoint for later use of this LRA Narayana client instance. * - * @param lraId LRA id consisting of the coordinator URL and the LRA uid + * @param lraId LRA id consisting of the coordinator URL and the LRA uid */ public void setCurrentLRA(URI lraId) { try { @@ -200,18 +197,20 @@ public List getAllLRAs() { try { client = getClient(); Response response = client.target(coordinatorUrl) - .request() - .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) - .async() - .get() - .get(QUERY_TIMEOUT, TimeUnit.SECONDS); + .request() + .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) + .async() + .get() + .get(QUERY_TIMEOUT, TimeUnit.SECONDS); if (response.getStatus() != OK.getStatusCode()) { - LRALogger.logger.debugf("Error getting all LRAs from the coordinator, response status: %d", response.getStatus()); + LRALogger.logger.debugf("Error getting all LRAs from the coordinator, response status: %d", + response.getStatus()); throw new WebApplicationException(response); } - return response.readEntity(new GenericType>() {}); + return response.readEntity(new GenericType>() { + }); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new WebApplicationException(Response.status(SERVICE_UNAVAILABLE) .entity("getAllLRAs client request timed out, try again later").build()); @@ -225,9 +224,9 @@ public List getAllLRAs() { /** * Starting LRA. You provide client id determining the LRA being started. * - * @param clientID client id determining the LRA - * @return LRA id as URL - * @throws WebApplicationException thrown when start of the LRA failed + * @param clientID client id determining the LRA + * @return LRA id as URL + * @throws WebApplicationException thrown when start of the LRA failed */ public URI startLRA(String clientID) throws WebApplicationException { return startLRA(clientID, 0L); @@ -237,10 +236,10 @@ public URI startLRA(String clientID) throws WebApplicationException { * Starting LRA. You provide client id that joins the LRA context * and is passed when working with the LRA. * - * @param clientID client id determining the LRA - * @param timeout timeout value in seconds, when timeout-ed the LRA will be compensated - * @return LRA id as URL - * @throws WebApplicationException thrown when start of the LRA failed + * @param clientID client id determining the LRA + * @param timeout timeout value in seconds, when timeout-ed the LRA will be compensated + * @return LRA id as URL + * @throws WebApplicationException thrown when start of the LRA failed */ private URI startLRA(String clientID, Long timeout) throws WebApplicationException { return startLRA(clientID, timeout, ChronoUnit.SECONDS); @@ -250,11 +249,11 @@ private URI startLRA(String clientID, Long timeout) throws WebApplicationExcepti * Starting LRA. You provide client id that joins the LRA context * and is passed when working with the LRA. * - * @param clientID client id determining the LRA - * @param timeout timeout value, when timeout-ed the LRA will be compensated - * @param unit timeout unit, when null seconds are used - * @return LRA id as URL - * @throws WebApplicationException thrown when start of the LRA failed + * @param clientID client id determining the LRA + * @param timeout timeout value, when timeout-ed the LRA will be compensated + * @param unit timeout unit, when null seconds are used + * @return LRA id as URL + * @throws WebApplicationException thrown when start of the LRA failed */ private URI startLRA(String clientID, Long timeout, ChronoUnit unit) throws WebApplicationException { return startLRA(getCurrent(), clientID, timeout, unit); @@ -268,14 +267,16 @@ public URI startLRA(URI parentLRA, String clientID, Long timeout, ChronoUnit uni * Starting LRA. You provide client id that joins the LRA context * and is passed when working with the LRA. * - * @param parentLRA when the newly started LRA should be nested with this LRA parent, when null the newly started LRA is top-level - * @param clientID client id determining the LRA - * @param timeout timeout value, when timeout-ed the LRA will be compensated - * @param unit timeout unit, when null seconds are used - * @return LRA id as URL - * @throws WebApplicationException thrown when start of the LRA failed + * @param parentLRA when the newly started LRA should be nested with this LRA parent, when null the newly started LRA is + * top-level + * @param clientID client id determining the LRA + * @param timeout timeout value, when timeout-ed the LRA will be compensated + * @param unit timeout unit, when null seconds are used + * @return LRA id as URL + * @throws WebApplicationException thrown when start of the LRA failed */ - public URI startLRA(URI parentLRA, String clientID, Long timeout, ChronoUnit unit, boolean verbose) throws WebApplicationException { + public URI startLRA(URI parentLRA, String clientID, Long timeout, ChronoUnit unit, boolean verbose) + throws WebApplicationException { Client client = null; Response response = null; URI lra; @@ -302,15 +303,15 @@ public URI startLRA(URI parentLRA, String clientID, Long timeout, ChronoUnit uni client = getClient(); response = client.target(coordinatorUrl) - .path(START_PATH) - .queryParam(CLIENT_ID_PARAM_NAME, clientID) - .queryParam(TIMELIMIT_PARAM_NAME, Duration.of(timeout, unit).toMillis()) - .queryParam(PARENT_LRA_PARAM_NAME, encodedParentLRA) - .request() - .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) - .async() - .post(null) - .get(START_TIMEOUT, TimeUnit.SECONDS); + .path(START_PATH) + .queryParam(CLIENT_ID_PARAM_NAME, clientID) + .queryParam(TIMELIMIT_PARAM_NAME, Duration.of(timeout, unit).toMillis()) + .queryParam(PARENT_LRA_PARAM_NAME, encodedParentLRA) + .request() + .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) + .async() + .post(null) + .get(START_TIMEOUT, TimeUnit.SECONDS); // validate the HTTP status code says an LRA resource was created if (isUnexpectedResponseStatus(response, Response.Status.CREATED)) { @@ -373,16 +374,17 @@ public void closeLRA(URI lraId, String compensator, String userData) throws WebA * @throws WebApplicationException if the LRA coordinator failed to enlist the participant */ public URI joinLRA(URI lraId, Long timeLimit, - URI compensateUri, URI completeUri, URI forgetUri, URI leaveUri, URI afterUri, URI statusUri, - String compensatorData) throws WebApplicationException { + URI compensateUri, URI completeUri, URI forgetUri, URI leaveUri, URI afterUri, URI statusUri, + String compensatorData) throws WebApplicationException { return enlistCompensator(lraId, timeLimit, "", compensateUri, completeUri, forgetUri, leaveUri, afterUri, statusUri, null); } + public URI joinLRA(URI lraId, Long timeLimit, - URI compensateUri, URI completeUri, URI forgetUri, URI leaveUri, URI afterUri, URI statusUri, - StringBuilder compensatorData) throws WebApplicationException { + URI compensateUri, URI completeUri, URI forgetUri, URI leaveUri, URI afterUri, URI statusUri, + StringBuilder compensatorData) throws WebApplicationException { return enlistCompensator(lraId, timeLimit, "", compensateUri, completeUri, forgetUri, leaveUri, afterUri, statusUri, @@ -400,10 +402,9 @@ public URI joinLRA(URI lraId, Long timeLimit, * @throws WebApplicationException if the LRA coordinator failed to enlist the participant */ public URI joinLRA(URI lraId, Long timeLimit, - URI participantUri, StringBuilder compensatorData) throws WebApplicationException { + URI participantUri, StringBuilder compensatorData) throws WebApplicationException { validateURI(participantUri, false, "Invalid participant URL: %s"); - StringBuilder linkHeaderValue - = makeLink(new StringBuilder(), null, "participant", participantUri.toASCIIString()); + StringBuilder linkHeaderValue = makeLink(new StringBuilder(), null, "participant", participantUri.toASCIIString()); return enlistCompensator(lraId, timeLimit, linkHeaderValue.toString(), compensatorData); } @@ -416,12 +417,12 @@ public void leaveLRA(URI lraId, String body) throws WebApplicationException { client = getClient(); response = client.target(coordinatorUrl) - .path(String.format(LEAVE_PATH, LRAConstants.getLRAUid(lraId))) - .request() - .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) - .async() - .put(body == null ? Entity.text("") : Entity.text(body)) - .get(LEAVE_TIMEOUT, TimeUnit.SECONDS); + .path(String.format(LEAVE_PATH, LRAConstants.getLRAUid(lraId))) + .request() + .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) + .async() + .put(body == null ? Entity.text("") : Entity.text(body)) + .get(LEAVE_TIMEOUT, TimeUnit.SECONDS); if (OK.getStatusCode() != response.getStatus()) { String logMsg = LRALogger.i18nLogger.error_lraLeaveUnexpectedStatus(lraId, response.getStatus(), @@ -445,14 +446,14 @@ public void leaveLRA(URI lraId, String body) throws WebApplicationException { * You get map of string and URI. * * @param compensatorClass compensator class to examine. - * @param uriPrefix the uri that triggered this join request. - * @param timeout how long the participant is prepared to wait for LRA - * to compensate or complete. + * @param uriPrefix the uri that triggered this join request. + * @param timeout how long the participant is prepared to wait for LRA + * to compensate or complete. * @return map of URI */ public static Map getTerminationUris(Class compensatorClass, String uriPrefix, Long timeout) { Map paths = new HashMap<>(); - final boolean[] asyncTermination = {false}; + final boolean[] asyncTermination = { false }; String timeoutValue = timeout != null ? Long.toString(timeout) : "0"; @@ -512,8 +513,8 @@ public static Map getTerminationUris(Class compensatorClass, * This means that {@link Suspended} annotation is available amongst the method parameters * while the method is annotated with {@link Complete} or {@link Compensate}. * - * @param method method to be checked for async completion - * @return true if method is to complete asynchronously, false if synchronously + * @param method method to be checked for async completion + * @return true if method is to complete asynchronously, false if synchronously */ public static boolean isAsyncCompletion(Method method) { if (method.isAnnotationPresent(Complete.class) || method.isAnnotationPresent(Compensate.class)) { @@ -531,18 +532,18 @@ public static boolean isAsyncCompletion(Method method) { } private static int checkMethod(Map paths, - Method method, String rel, - Path pathAnnotation, - Annotation annotationClass, - String uriPrefix) { - /* - * If the annotationClass is null the requested participant annotation is not present, - * but we also need to check for conformance with the interoperability spec, - * ie look for paths of the form: - * `/compensate` - * `/complete` - * etc - */ + Method method, String rel, + Path pathAnnotation, + Annotation annotationClass, + String uriPrefix) { + /* + * If the annotationClass is null the requested participant annotation is not present, + * but we also need to check for conformance with the interoperability spec, + * ie look for paths of the form: + * `/compensate` + * `/complete` + * etc + */ if (annotationClass == null) { // TODO support standard compenators with: && !pathAnnotation.value().endsWith(rel)) { // ie ones that do not use the @Compensate annotation @@ -586,12 +587,12 @@ public LRAStatus getStatus(URI uri) throws WebApplicationException { try { client = getClient(); response = client.target(coordinatorUrl) - .path(String.format(STATUS_PATH, LRAConstants.getLRAUid(uri))) - .request() - .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) - .async() - .get() - .get(QUERY_TIMEOUT, TimeUnit.SECONDS); + .path(String.format(STATUS_PATH, LRAConstants.getLRAUid(uri))) + .request() + .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) + .async() + .get() + .get(QUERY_TIMEOUT, TimeUnit.SECONDS); // TODO add tests for each of these checks if (response.getStatus() == NOT_FOUND.getStatusCode()) { @@ -642,7 +643,7 @@ private static StringBuilder makeLink(StringBuilder b, String uriPrefix, String } String terminationUri = uriPrefix == null ? value : String.format("%s%s", uriPrefix, value); - Link link = Link.fromUri(terminationUri).title(key + " URI").rel(key).type(MediaType.TEXT_PLAIN).build(); + Link link = Link.fromUri(terminationUri).title(key + " URI").rel(key).type(MediaType.TEXT_PLAIN).build(); if (b.length() != 0) { b.append(','); @@ -652,9 +653,9 @@ private static StringBuilder makeLink(StringBuilder b, String uriPrefix, String } private URI enlistCompensator(URI lraUri, Long timelimit, String uriPrefix, - URI compensateUri, URI completeUri, - URI forgetUri, URI leaveUri, URI afterUri, URI statusUri, - StringBuilder compensatorData) { + URI compensateUri, URI completeUri, + URI forgetUri, URI leaveUri, URI afterUri, URI statusUri, + StringBuilder compensatorData) { validateURI(completeUri, true, "Invalid complete URL: %s"); validateURI(compensateUri, true, "Invalid compensate URL: %s"); validateURI(leaveUri, true, "Invalid status URL: %s"); @@ -712,13 +713,13 @@ public URI enlistCompensator(URI uri, Long timelimit, String linkHeader, StringB headers.add("Link", linkHeader); response = client.target(coordinatorUrl) - .path(LRAConstants.getLRAUid(uri)) - .queryParam(TIMELIMIT_PARAM_NAME, timelimit) - .request() - .headers(headers) - .async() - .put(Entity.text(compensatorData == null ? linkHeader : data)) - .get(JOIN_TIMEOUT, TimeUnit.SECONDS); + .path(LRAConstants.getLRAUid(uri)) + .queryParam(TIMELIMIT_PARAM_NAME, timelimit) + .request() + .headers(headers) + .async() + .put(Entity.text(compensatorData == null ? linkHeader : data)) + .get(JOIN_TIMEOUT, TimeUnit.SECONDS); String responseEntity = response.hasEntity() ? response.readEntity(String.class) : ""; // remove it and create tests for PRECONDITION_FAILED and NOT_FOUND @@ -749,12 +750,13 @@ public URI enlistCompensator(URI uri, Long timelimit, String linkHeader, StringB recoveryUrl = response.getHeaderString(LRA_HTTP_RECOVERY_HEADER); return new URI(recoveryUrl); } catch (URISyntaxException e) { - LRALogger.logger.infof(e,"join %s returned an invalid recovery URI '%s': %s", lraId, recoveryUrl, responseEntity); + LRALogger.logger.infof(e, "join %s returned an invalid recovery URI '%s': %s", lraId, recoveryUrl, + responseEntity); throwGenericLRAException(null, Response.Status.SERVICE_UNAVAILABLE.getStatusCode(), "join " + lraId + " returned an invalid recovery URI '" + recoveryUrl + "' : " + responseEntity, e); return null; } - // don't catch WebApplicationException, just let it propagate + // don't catch WebApplicationException, just let it propagate } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new WebApplicationException(Response.status(SERVICE_UNAVAILABLE) .entity("join LRA client request timed out, try again later").build()); @@ -777,14 +779,14 @@ private void endLRA(URI lra, boolean confirm, String compensator, String userDat String lraUid = LRAConstants.getLRAUid(lra); try { response = client.target(coordinatorUrl) - .path(confirm ? String.format(CLOSE_PATH, lraUid) : String.format(CANCEL_PATH, lraUid)) - .request() - .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) - .header(NARAYANA_LRA_PARTICIPANT_LINK_HEADER_NAME, compensator) - .header(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME, userData) - .async() - .put(Entity.text("")) - .get(END_TIMEOUT, TimeUnit.SECONDS); + .path(confirm ? String.format(CLOSE_PATH, lraUid) : String.format(CANCEL_PATH, lraUid)) + .request() + .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, LRAConstants.CURRENT_API_VERSION_STRING) + .header(NARAYANA_LRA_PARTICIPANT_LINK_HEADER_NAME, compensator) + .header(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME, userData) + .async() + .put(Entity.text("")) + .get(END_TIMEOUT, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new WebApplicationException(Response.status(SERVICE_UNAVAILABLE) .entity("end LRA client request timed out, try again later") @@ -877,7 +879,8 @@ private void lraTracef(URI lra, String reasonFormat, Object... parameters) { public void close() { } - private void throwGenericLRAException(URI lraId, int statusCode, String message, Throwable cause) throws WebApplicationException { + private void throwGenericLRAException(URI lraId, int statusCode, String message, Throwable cause) + throws WebApplicationException { String errorMsg = String.format("%s: %s", lraId, message); throw new WebApplicationException(errorMsg, cause, Response.status(statusCode).entity(errorMsg).build()); } diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/api/Coordinator.java b/coordinator/src/main/java/io/narayana/lra/coordinator/api/Coordinator.java index 085140ab99..0ac7f90a8e 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/api/Coordinator.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/api/Coordinator.java @@ -5,6 +5,27 @@ package io.narayana.lra.coordinator.api; +import static io.narayana.lra.LRAConstants.API_VERSION_1_0; +import static io.narayana.lra.LRAConstants.CLIENT_ID_PARAM_NAME; +import static io.narayana.lra.LRAConstants.COMPENSATE; +import static io.narayana.lra.LRAConstants.COMPLETE; +import static io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME; +import static io.narayana.lra.LRAConstants.CURRENT_API_VERSION_STRING; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; +import static io.narayana.lra.LRAConstants.PARENT_LRA_PARAM_NAME; +import static io.narayana.lra.LRAConstants.PARTICIPANT_TIMEOUT; +import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; +import static io.narayana.lra.LRAConstants.STATUS; +import static io.narayana.lra.LRAConstants.STATUS_PARAM_NAME; +import static io.narayana.lra.LRAConstants.TIMELIMIT_PARAM_NAME; +import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; +import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static jakarta.ws.rs.core.Response.Status.OK; +import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.narayana.lra.Current; @@ -14,9 +35,7 @@ import io.narayana.lra.coordinator.domain.service.LRAService; import io.narayana.lra.coordinator.internal.LRARecoveryModule; import io.narayana.lra.logging.LRALogger; - import jakarta.enterprise.context.ApplicationScoped; - import jakarta.json.Json; import jakarta.json.JsonObject; import jakarta.ws.rs.ApplicationPath; @@ -24,11 +43,11 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.POST; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.PUT; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.ServiceUnavailableException; import jakarta.ws.rs.WebApplicationException; @@ -42,7 +61,6 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriInfo; - import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; @@ -51,7 +69,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; - import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.faulttolerance.Bulkhead; import org.eclipse.microprofile.lra.annotation.LRAStatus; @@ -72,50 +89,16 @@ import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.tags.Tag; -import static io.narayana.lra.LRAConstants.API_VERSION_1_0; -import static io.narayana.lra.LRAConstants.CLIENT_ID_PARAM_NAME; -import static io.narayana.lra.LRAConstants.COMPENSATE; -import static io.narayana.lra.LRAConstants.COMPLETE; -import static io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME; -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; -import static io.narayana.lra.LRAConstants.PARENT_LRA_PARAM_NAME; -import static io.narayana.lra.LRAConstants.PARTICIPANT_TIMEOUT; -import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; -import static io.narayana.lra.LRAConstants.STATUS; -import static io.narayana.lra.LRAConstants.STATUS_PARAM_NAME; -import static io.narayana.lra.LRAConstants.TIMELIMIT_PARAM_NAME; -import static io.narayana.lra.LRAConstants.CURRENT_API_VERSION_STRING; -import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; -import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; -import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; -import static jakarta.ws.rs.core.Response.Status.OK; -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; - @ApplicationScoped @ApplicationPath("/") @Path(COORDINATOR_PATH_NAME) -@OpenAPIDefinition( - info = @Info(title = "LRA Coordinator", version = LRAConstants.CURRENT_API_VERSION_STRING, - contact = @Contact(name = "Narayana", url = "https://narayana.io")), - tags = @Tag(name = "LRA Coordinator"), - components = @Components( - schemas = { - @Schema(name = "LRAApiVersionSchema", - description = "Format is `major.minor`, both components are required, they are to be numbers", - type = SchemaType.STRING, pattern = "^\\d+\\.\\d+$", example = "1.0") - }, - parameters = { - @Parameter(name = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME, in = ParameterIn.HEADER, - description = "Narayana LRA API version", schema = @Schema(ref = "LRAApiVersionSchema")) - }, - headers = { - @Header(name = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME, description = "Narayana LRA API version", - schema = @Schema(ref = "LRAApiVersionSchema")) - } - ) -) +@OpenAPIDefinition(info = @Info(title = "LRA Coordinator", version = LRAConstants.CURRENT_API_VERSION_STRING, contact = @Contact(name = "Narayana", url = "https://narayana.io")), tags = @Tag(name = "LRA Coordinator"), components = @Components(schemas = { + @Schema(name = "LRAApiVersionSchema", description = "Format is `major.minor`, both components are required, they are to be numbers", type = SchemaType.STRING, pattern = "^\\d+\\.\\d+$", example = "1.0") +}, parameters = { + @Parameter(name = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME, in = ParameterIn.HEADER, description = "Narayana LRA API version", schema = @Schema(ref = "LRAApiVersionSchema")) +}, headers = { + @Header(name = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME, description = "Narayana LRA API version", schema = @Schema(ref = "LRAApiVersionSchema")) +})) @Tag(name = "LRA Coordinator", description = "Operations to work with active LRAs (to start, to get a status, to finish, etc.)") public class Coordinator extends Application { @Context @@ -154,24 +137,19 @@ private boolean isAllowParticipantData(String version) { @GET @Path("/") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) @Operation(summary = "Returns all LRAs", description = "Gets both active and recovering LRAs") @APIResponses({ - @APIResponse(responseCode = "200", description = "The LRAData json array which is known to coordinator", - content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = LRAData.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME)}), - @APIResponse(responseCode = "400", description = "Provided Status is not recognized as a valid LRA status value", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME)}), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "The LRAData json array which is known to coordinator", content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = LRAData.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "400", description = "Provided Status is not recognized as a valid LRA status value", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), }) public Response getAllLRAs( - @Parameter(name = STATUS_PARAM_NAME, description = "Filter the returned LRAs to only those in the give state (see CompensatorStatus)") - @QueryParam(STATUS_PARAM_NAME) @DefaultValue("") String state, + @Parameter(name = STATUS_PARAM_NAME, description = "Filter the returned LRAs to only those in the give state (see CompensatorStatus)") @QueryParam(STATUS_PARAM_NAME) @DefaultValue("") String state, @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { LRAStatus requestedLRAStatus = null; if (!state.isEmpty()) { try { @@ -212,25 +190,21 @@ public Response getAllLRAs( @GET @Path("{LraId}/status") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) @Operation(summary = "Obtain the status of an LRA as a string") @APIResponses({ - @APIResponse(responseCode = "200", description = "The LRA exists. The status is reported in the content body.", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "The LRA exists. The status is reported in the content body.", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), }) public Response getLRAStatus( - @Parameter(name = "LraId", description = "The unique identifier of the LRA." + - "Expecting to be a valid URL where the participant can be contacted at. If not in URL format it will be considered " + - "to be an id which will be declared to exist at URL where coordinator is deployed at.", required = true) - @PathParam("LraId")String lraId, - @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { + @Parameter(name = "LraId", description = "The unique identifier of the LRA." + + "Expecting to be a valid URL where the participant can be contacted at. If not in URL format it will be considered " + + + "to be an id which will be declared to exist at URL where coordinator is deployed at.", required = true) @PathParam("LraId") String lraId, + @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { LongRunningAction transaction = lraService.getTransaction(toURI(lraId)); LRAStatus status = transaction.getLRAStatus(); @@ -247,29 +221,24 @@ public Response getLRAStatus( } return Response.ok() - .entity(status.name()) - .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version).build(); + .entity(status.name()) + .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version).build(); } @GET @Path("{LraId}") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) @Operation(summary = "Obtain the information about an LRA as a JSON structure") @APIResponses({ - @APIResponse(responseCode = "200", description = "The LRA exists and the information is packed as JSON in the content body.", - content = @Content(schema = @Schema(implementation = LRAData.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "The LRA exists and the information is packed as JSON in the content body.", content = @Content(schema = @Schema(implementation = LRAData.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), }) public Response getLRAInfo( - @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) - @PathParam("LraId") String lraId, + @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId, @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { URI lraIdURI = toURI(lraId); LRAData lraData = lraService.getLRA(lraIdURI); return Response.status(OK).entity(lraData) @@ -280,16 +249,17 @@ public Response getLRAInfo( * Performing a POST on {@value LRAConstants#COORDINATOR_PATH_NAME}/start?ClientID={ClientID} * will start a new lra with a default timeout and return an LRA URL * of the form {coordinator url}/{@value LRAConstants#COORDINATOR_PATH_NAME}/{LraId}. - * Adding a query parameter, {@value LRAConstants#TIMELIMIT_PARAM_NAME}={timeout}, will start a new lra with the specified timeout. - * If the lra is terminated because of a timeout, the lra URL is deleted and all further invocations on the URL will return 404. + * Adding a query parameter, {@value LRAConstants#TIMELIMIT_PARAM_NAME}={timeout}, will start a new lra with the specified + * timeout. + * If the lra is terminated because of a timeout, the lra URL is deleted and all further invocations on the URL will return + * 404. * The invoker can assume this was equivalent to a compensation operation. */ @POST @Path("start") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) @Bulkhead - @Operation(summary = "Start a new LRA", - description = "The LRA model uses a presumed nothing protocol: the coordinator must communicate " + @Operation(summary = "Start a new LRA", description = "The LRA model uses a presumed nothing protocol: the coordinator must communicate " + "with participants in order to inform them of the LRA activity. Every time a " + "Compensator is enrolled with an LRA, the coordinator must make information about " + "it durable so that the Compensator can be contacted when the LRA terminates, " @@ -297,34 +267,21 @@ public Response getLRAInfo( + "cannot make any presumption about the state of the global transaction without " + "consulting the coordinator and all participants, respectively.") @APIResponses({ - @APIResponse(responseCode = "201", - description = "The request was successful and the response body contains the id of the new LRA", - content = @Content(schema = @Schema(description = "An URI of the new LRA", implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "404", description = "Parent LRA id cannot be joint to the started LRA", - content = @Content(schema = @Schema(description = "Message containing problematic LRA id", implementation = String.class))), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "500", description = "A new LRA could not be started. Coordinator internal error.", - content = @Content(schema = @Schema(implementation = String.class))) + @APIResponse(responseCode = "201", description = "The request was successful and the response body contains the id of the new LRA", content = @Content(schema = @Schema(description = "An URI of the new LRA", implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "404", description = "Parent LRA id cannot be joint to the started LRA", content = @Content(schema = @Schema(description = "Message containing problematic LRA id", implementation = String.class))), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "500", description = "A new LRA could not be started. Coordinator internal error.", content = @Content(schema = @Schema(implementation = String.class))) }) public Response startLRA( - @Parameter(name = CLIENT_ID_PARAM_NAME, - description = "Each client is expected to have a unique identity (which can be a URL).", - required = true) - @QueryParam(CLIENT_ID_PARAM_NAME) @DefaultValue("") String clientId, - @Parameter(name = TIMELIMIT_PARAM_NAME, - description = "Specifies the maximum time in milli seconds that the LRA will exist for.\n" + @Parameter(name = CLIENT_ID_PARAM_NAME, description = "Each client is expected to have a unique identity (which can be a URL).", required = true) @QueryParam(CLIENT_ID_PARAM_NAME) @DefaultValue("") String clientId, + @Parameter(name = TIMELIMIT_PARAM_NAME, description = "Specifies the maximum time in milli seconds that the LRA will exist for.\n" + "If the LRA is terminated because of a timeout, the LRA URL is deleted.\n" + "All further invocations on the URL will return 404.\n" - + "The invoker can assume this was equivalent to a compensate operation.") - @QueryParam(TIMELIMIT_PARAM_NAME) @DefaultValue("0") Long timelimit, - @Parameter(name = PARENT_LRA_PARAM_NAME, - description = "The enclosing LRA if this new LRA is nested") - @QueryParam(PARENT_LRA_PARAM_NAME) @DefaultValue("") String parentLRA, + + "The invoker can assume this was equivalent to a compensate operation.") @QueryParam(TIMELIMIT_PARAM_NAME) @DefaultValue("0") Long timelimit, + @Parameter(name = PARENT_LRA_PARAM_NAME, description = "The enclosing LRA if this new LRA is nested") @QueryParam(PARENT_LRA_PARAM_NAME) @DefaultValue("") String parentLRA, @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { URI parentId = (parentLRA == null || parentLRA.trim().isEmpty()) ? null : toURI(parentLRA); String coordinatorUrl = String.format("%s%s", context.getBaseUri(), COORDINATOR_PATH_NAME); @@ -347,7 +304,8 @@ public Response startLRA( if (response.getStatus() != Response.Status.OK.getStatusCode()) { String errMessage = String.format("The coordinator at %s returned an unexpected response: %d" - + "when the LRA '%s' tried to join the parent LRA '%s'", parentId, response.getStatus(), lraId, parentLRA); + + "when the LRA '%s' tried to join the parent LRA '%s'", parentId, response.getStatus(), + lraId, parentLRA); return Response.status(response.getStatus()).entity(errMessage).build(); } } @@ -384,36 +342,29 @@ public Response startLRA( @PUT @Path("{LraId}/renew") - @Operation(summary = "Update the TimeLimit for an existing LRA", - description = "LRAs can be automatically cancelled if they aren't closed or cancelled before the TimeLimit " + @Operation(summary = "Update the TimeLimit for an existing LRA", description = "LRAs can be automatically cancelled if they aren't closed or cancelled before the TimeLimit " + "specified at creation time is reached. The time limit can be updated.") @APIResponses({ - @APIResponse(responseCode = "200", description = "If the LRA time limit has been updated", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA or " + - "the LRA is not longer active (ie the complete or compensate messages have been sent", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "If the LRA time limit has been updated", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA or " + + "the LRA is not longer active (ie the complete or compensate messages have been sent", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), }) public Response renewTimeLimit( - @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) - @PathParam("LraId") String lraId, - @Parameter(name = TIMELIMIT_PARAM_NAME, description = "The new time limit for the LRA", required = true) - @QueryParam(TIMELIMIT_PARAM_NAME) @DefaultValue("0") Long timeLimit, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { + @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId, + @Parameter(name = TIMELIMIT_PARAM_NAME, description = "The new time limit for the LRA", required = true) @QueryParam(TIMELIMIT_PARAM_NAME) @DefaultValue("0") Long timeLimit, + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) { return Response.status(lraService.renewTimeLimit(toURI(lraId), timeLimit)) - .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version) - .entity(lraId) - .build(); + .header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version) + .entity(lraId) + .build(); } @GET @Path("nested/{NestedLraId}/status") - public Response getNestedLRAStatus(@PathParam("NestedLraId")String nestedLraId) { + public Response getNestedLRAStatus(@PathParam("NestedLraId") String nestedLraId) { if (!lraService.hasTransaction(nestedLraId)) { // it must have compensated return Response.ok(ParticipantStatus.Compensated.name()).build(); @@ -435,13 +386,20 @@ public Response getNestedLRAStatus(@PathParam("NestedLraId")String nestedLraId) private ParticipantStatus mapToParticipantStatus(LRAStatus lraStatus) { switch (lraStatus) { - case Active: return ParticipantStatus.Active; - case Closed: return ParticipantStatus.Completed; - case Cancelled: return ParticipantStatus.Compensated; - case Closing: return ParticipantStatus.Completing; - case Cancelling: return ParticipantStatus.Compensating; - case FailedToClose: return ParticipantStatus.FailedToComplete; - case FailedToCancel: return ParticipantStatus.FailedToCompensate; + case Active: + return ParticipantStatus.Active; + case Closed: + return ParticipantStatus.Completed; + case Cancelled: + return ParticipantStatus.Compensated; + case Closing: + return ParticipantStatus.Completing; + case Cancelling: + return ParticipantStatus.Compensating; + case FailedToClose: + return ParticipantStatus.FailedToComplete; + case FailedToCancel: + return ParticipantStatus.FailedToCompensate; default: // the status has been provided by a nested coordinator which we don't necessarily control // - it's not a client error but a problem with the remote server so we have no other option @@ -495,30 +453,24 @@ public Response forgetNestedLRA(@PathParam("NestedLraId") String nestedLraId) { */ @PUT @Path("{LraId}/close") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) - @Operation(summary = "Attempt to close an LRA", - description = "Trigger the successful completion of the LRA. All" + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) + @Operation(summary = "Attempt to close an LRA", description = "Trigger the successful completion of the LRA. All" + " participants will be dropped by the coordinator." + " The complete message will be sent to the participants." + " Upon termination, the URL is implicitly deleted." + " The invoker cannot know for sure whether the lra completed" + " or compensated without enlisting a participant.") @APIResponses({ - @APIResponse(responseCode = "200", description = "The complete message was sent to all coordinators", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "The complete message was sent to all coordinators", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), }) public Response closeLRA( - @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) - @PathParam("LraId") String lraId, + @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId, @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, @HeaderParam(LRAConstants.NARAYANA_LRA_PARTICIPANT_LINK_HEADER_NAME) @DefaultValue("") String compensator, @HeaderParam(LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) @DefaultValue("") String userData) { @@ -538,30 +490,24 @@ public Response closeLRA( @PUT @Path("{LraId}/cancel") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) - @Operation(summary = "Attempt to cancel an LRA", - description = " Trigger the compensation of the LRA. All" + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) + @Operation(summary = "Attempt to cancel an LRA", description = " Trigger the compensation of the LRA. All" + " participants will be triggered by the coordinator (ie the compensate message will be sent to each participants)." + " Upon termination, the URL is implicitly deleted." + " The invoker cannot know for sure whether the lra completed or compensated without enlisting a participant.") @APIResponses({ - @APIResponse(responseCode = "200", description = "The compensate message was sent to all coordinators", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", - content = @Content(schema = @Schema(implementation = String.class)), - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "The compensate message was sent to all coordinators", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), }) public Response cancelLRA( - @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) - @PathParam("LraId")String lraId, - @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, - @HeaderParam(LRAConstants.NARAYANA_LRA_PARTICIPANT_LINK_HEADER_NAME) @DefaultValue("") String compensator, - @HeaderParam(LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) @DefaultValue("") String userData) { + @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId, + @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, + @HeaderParam(LRAConstants.NARAYANA_LRA_PARTICIPANT_LINK_HEADER_NAME) @DefaultValue("") String compensator, + @HeaderParam(LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) @DefaultValue("") String userData) { LRAData lraData = lraService.endLRA(toURI(lraId), true, false, compensator, userData); @@ -574,54 +520,37 @@ public Response cancelLRA( @PUT @Path("{LraId}") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) @Operation(summary = "A Compensator can join with the LRA at any time prior to the completion of an activity") @APIResponses({ - @APIResponse(responseCode = "200", - description = "The participant was successfully registered with the LRA", - content = @Content(schema = @Schema(description = "A URI representing the recovery id of this join request",implementation = String.class)), - headers = { - @Header(name = LRA_HTTP_RECOVERY_HEADER, description = "It contains a unique resource reference for that participant:\n" - + " - HTTP GET on the reference returns the original participant URL;\n" // Note that isn't a test for this - + " - HTTP PUT on the reference will overwrite the old participant URL with the new one supplied.", - schema = @Schema(implementation = String.class)), - @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "400", description = "Link does not contain all required fields for joining the LRA. " + - "Probably no compensator or after 'rel' is available.", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "412", - description = "The LRA is not longer active (ie the complete or compensate message has been sent), or wrong format of compensator data", - content = @Content(schema = @Schema(implementation = String.class)), - headers = {@Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME)}), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "500", description = "Format of the compensator data (e.g. Link format) could not be processed", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "The participant was successfully registered with the LRA", content = @Content(schema = @Schema(description = "A URI representing the recovery id of this join request", implementation = String.class)), headers = { + @Header(name = LRA_HTTP_RECOVERY_HEADER, description = "It contains a unique resource reference for that participant:\n" + + " - HTTP GET on the reference returns the original participant URL;\n" // Note that isn't a test for this + + " - HTTP PUT on the reference will overwrite the old participant URL with the new one supplied.", schema = @Schema(implementation = String.class)), + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "400", description = "Link does not contain all required fields for joining the LRA. " + + "Probably no compensator or after 'rel' is available.", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "412", description = "The LRA is not longer active (ie the complete or compensate message has been sent), or wrong format of compensator data", content = @Content(schema = @Schema(implementation = String.class)), headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "500", description = "Format of the compensator data (e.g. Link format) could not be processed", content = @Content(schema = @Schema(implementation = String.class))), }) public Response joinLRAViaBody( - @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) - @PathParam("LraId")String lraId, - @Parameter(name = TIMELIMIT_PARAM_NAME, - description = "The time limit in milliseconds that the Compensator can guarantee that it can compensate " + @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId, + @Parameter(name = TIMELIMIT_PARAM_NAME, description = "The time limit in milliseconds that the Compensator can guarantee that it can compensate " + "the work performed by the service. After this time period has elapsed, it may no longer be " + "possible to undo the work within the scope of this (or any enclosing) LRA. It may therefore " + "be necessary for the application or service to start other activities to explicitly try to " + "compensate this work. The application or coordinator may use this information to control the " - + "lifecycle of an LRA.") - @QueryParam(TIMELIMIT_PARAM_NAME) @DefaultValue("0") long timeLimit, - @Parameter(name = "Link", - description = "The resource paths that the coordinator will use to complete or compensate and to request" + + "lifecycle of an LRA.") @QueryParam(TIMELIMIT_PARAM_NAME) @DefaultValue("0") long timeLimit, + @Parameter(name = "Link", description = "The resource paths that the coordinator will use to complete or compensate and to request" + " the status of the participant. The link rel names are" - + " complete, compensate and status.") - @HeaderParam("Link") @DefaultValue("") String compensatorLink, + + " complete, compensate and status.") @HeaderParam("Link") @DefaultValue("") String compensatorLink, @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, @HeaderParam(LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) @DefaultValue("") String userData, - @RequestBody(name = "Compensator data", - description = "A compensator can also register with an LRA by putting the compensator end " + @RequestBody(name = "Compensator data", description = "A compensator can also register with an LRA by putting the compensator end " + "points in the body of request as a link header. This feature is deprecated and undocumented " + "and will be removed in a later version of the protocol") String compensatorURL) { @@ -686,7 +615,6 @@ public Response joinLRAViaBody( return joinLRA(toURI(lraId), mediaType, timeLimit, compensatorURL, null, version); } - private static void makeLink(StringBuilder b, String key, String value) { if (value != null) { @@ -712,7 +640,7 @@ private boolean isLink(String linkString) { } private Response joinLRA(URI lraId, String acceptMediaType, long timeLimit, String linkHeader, - StringBuilder userData, String version) { + StringBuilder userData, String version) { final String recoveryUrlBase = String.format("%s%s/%s", context.getBaseUri().toASCIIString(), COORDINATOR_PATH_NAME, RECOVERY_COORDINATOR_PATH_NAME); @@ -754,32 +682,27 @@ private Response joinLRA(URI lraId, String acceptMediaType, long timeLimit, Stri .build()); } } + /** * A participant can resign from an LRA at any time prior to the completion of an activity by performing a * PUT on {@value LRAConstants#COORDINATOR_PATH_NAME}/{LraId}/remove with the URL of the participant. */ @PUT @Path("{LraId}/remove") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) @Operation(summary = "A Compensator can resign from the LRA at any time prior to the completion of an activity") @APIResponses({ - @APIResponse(responseCode = "200", description = "If the participant was successfully removed from the LRA", - headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), - @APIResponse(responseCode = "400", description = "The coordinator has no knowledge of this participant compensator URL", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", - content = @Content(schema = @Schema(implementation = String.class))), - @APIResponse(responseCode = "412", - description = "The LRA is not longer active (ie in the complete or compensate messages have been sent"), - @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", - content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "200", description = "If the participant was successfully removed from the LRA", headers = { + @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), + @APIResponse(responseCode = "400", description = "The coordinator has no knowledge of this participant compensator URL", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", content = @Content(schema = @Schema(implementation = String.class))), + @APIResponse(responseCode = "412", description = "The LRA is not longer active (ie in the complete or compensate messages have been sent"), + @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))), }) public Response leaveLRA( - @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) - @PathParam("LraId") String lraId, + @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId, @HeaderParam(HttpHeaders.ACCEPT) @DefaultValue(MediaType.TEXT_PLAIN) String mediaType, - @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) - @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, + @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version, String participantCompensatorUrl) { int status = lraService.leave(toURI(lraId), participantCompensatorUrl); diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/api/CoordinatorContainerFilter.java b/coordinator/src/main/java/io/narayana/lra/coordinator/api/CoordinatorContainerFilter.java index 707399f94d..692f8b268e 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/api/CoordinatorContainerFilter.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/api/CoordinatorContainerFilter.java @@ -5,10 +5,13 @@ package io.narayana.lra.coordinator.api; +import static io.narayana.lra.LRAConstants.CURRENT_API_VERSION_STRING; +import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; + import io.narayana.lra.Current; import io.narayana.lra.LRAConstants; import io.narayana.lra.logging.LRALogger; - import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; @@ -21,10 +24,6 @@ import java.net.URI; import java.net.URISyntaxException; -import static io.narayana.lra.LRAConstants.CURRENT_API_VERSION_STRING; -import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; - @Provider public class CoordinatorContainerFilter implements ContainerRequestFilter, ContainerResponseFilter { @@ -64,8 +63,9 @@ public void filter(ContainerRequestContext requestContext, ContainerResponseCont if (!responseContext.getHeaders().containsKey(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME)) { // when app code did not provide version to header to be returned back // then using the api version which came within request; when provided neither then the current version of the api - String responseVersion = requestContext.getHeaders().containsKey(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) ? - requestContext.getHeaderString(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) : CURRENT_API_VERSION_STRING; + String responseVersion = requestContext.getHeaders().containsKey(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) + ? requestContext.getHeaderString(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) + : CURRENT_API_VERSION_STRING; responseContext.getHeaders().putSingle(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME, responseVersion); } diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/api/RecoveryCoordinator.java b/coordinator/src/main/java/io/narayana/lra/coordinator/api/RecoveryCoordinator.java index 35518cb0d6..ee11b3e400 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/api/RecoveryCoordinator.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/api/RecoveryCoordinator.java @@ -5,22 +5,16 @@ package io.narayana.lra.coordinator.api; +import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; +import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; + import io.narayana.lra.LRAData; import io.narayana.lra.coordinator.domain.model.LongRunningAction; import io.narayana.lra.coordinator.domain.service.LRAService; import io.narayana.lra.coordinator.internal.LRARecoveryModule; import io.narayana.lra.logging.LRALogger; -import jakarta.ws.rs.ServiceUnavailableException; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.enums.SchemaType; -import org.eclipse.microprofile.openapi.annotations.media.Content; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - import jakarta.ws.rs.DELETE; import jakarta.ws.rs.GET; import jakarta.ws.rs.NotFoundException; @@ -28,6 +22,7 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.ServiceUnavailableException; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; @@ -36,11 +31,15 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.List; - -import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; -import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; -import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; -import static jakarta.ws.rs.core.Response.Status.PRECONDITION_FAILED; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.enums.SchemaType; +import org.eclipse.microprofile.openapi.annotations.media.Content; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; @Tag(name = "LRA Recovery") public class RecoveryCoordinator { @@ -55,19 +54,14 @@ public RecoveryCoordinator() { @Path("{LRAId}/{RecCoordId}") @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Lookup the participant URL", description = "Performing a GET on the recovery URL " + - "(returned from a join request) will return the original participant URL(s)") + "(returned from a join request) will return the original participant URL(s)") @APIResponses({ - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this participant"), - @APIResponse(responseCode = "200", description = "The participant associated with this recovery id is returned", - content = @Content(schema = @Schema(title = "The original participant URI"))) + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this participant"), + @APIResponse(responseCode = "200", description = "The participant associated with this recovery id is returned", content = @Content(schema = @Schema(title = "The original participant URI"))) }) public String getCompensator( - @Parameter(name = "LRAId", description = "Identifies the LRAId that the participant joined", required = true) - @PathParam("LRAId") String lraId, - @Parameter(name = "RecCoordId", - description = "An identifier that was returned by the coordinator when a participant joined the LRA", - required = true) - @PathParam("RecCoordId") String rcvCoordId, + @Parameter(name = "LRAId", description = "Identifies the LRAId that the participant joined", required = true) @PathParam("LRAId") String lraId, + @Parameter(name = "RecCoordId", description = "An identifier that was returned by the coordinator when a participant joined the LRA", required = true) @PathParam("RecCoordId") String rcvCoordId, @Context UriInfo uriInfo) throws NotFoundException { String context = uriInfo.getRequestUri().toASCIIString(); @@ -89,23 +83,17 @@ public String getCompensator( @PUT @Path("{LRAId}/{RecCoordId}") @Produces(MediaType.APPLICATION_JSON) - @Operation(summary = "Update the endpoint that a participant is prepared to accept requests on.", - description = "Performing a PUT on the recovery URL will overwrite the old with the new one supplied" + + @Operation(summary = "Update the endpoint that a participant is prepared to accept requests on.", description = "Performing a PUT on the recovery URL will overwrite the old with the new one supplied" + + " and return the old url. The old value is returned." + "The full URL was returned when the participant first joined the LRA.") @APIResponses({ - @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this participant"), - @APIResponse(responseCode = "200", description = "The coordinator has replaced the old participant with the new one") + @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this participant"), + @APIResponse(responseCode = "200", description = "The coordinator has replaced the old participant with the new one") }) public String replaceCompensator( - @Parameter(name = "LRAId", - description = "Identifies the LRAId that the participant joined", - required = true) - @PathParam("LRAId") String lraId, - @Parameter(name = "RecCoordId", - description = "An identifier that was returned by the coordinator when a participant joined the LRA", - required = true) - @PathParam("RecCoordId") String rcvCoordId, + @Parameter(name = "LRAId", description = "Identifies the LRAId that the participant joined", required = true) @PathParam("LRAId") String lraId, + @Parameter(name = "RecCoordId", description = "An identifier that was returned by the coordinator when a participant joined the LRA", required = true) @PathParam("RecCoordId") String rcvCoordId, @Context UriInfo uriInfo, String newCompensatorUrl) throws NotFoundException { String context = uriInfo.getRequestUri().toASCIIString(); @@ -141,10 +129,8 @@ public String replaceCompensator( @GET @Produces(MediaType.APPLICATION_JSON) - @Operation(summary = "List recovering Long Running Actions", - description = "Returns LRAs that are recovering (ie some participants still need to be ran)") - @APIResponse(responseCode = "200", - content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = LRAData.class))) + @Operation(summary = "List recovering Long Running Actions", description = "Returns LRAs that are recovering (ie some participants still need to be ran)") + @APIResponse(responseCode = "200", content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = LRAData.class))) public List getRecoveringLRAs() { return lraService.getAllRecovering(true); } @@ -152,12 +138,10 @@ public List getRecoveringLRAs() { @GET @Path("failed") @Produces(MediaType.APPLICATION_JSON) - @Operation(summary = "List failed Long Running Actions", - description = "Returns LRAs that have failed. " + - " Failure records are vital pieces of data needed to aid failure tracking and analysis " + - " and are retained for inspection.") - @APIResponse(responseCode = "200", - content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = LRAData.class))) + @Operation(summary = "List failed Long Running Actions", description = "Returns LRAs that have failed. " + + " Failure records are vital pieces of data needed to aid failure tracking and analysis " + + " and are retained for inspection.") + @APIResponse(responseCode = "200", content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = LRAData.class))) public List getFailedLRAs() { return lraService.getFailedLRAs(); } @@ -166,21 +150,19 @@ public List getFailedLRAs() { @Path("{LraId}") @Operation(summary = "Remove the log for a failed LRA") @APIResponses({ - @APIResponse(responseCode = "204", - description = "If the LRA log was successfully removed"), - @APIResponse(responseCode = "412", - description = "If the LRA is not in an end state (in which case the response " + - "entity will indicate the current state at the time of the request)"), - @APIResponse(responseCode = "412", - description = "If the input LRA does not correspond to a valid URI (in which case the " + - "response entity will contain the error message)"), - @APIResponse(responseCode = "500", - description = "If the attempt to remove the LRA log failed. This return code does not " + - "discriminate between a failure at the log storage level or if the log did not exist)") + @APIResponse(responseCode = "204", description = "If the LRA log was successfully removed"), + @APIResponse(responseCode = "412", description = "If the LRA is not in an end state (in which case the response " + + "entity will indicate the current state at the time of the request)"), + @APIResponse(responseCode = "412", description = "If the input LRA does not correspond to a valid URI (in which case the " + + + "response entity will contain the error message)"), + @APIResponse(responseCode = "500", description = "If the attempt to remove the LRA log failed. This return code does not " + + + "discriminate between a failure at the log storage level or if the log did not exist)") }) public Response deleteFailedLRA( - @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) - @PathParam("LraId")String lraId) throws NotFoundException { + @Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId) + throws NotFoundException { URI lra; try { diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParentAbstractRecord.java b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParentAbstractRecord.java index 87287cada9..834d4a6bda 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParentAbstractRecord.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParentAbstractRecord.java @@ -15,7 +15,6 @@ import io.narayana.lra.coordinator.domain.service.LRAService; import io.narayana.lra.coordinator.internal.LRARecoveryModule; import io.narayana.lra.logging.LRALogger; - import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -215,4 +214,4 @@ public boolean shouldMerge(AbstractRecord a) { public boolean shouldReplace(AbstractRecord a) { return false; } -} \ No newline at end of file +} diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParticipantRecord.java b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParticipantRecord.java index 142328381a..bb42c38fde 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParticipantRecord.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LRAParticipantRecord.java @@ -5,23 +5,25 @@ package io.narayana.lra.coordinator.domain.model; +import static io.narayana.lra.LRAConstants.AFTER; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; +import static io.narayana.lra.LRAConstants.PARTICIPANT_TIMEOUT; +import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; + import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.arjuna.coordinator.AbstractRecord; import com.arjuna.ats.arjuna.coordinator.RecordType; import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome; import com.arjuna.ats.arjuna.state.InputObjectState; import com.arjuna.ats.arjuna.state.OutputObjectState; - import io.narayana.lra.Current; import io.narayana.lra.LRAConstants; import io.narayana.lra.LRAData; import io.narayana.lra.coordinator.domain.service.LRAService; import io.narayana.lra.logging.LRALogger; -import jakarta.ws.rs.core.HttpHeaders; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; - import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.client.AsyncInvoker; import jakarta.ws.rs.client.Client; @@ -29,6 +31,7 @@ import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation; import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.Link; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -46,14 +49,9 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; - -import static io.narayana.lra.LRAConstants.AFTER; -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; -import static io.narayana.lra.LRAConstants.PARTICIPANT_TIMEOUT; -import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; public class LRAParticipantRecord extends AbstractRecord implements Comparable { private static final String TYPE_NAME = "/StateManager/AbstractRecord/LRARecord"; @@ -90,7 +88,7 @@ public LRAParticipantRecord() { try { // if compensateURI is a link parse it into compensate,complete and status urls if (linkURI.startsWith("<")) { - Exception[] parseException = {null}; + Exception[] parseException = { null }; Arrays.stream(linkURI.split(",")).forEach((linkStr) -> { Exception e = parseLink(linkStr); @@ -100,7 +98,8 @@ public LRAParticipantRecord() { }); if (parseException[0] != null) { - String errorMsg = LRALogger.i18nLogger.error_invalidCompensator(lra.getId(), parseException[0].getMessage(), linkURI); + String errorMsg = LRALogger.i18nLogger.error_invalidCompensator(lra.getId(), parseException[0].getMessage(), + linkURI); LRALogger.logger.error(errorMsg); if (LRALogger.logger.isTraceEnabled()) { trace_progress(errorMsg); @@ -140,7 +139,8 @@ public LRAParticipantRecord() { trace_progress("created"); } } catch (URISyntaxException e) { - String logMsg = LRALogger.i18nLogger.error_invalidFormatToCreateLRAParticipantRecord(lraId.toASCIIString(), linkURI, e.getMessage()); + String logMsg = LRALogger.i18nLogger.error_invalidFormatToCreateLRAParticipantRecord(lraId.toASCIIString(), linkURI, + e.getMessage()); LRALogger.logger.error(logMsg); if (LRALogger.logger.isTraceEnabled()) { trace_progress(logMsg); @@ -286,7 +286,8 @@ private int tryDoEnd(boolean compensate) { if (isFinished()) { return atEnd(status == ParticipantStatus.FailedToComplete || status == ParticipantStatus.FailedToCompensate - ? TwoPhaseOutcome.FINISH_ERROR : TwoPhaseOutcome.FINISH_OK); + ? TwoPhaseOutcome.FINISH_ERROR + : TwoPhaseOutcome.FINISH_OK); } if (ParticipantStatus.Compensating.equals(status)) { @@ -311,7 +312,7 @@ private int tryDoEnd(boolean compensate) { return atEnd(TwoPhaseOutcome.FINISH_OK); // the participant has already completed } - endPath = completeURI; // we are going to ask the participant to complete + endPath = completeURI; // we are going to ask the participant to complete status = ParticipantStatus.Completing; } @@ -442,7 +443,6 @@ boolean isFinished() { } } - boolean isFailed() { return status == ParticipantStatus.FailedToCompensate || status == ParticipantStatus.FailedToComplete; } @@ -592,7 +592,8 @@ private int retryGetEndStatus(URI endPath, boolean compensate) { } if (cStatus == null) { - LRALogger.logger.warnf("LRAParticipantRecord.retryGetEndStatus: local LRA %s accepted but has a null status", + LRALogger.logger.warnf( + "LRAParticipantRecord.retryGetEndStatus: local LRA %s accepted but has a null status", endPath); return -1; // shouldn't happen since it imples it's still be active - force end to be called } @@ -776,7 +777,7 @@ private int tryLocalEndInvocation(URI endPath) { if (!isCompensate && !isComplete) { if (LRALogger.logger.isInfoEnabled()) { LRALogger.logger.infof("LRAParticipantRecord.doEnd invalid nested participant url %s" + - "(should be compensate or complete)", + "(should be compensate or complete)", endPath); } @@ -802,14 +803,14 @@ boolean forget() { try { client = ClientBuilder.newClient(); Response response = client.target(forgetURI)//.path(getLRAId(lraId)) - .request() - .header(LRA_HTTP_CONTEXT_HEADER, lraId) - .header(LRA_HTTP_RECOVERY_HEADER, recoveryURI) - .header(LRA_HTTP_PARENT_CONTEXT_HEADER, parentId) - .header(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME, compensatorData) - .async() - .delete() - .get(PARTICIPANT_TIMEOUT, TimeUnit.SECONDS); + .request() + .header(LRA_HTTP_CONTEXT_HEADER, lraId) + .header(LRA_HTTP_RECOVERY_HEADER, recoveryURI) + .header(LRA_HTTP_PARENT_CONTEXT_HEADER, parentId) + .header(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME, compensatorData) + .async() + .delete() + .get(PARTICIPANT_TIMEOUT, TimeUnit.SECONDS); if (response.getStatus() == Response.Status.OK.getStatusCode()) { forgetURI = null; // succeeded so dispose of the endpoint @@ -822,7 +823,7 @@ boolean forget() { exception = (WebApplicationException) cause; } LRALogger.logger.infof("LRAParticipantRecord.forget delete %s failed for LRA %s (reason %s)", - forgetURI, lraId, exception.getMessage()); + forgetURI, lraId, exception.getMessage()); return false; // force recovery to keep retrying } finally { if (LRALogger.logger.isTraceEnabled()) { @@ -836,8 +837,8 @@ boolean forget() { } else { LRALogger.logger.warnf( - "LRAParticipantRecord.forget() LRA: %s: cannot forget %s: missing forget URI, status: %s", - lraId, recoveryURI, status); + "LRAParticipantRecord.forget() LRA: %s: cannot forget %s: missing forget URI, status: %s", + lraId, recoveryURI, status); } return true; @@ -1083,4 +1084,4 @@ private void trace_progress(String reason) { status, accepted); } -} \ No newline at end of file +} diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LongRunningAction.java b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LongRunningAction.java index a16f356c0f..5826eab48a 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LongRunningAction.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/model/LongRunningAction.java @@ -5,6 +5,8 @@ package io.narayana.lra.coordinator.domain.model; +import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; + import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.arjuna.coordinator.AbstractRecord; import com.arjuna.ats.arjuna.coordinator.ActionStatus; @@ -15,19 +17,14 @@ import com.arjuna.ats.arjuna.coordinator.RecordType; import com.arjuna.ats.arjuna.state.InputObjectState; import com.arjuna.ats.arjuna.state.OutputObjectState; - import io.narayana.lra.Current; import io.narayana.lra.LRAConstants; import io.narayana.lra.LRAData; -import io.narayana.lra.logging.LRALogger; import io.narayana.lra.coordinator.domain.service.LRAService; - -import org.eclipse.microprofile.lra.annotation.LRAStatus; - -import jakarta.ws.rs.core.Response; +import io.narayana.lra.logging.LRALogger; import jakarta.ws.rs.ServiceUnavailableException; import jakarta.ws.rs.WebApplicationException; - +import jakarta.ws.rs.core.Response; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -46,8 +43,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; - -import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import org.eclipse.microprofile.lra.annotation.LRAStatus; public class LongRunningAction extends BasicAction { private static final String LRA_TYPE = "/StateManager/BasicAction/LongRunningAction"; @@ -64,7 +60,8 @@ public class LongRunningAction extends BasicAction { private final LRAService lraService; LRAParentAbstractRecord par; - public LongRunningAction(LRAService lraService, String baseUrl, LongRunningAction parent, String clientId) throws URISyntaxException { + public LongRunningAction(LRAService lraService, String baseUrl, LongRunningAction parent, String clientId) + throws URISyntaxException { super(new Uid()); if (lraService == null) { @@ -126,7 +123,7 @@ public LongRunningAction(Uid rcvUid) { * Creating {@link LRAData} from the current {@link LongRunningAction} state. * The data are immutable and represents the current state of the LRA transaction. * - * @return immutable {@link LRAData} representing the current state of the LRA transaction + * @return immutable {@link LRAData} representing the current state of the LRA transaction */ public LRAData getLRAData() { return new LRAData(id, clientId, status, isTopLevel(), isRecovering(), @@ -301,8 +298,10 @@ public boolean restore_state(InputObjectState os, int ot) { } } clientId = os.unpackString(); - startTime = os.unpackBoolean() ? LocalDateTime.ofInstant(Instant.ofEpochMilli(os.unpackLong()), ZoneOffset.UTC) : null; - finishTime = os.unpackBoolean() ? LocalDateTime.ofInstant(Instant.ofEpochMilli(os.unpackLong()), ZoneOffset.UTC) : null; + startTime = os.unpackBoolean() ? LocalDateTime.ofInstant(Instant.ofEpochMilli(os.unpackLong()), ZoneOffset.UTC) + : null; + finishTime = os.unpackBoolean() ? LocalDateTime.ofInstant(Instant.ofEpochMilli(os.unpackLong()), ZoneOffset.UTC) + : null; status = LRAStatus.valueOf(os.unpackString()); /* @@ -779,15 +778,14 @@ protected LRAStatus toLRAStatus(int atomicActionStatus) { } public LRAParticipantRecord enlistParticipant(URI coordinatorUrl, String participantUrl, String recoveryUrlBase, - long timeLimit, String compensatorData, String version) + long timeLimit, String compensatorData, String version) throws UnsupportedEncodingException { ReentrantLock lock = tryLockTransaction(); if (lock == null) { String reason = LRALogger.i18nLogger.warn_enlistment(); LRALogger.logger.warn(reason); throw new ServiceUnavailableException(reason); - } - else { + } else { try { LRAParticipantRecord participant = findLRAParticipant(participantUrl, false); if (participant != null) { @@ -807,8 +805,7 @@ public LRAParticipantRecord enlistParticipant(URI coordinatorUrl, String partici throw new ServiceUnavailableException(LRALogger.i18nLogger.warn_saveState(DEACTIVATE_REASON)); } return participant; - } - finally { + } finally { lock.unlock(); } } @@ -816,7 +813,7 @@ public LRAParticipantRecord enlistParticipant(URI coordinatorUrl, String partici } private LRAParticipantRecord doEnlistParticipant(URI coordinatorUrl, String participantUrl, String recoveryUrlBase, - long timeLimit, String compensatorData, String version) { + long timeLimit, String compensatorData, String version) { LRAParticipantRecord p = new LRAParticipantRecord(this, lraService, participantUrl, compensatorData); String pid = p.get_uid().fileStringForm(); @@ -848,8 +845,8 @@ private LRAParticipantRecord doEnlistParticipant(URI coordinatorUrl, String part if (isFinished()) { throw new WebApplicationException(Response.status(Response.Status.GONE) - .entity(LRALogger.i18nLogger.error_tooLateToJoin(id.toASCIIString(), "finished")) - .build()); + .entity(LRALogger.i18nLogger.error_tooLateToJoin(id.toASCIIString(), "finished")) + .build()); } if (add(p) != AddOutcome.AR_REJECTED) { @@ -945,7 +942,7 @@ private LRAParticipantRecord findLRAParticipant(String participantUrl, boolean r return rec; } - private LRAParticipantRecord findLRAParticipant(String participantUrl, boolean remove, RecordList...lists) { + private LRAParticipantRecord findLRAParticipant(String participantUrl, boolean remove, RecordList... lists) { for (RecordList list : lists) { if (list != null) { RecordListIterator i = new RecordListIterator(list); @@ -978,7 +975,7 @@ private LRAParticipantRecord findLRAParticipant(String participantUrl, boolean r return null; } - private LRAParticipantRecord findLRAParticipantByRecoveryUrl(URI recoveryUrl, boolean remove, RecordList...lists) { + private LRAParticipantRecord findLRAParticipantByRecoveryUrl(URI recoveryUrl, boolean remove, RecordList... lists) { for (RecordList list : lists) { if (list != null) { RecordListIterator i = new RecordListIterator(list); @@ -1123,8 +1120,7 @@ private int scheduleCancellation(Runnable runnable, Long timeLimit, boolean save Long nanosToAdd = timeLimit; try { nanosToAdd = Math.multiplyExact(timeLimit, 1000000); - } - catch (ArithmeticException e) { + } catch (ArithmeticException e) { LRALogger.logger.warn( LRALogger.i18nLogger.warn_timelimit_too_long(timeLimit, Long.MAX_VALUE)); nanosToAdd = Long.MAX_VALUE; @@ -1246,6 +1242,7 @@ private boolean hasElements(RecordList list) { /** * Checks whether the LRA has finished and whether all the post LRA actions are complete + * * @return true if all post LRA actions are complete */ public boolean hasPendingActions() { @@ -1283,4 +1280,4 @@ private void trace_progress(String reason) { startTime, finishTime); } -} \ No newline at end of file +} diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/service/LRAService.java b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/service/LRAService.java index d28b1219ef..875f5e35d8 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/domain/service/LRAService.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/domain/service/LRAService.java @@ -5,20 +5,21 @@ package io.narayana.lra.coordinator.domain.service; +import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import static jakarta.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE; +import static java.util.stream.Collectors.toList; + import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.arjuna.coordinator.ActionStatus; import com.arjuna.ats.arjuna.coordinator.BasicAction; +import com.arjuna.ats.arjuna.recovery.RecoveryManager; import io.narayana.lra.LRAConstants; import io.narayana.lra.LRAData; -import io.narayana.lra.logging.LRALogger; -import com.arjuna.ats.arjuna.recovery.RecoveryManager; - import io.narayana.lra.coordinator.domain.model.LRAParticipantRecord; -import io.narayana.lra.coordinator.internal.LRARecoveryModule; import io.narayana.lra.coordinator.domain.model.LongRunningAction; - -import org.eclipse.microprofile.lra.annotation.LRAStatus; - +import io.narayana.lra.coordinator.internal.LRARecoveryModule; +import io.narayana.lra.logging.LRALogger; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; @@ -31,11 +32,7 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Matcher; import java.util.regex.Pattern; - -import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; -import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; -import static jakarta.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE; -import static java.util.stream.Collectors.toList; +import org.eclipse.microprofile.lra.annotation.LRAStatus; public class LRAService { private static final Pattern LINK_REL_PATTERN = Pattern.compile("(\\w+)=\"([^\"]+)\"|([^\\s]+)"); @@ -131,9 +128,9 @@ public List getAll(LRAStatus lraStatus) { * Getting all the LRA managed by recovery manager. This means all LRAs which are not mapped * only in memory but that were already saved in object store. * - * @param scan defines if there is run recovery manager scanning before returning the collection, - * when the recovery is run then the object store is touched and the returned - * list may be updated with the new loaded objects + * @param scan defines if there is run recovery manager scanning before returning the collection, + * when the recovery is run then the object store is touched and the returned + * list may be updated with the new loaded objects * @return list of the {@link LRAData} which define the recovering LRAs */ public List getAllRecovering(boolean scan) { @@ -171,6 +168,7 @@ public void finished(LongRunningAction transaction, boolean fromHierarchy) { /** * Remove a log corresponding to an LRA record + * * @param lraId the id of the LRA * @return true if the record was either removed or was not present */ @@ -261,8 +259,8 @@ public synchronized LongRunningAction startLRA(String baseUri, URI parentLRA, St } catch (URISyntaxException e) { throw new WebApplicationException(e.getMessage(), Response.status(Response.Status.PRECONDITION_FAILED) - .entity(String.format("Invalid base URI: '%s'", baseUri)) - .build()); + .entity(String.format("Invalid base URI: '%s'", baseUri)) + .build()); } status = lra.begin(timelimit); @@ -294,7 +292,7 @@ public LRAData endLRA(URI lraId, boolean compensate, boolean fromHierarchy) { return endLRA(lraId, compensate, fromHierarchy, null, null); } - public LRAData endLRA(URI lraId, boolean compensate, boolean fromHierarchy, String compensator, String userData) { + public LRAData endLRA(URI lraId, boolean compensate, boolean fromHierarchy, String compensator, String userData) { lraTrace(lraId, "end LRA"); LongRunningAction transaction = getTransaction(lraId); @@ -339,22 +337,24 @@ public int leave(URI lraId, String compensatorUrl) { if (wasForgotten) { return Response.Status.OK.getStatusCode(); } else { - String errorMsg = String.format("LRAService.forget %s failed as the participant was not found, compensator url '%s'", + String errorMsg = String.format( + "LRAService.forget %s failed as the participant was not found, compensator url '%s'", lraId, compensatorUrl); throw new WebApplicationException(errorMsg, Response.status(Response.Status.BAD_REQUEST) .entity(errorMsg).build()); } } + public int joinLRA(StringBuilder recoveryUrl, URI lra, long timeLimit, - String compensatorUrl, String linkHeader, String recoveryUrlBase, - StringBuilder compensatorData) { - return joinLRA(recoveryUrl, lra,timeLimit, compensatorUrl, linkHeader, recoveryUrlBase, compensatorData, null); + String compensatorUrl, String linkHeader, String recoveryUrlBase, + StringBuilder compensatorData) { + return joinLRA(recoveryUrl, lra, timeLimit, compensatorUrl, linkHeader, recoveryUrlBase, compensatorData, null); } public int joinLRA(StringBuilder recoveryUrl, URI lra, long timeLimit, - String compensatorUrl, String linkHeader, String recoveryUrlBase, - StringBuilder compensatorData, String version) { - if (lra == null) { + String compensatorUrl, String linkHeader, String recoveryUrlBase, + StringBuilder compensatorData, String version) { + if (lra == null) { lraTrace(null, "Error missing LRA header in join request"); } else { lraTrace(lra, "join LRA"); @@ -487,4 +487,4 @@ private List getDataByStatus(Map lrasToFilter, return lrasToFilter.values().stream().filter(t -> t.getLRAStatus() == status) .map(LongRunningAction::getLRAData).collect(toList()); } -} \ No newline at end of file +} diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/internal/LRARecoveryModule.java b/coordinator/src/main/java/io/narayana/lra/coordinator/internal/LRARecoveryModule.java index 594efa0748..a94de2a638 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/internal/LRARecoveryModule.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/internal/LRARecoveryModule.java @@ -8,26 +8,25 @@ import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.arjuna.common.recoveryPropertyManager; import com.arjuna.ats.arjuna.exceptions.ObjectStoreException; -import com.arjuna.ats.arjuna.recovery.RecoveryManager; -import io.narayana.lra.logging.LRALogger; import com.arjuna.ats.arjuna.objectstore.RecoveryStore; import com.arjuna.ats.arjuna.objectstore.StateStatus; import com.arjuna.ats.arjuna.objectstore.StoreManager; +import com.arjuna.ats.arjuna.recovery.RecoveryManager; import com.arjuna.ats.arjuna.recovery.RecoveryModule; import com.arjuna.ats.arjuna.recovery.TransactionStatusConnectionManager; import com.arjuna.ats.arjuna.state.InputObjectState; import com.arjuna.ats.arjuna.state.OutputObjectState; -import io.narayana.lra.coordinator.domain.model.LongRunningAction; import io.narayana.lra.coordinator.domain.model.FailedLongRunningAction; +import io.narayana.lra.coordinator.domain.model.LongRunningAction; import io.narayana.lra.coordinator.domain.service.LRAService; -import org.eclipse.microprofile.lra.annotation.LRAStatus; - +import io.narayana.lra.logging.LRALogger; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.function.Consumer; +import org.eclipse.microprofile.lra.annotation.LRAStatus; public class LRARecoveryModule implements RecoveryModule { public LRARecoveryModule() { @@ -93,7 +92,7 @@ public void periodicWorkSecondPass() { } private synchronized void recoverTransactions() { - // uids per transaction type + // uids per transaction type InputObjectState aa_uids = new InputObjectState(); if (getUids(_transactionType, aa_uids)) { @@ -143,7 +142,7 @@ private void doRecoverTransaction(Uid recoverUid) { } } - public boolean moveEntryToFailedLRAPath (final Uid failedUid) { + public boolean moveEntryToFailedLRAPath(final Uid failedUid) { String failedLRAType = FailedLongRunningAction.FAILED_LRA_TYPE; boolean moved = false; try { @@ -164,7 +163,8 @@ public boolean moveEntryToFailedLRAPath (final Uid failedUid) { if (_recoveryStore.write_committed(failedUid, failedLRAType, new OutputObjectState(inputState))) { moved = _recoveryStore.remove_committed(failedUid, _transactionType); if (moved) { - LRALogger.logger.infof("Failed lra record (Uid: %s) moved to new location type: %s", failedUid, failedLRAType); + LRALogger.logger.infof("Failed lra record (Uid: %s) moved to new location type: %s", failedUid, + failedLRAType); } } } @@ -325,4 +325,4 @@ private void forEach(InputObjectState uids, Consumer consumer, final String private final TransactionStatusConnectionManager _transactionStatusConnectionMgr; private static LRARecoveryModule lraRecoveryModule; -} \ No newline at end of file +} diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/internal/RecoveringLRA.java b/coordinator/src/main/java/io/narayana/lra/coordinator/internal/RecoveringLRA.java index 2174a6e68b..bb46a1ddaa 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/internal/RecoveringLRA.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/internal/RecoveringLRA.java @@ -7,13 +7,12 @@ import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.arjuna.coordinator.ActionStatus; -import io.narayana.lra.logging.LRALogger; import io.narayana.lra.coordinator.domain.model.LongRunningAction; import io.narayana.lra.coordinator.domain.service.LRAService; +import io.narayana.lra.logging.LRALogger; import jakarta.ws.rs.ServiceUnavailableException; -import org.eclipse.microprofile.lra.annotation.LRAStatus; - import java.util.concurrent.locks.ReentrantLock; +import org.eclipse.microprofile.lra.annotation.LRAStatus; class RecoveringLRA extends LongRunningAction { /** @@ -115,4 +114,4 @@ private void tryReplayPhase2() { // Flag to indicate that this transaction has been re-activated successfully. private boolean _activated = false; -} \ No newline at end of file +} diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/management/BrowserCommand.java b/coordinator/src/main/java/io/narayana/lra/coordinator/management/BrowserCommand.java index 7c65960ddb..387c0bc931 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/management/BrowserCommand.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/management/BrowserCommand.java @@ -21,18 +21,6 @@ import io.narayana.lra.coordinator.internal.Implementations; import io.narayana.lra.coordinator.internal.LRARecoveryModule; import io.narayana.lra.coordinator.tools.osb.mbean.LRAActionBean; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.InstanceNotFoundException; -import javax.management.IntrospectionException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectInstance; -import javax.management.ObjectName; -import javax.management.ReflectionException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -46,6 +34,17 @@ import java.util.List; import java.util.Scanner; import java.util.Set; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.ReflectionException; /* * Browser for viewing LRA MBeans: @@ -68,12 +67,12 @@ public abstract class BrowserCommand { private static String[][] LRA_OSB_TYPES = { // osTypeClassName, beanTypeClassName - see com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBrowser - {LongRunningAction.getType().substring(1), + { LongRunningAction.getType().substring(1), LongRunningAction.class.getName(), - LRAActionBean.class.getName()}, - {FailedLongRunningAction.getType().substring(1), + LRAActionBean.class.getName() }, + { FailedLongRunningAction.getType().substring(1), FailedLongRunningAction.class.getName(), - LRAActionBean.class.getName()} + LRAActionBean.class.getName() } }; private enum CommandName { @@ -186,7 +185,7 @@ public static void main(String[] args) throws Exception { public static String run(String[] args) throws Exception { try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - PrintStream printStream = new PrintStream(outputStream)) { + PrintStream printStream = new PrintStream(outputStream)) { parseArgs(args); @@ -225,7 +224,7 @@ private static void setupStore(String storeDir) throws Exception { recoveryManager.addModule(new LRARecoveryModule()); osb = ObjStoreBrowser.getInstance(); - for(String[] typeAndBean: LRA_OSB_TYPES) { + for (String[] typeAndBean : LRA_OSB_TYPES) { osb.addType(typeAndBean[0], typeAndBean[1], typeAndBean[2]); } osb.start(); @@ -233,10 +232,9 @@ private static void setupStore(String storeDir) throws Exception { private static void setupStore(String storeDir, boolean hqstore) throws Exception { String storePath = new File(storeDir).getCanonicalPath(); - ObjectStoreEnvironmentBean commsObjStoreCommsEnvBean = - BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore"); - ObjectStoreEnvironmentBean defObjStoreCommsEnvBean = - BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class); + ObjectStoreEnvironmentBean commsObjStoreCommsEnvBean = BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, + "communicationStore"); + ObjectStoreEnvironmentBean defObjStoreCommsEnvBean = BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class); if (hqstore) { File hornetqStoreDir = new File(storeDir); @@ -310,9 +308,9 @@ void execute(PrintStream printStream, List args) throws Exception { RecoveryManager.manager().terminate(false); } catch (Throwable ignore) { } - } + } - boolean cancel() { + boolean cancel() { finished = true; try { cmdSource.close(); @@ -324,7 +322,7 @@ boolean cancel() { private void processCommand(PrintStream printStream, Scanner scanner) { printStream.printf("%s> ", currentType); - List args = new ArrayList (Arrays.asList(scanner.nextLine().split("\\s+"))); + List args = new ArrayList(Arrays.asList(scanner.nextLine().split("\\s+"))); BrowserCommand command = args.size() == 0 ? getCommand(CommandName.HELP) : getCommand(args.remove(0)); try { @@ -355,7 +353,7 @@ void execute(PrintStream printStream, List args) throws Exception { printStream.print(currentStoreDir); else printStream.printf("not supported - please restart and use the \"-s\" option (%s)", SYNTAX); -// restartStore(args.get(0)); + // restartStore(args.get(0)); } }, @@ -430,7 +428,8 @@ void execute(PrintStream printStream, List args) throws Exception { } } - void listMBeans(PrintStream printStream, String itype) throws MalformedObjectNameException, ReflectionException, InstanceNotFoundException, IntrospectionException { + void listMBeans(PrintStream printStream, String itype) throws MalformedObjectNameException, ReflectionException, + InstanceNotFoundException, IntrospectionException { MBeanServer mbs = JMXServer.getAgent().getServer(); String osMBeanName = "jboss.jta:type=ObjectStore,itype=" + itype; //Set allTransactions = mbs.queryMBeans(new ObjectName("jboss.jta:type=ObjectStore,*"), null); @@ -442,7 +441,7 @@ void listMBeans(PrintStream printStream, String itype) throws MalformedObjectNam if (!transactionId.contains("puid") && transactionId.contains("itype")) { printStream.printf("Transaction: %s%n", oi.getObjectName()); - String participantQuery = transactionId + ",puid=*"; + String participantQuery = transactionId + ",puid=*"; Set participants = mbs.queryMBeans(new ObjectName(participantQuery), null); printAtrributes(printStream, "\t", mbs, oi); @@ -458,7 +457,7 @@ void listMBeans(PrintStream printStream, String itype) throws MalformedObjectNam void printAtrributes(PrintStream printStream, String printPrefix, MBeanServer mbs, ObjectInstance oi) throws IntrospectionException, InstanceNotFoundException, ReflectionException { - MBeanInfo info = mbs.getMBeanInfo( oi.getObjectName() ); + MBeanInfo info = mbs.getMBeanInfo(oi.getObjectName()); MBeanAttributeInfo[] attributeArray = info.getAttributes(); int i = 0; String[] attributeNames = new String[attributeArray.length]; @@ -470,7 +469,7 @@ void printAtrributes(PrintStream printStream, String printPrefix, MBeanServer mb for (Attribute attribute : attributes.asList()) { Object value = attribute.getValue(); - String v = value == null ? "null" : value.toString(); + String v = value == null ? "null" : value.toString(); printStream.printf("%s%s=%s%n", printPrefix, attribute.getName(), v); } diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBean.java b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBean.java index 8add915d27..4e3a0420ed 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBean.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBean.java @@ -10,7 +10,6 @@ import com.arjuna.ats.arjuna.tools.osb.mbean.ParticipantStatus; import com.arjuna.ats.arjuna.tools.osb.mbean.UidWrapper; import io.narayana.lra.coordinator.domain.model.LongRunningAction; - import java.net.URI; public class LRAActionBean extends ActionBean implements LRAActionBeanMBean { @@ -20,7 +19,7 @@ public LRAActionBean(UidWrapper w) { } @Override - protected LRAParticipantRecordWrapper createParticipant(AbstractRecord rec, ParticipantStatus listType) { + protected LRAParticipantRecordWrapper createParticipant(AbstractRecord rec, ParticipantStatus listType) { return new LRAParticipantRecordWrapper(this, rec, listType); } @@ -57,4 +56,4 @@ public long getFinishTime() { private LongRunningAction getLRA() { return (LongRunningAction) ra.getAction(); } -} \ No newline at end of file +} diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBeanMBean.java b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBeanMBean.java index b062358932..d535ef0ee0 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBeanMBean.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAActionBeanMBean.java @@ -8,15 +8,19 @@ import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription; import com.arjuna.ats.arjuna.tools.osb.mbean.ActionBeanMBean; import com.arjuna.ats.arjuna.tools.osb.mbean.OSEntryBeanMBean; - import java.net.URI; @MXBeanDescription("Management view of an Long Running Action") public interface LRAActionBeanMBean extends ActionBeanMBean, OSEntryBeanMBean { URI getLRAId(); + URI getParentLRAId(); + String getLRAClientId(); + String getLRAStatus(); + long getStartTime(); + long getFinishTime(); } diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapper.java b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapper.java index a29dcf40c1..e35e91f20a 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapper.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapper.java @@ -10,7 +10,6 @@ import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapper; import com.arjuna.ats.arjuna.tools.osb.mbean.ParticipantStatus; import io.narayana.lra.coordinator.domain.model.LRAParticipantRecord; - import java.net.URI; public class LRAParticipantRecordWrapper extends LogRecordWrapper implements LRAParticipantRecordWrapperMBean { diff --git a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapperMBean.java b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapperMBean.java index 13153b4d00..a728bc27dc 100644 --- a/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapperMBean.java +++ b/coordinator/src/main/java/io/narayana/lra/coordinator/tools/osb/mbean/LRAParticipantRecordWrapperMBean.java @@ -7,16 +7,17 @@ import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription; import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapperMBean; - import java.net.URI; @MXBeanDescription("Management view of an participant record of the LRA") public interface LRAParticipantRecordWrapperMBean extends LogRecordWrapperMBean { URI getRecoveryURI(); + String getParticipantPath(); String getCompensator(); + URI getEndNotificationUri(); String getLRAStatus(); diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/LRAListener.java b/coordinator/src/test/java/io/narayana/lra/coordinator/LRAListener.java index be4ce97a76..fea9328390 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/LRAListener.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/LRAListener.java @@ -5,19 +5,18 @@ package io.narayana.lra.coordinator; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; + import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.core.Response; +import java.net.URI; import org.eclipse.microprofile.lra.annotation.AfterLRA; import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; -import java.net.URI; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; - @Path(LRAListener.LRA_LISTENER_PATH) public class LRAListener { static final String LRA_LISTENER_PATH = "lra-listener"; @@ -68,4 +67,4 @@ public Response killJVM() { Runtime.getRuntime().halt(1); return Response.ok(status.name()).build(); } -} \ No newline at end of file +} diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/TimeoutValueAdjuster.java b/coordinator/src/test/java/io/narayana/lra/coordinator/TimeoutValueAdjuster.java index 951b88f678..afce7df317 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/TimeoutValueAdjuster.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/TimeoutValueAdjuster.java @@ -14,7 +14,7 @@ private TimeoutValueAdjuster() { // not for initialization } - static long adjustTimeout(long originalTimeout) { + static long adjustTimeout(long originalTimeout) { if (timeoutFactor <= 0) { return originalTimeout; } diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATest.java b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATest.java index 386a02d388..b9f98344cd 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATest.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATest.java @@ -13,13 +13,39 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.arjuna.ats.arjuna.exceptions.ObjectStoreException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.narayana.lra.Current; +import io.narayana.lra.LRAConstants; +import io.narayana.lra.LRAData; +import io.narayana.lra.client.internal.NarayanaLRAClient; +import io.narayana.lra.coordinator.api.Coordinator; +import io.narayana.lra.coordinator.domain.service.LRAService; +import io.narayana.lra.coordinator.internal.LRARecoveryModule; +import io.narayana.lra.filter.ServerLRAFilter; +import io.narayana.lra.logging.LRALogger; +import io.narayana.lra.provider.ParticipantStatusOctetStreamProvider; +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.ServiceUnavailableException; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Application; +import jakarta.ws.rs.core.Link; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -34,14 +60,6 @@ import java.util.StringTokenizer; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; - -import com.arjuna.ats.arjuna.exceptions.ObjectStoreException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.narayana.lra.Current; -import io.narayana.lra.LRAConstants; -import jakarta.ws.rs.ServiceUnavailableException; import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; @@ -59,26 +77,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; - -import io.narayana.lra.LRAData; -import io.narayana.lra.client.internal.NarayanaLRAClient; -import io.narayana.lra.coordinator.api.Coordinator; -import io.narayana.lra.coordinator.domain.service.LRAService; -import io.narayana.lra.coordinator.internal.LRARecoveryModule; -import io.narayana.lra.filter.ServerLRAFilter; -import io.narayana.lra.logging.LRALogger; -import io.narayana.lra.provider.ParticipantStatusOctetStreamProvider; -import jakarta.ws.rs.ApplicationPath; -import jakarta.ws.rs.NotFoundException; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.WebTarget; -import jakarta.ws.rs.core.Application; -import jakarta.ws.rs.core.Link; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; import org.junit.runner.RunWith; @RunWith(BMUnitRunner.class) @@ -694,6 +692,7 @@ public void testReplaceCompensator() throws URISyntaxException { /** * Run a loop of LRAs so that a debugger can watch memory + * * @throws URISyntaxException */ @Test @@ -779,7 +778,7 @@ public void testNestedLRAParentCancels() { } private void testNestedLRA(boolean childCancelEarly, boolean parentCancelEarly, - boolean childCancelLate, boolean parentCancelLate) { + boolean childCancelLate, boolean parentCancelLate) { // start a transaction (and cancel it if parentCancelEarly is true) Response parentResponse = client.target(TestPortProvider.generateURL("/base/test/start")) .queryParam("cancel", parentCancelEarly) @@ -894,10 +893,13 @@ public void mixedMultiLevelNestedActivity() { } private enum CompletionType { - complete, compensate, mixed + complete, + compensate, + mixed } - private void multiLevelNestedActivity(CompletionType how, int nestedCnt) throws WebApplicationException, URISyntaxException { + private void multiLevelNestedActivity(CompletionType how, int nestedCnt) + throws WebApplicationException, URISyntaxException { WebTarget resourcePath = client.target(TestPortProvider.generateURL("/base/test/multiLevelNestedActivity")); if (how == CompletionType.mixed && nestedCnt <= 1) { @@ -950,7 +952,7 @@ private void multiLevelNestedActivity(CompletionType how, int nestedCnt) throws /* * the test starts LRA1 calls a @Mandatory method multiLevelNestedActivity which enlists in LRA1 * multiLevelNestedActivity then calls an @Nested method which starts L2 and enlists another participant - * when the method returns the nested participant is completed (ie completed count is incremented) + * when the method returns the nested participant is completed (ie completed count is incremented) * Canceling L1 should then compensate the L1 enlistment (ie compensate count is incremented) * which will then tell L2 to compensate (ie the compensate count is incremented again) */ @@ -1016,7 +1018,7 @@ private void multiLevelNestedActivity(CompletionType how, int nestedCnt) throws */ // there should be just 1 compensation (the first nested LRA) assertEquals("multiLevelNestedActivity: step 9 (called test path " + - resourcePath.getUri() + ")",1, compensateCount.get()); + resourcePath.getUri() + ")", 1, compensateCount.get()); } // verify that the coordinator does not return any LRAs @@ -1109,14 +1111,9 @@ public void testTimeout() throws URISyntaxException { } @Test - @BMRules(rules={ + @BMRules(rules = { // a rule to abort an LRA when a participant is being enlisted - @BMRule(name = "Rendezvous doEnlistParticipant", - targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", - targetMethod = "enlistParticipant", - targetLocation = "ENTRY", - helper = "io.narayana.lra.coordinator.domain.model.BytemanHelper", - action = "abortLRA($0)") + @BMRule(name = "Rendezvous doEnlistParticipant", targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", targetMethod = "enlistParticipant", targetLocation = "ENTRY", helper = "io.narayana.lra.coordinator.domain.model.BytemanHelper", action = "abortLRA($0)") }) public void testTimeoutWhileJoining() throws URISyntaxException { String target = TestPortProvider.generateURL("/base/test/timeout-while-joining"); @@ -1248,13 +1245,9 @@ public void testTransitionToActivateFailure() throws IOException, URISyntaxExcep } @Test - @BMRules(rules={ + @BMRules(rules = { // a rule to fail store writes when an LRA participant is being enlisted - @BMRule(name = "fail deactivate during enlist", - targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", - targetMethod = "enlistParticipant", - targetLocation = "AFTER INVOKE deactivate", - action = "$! = false;" ) + @BMRule(name = "fail deactivate during enlist", targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", targetMethod = "enlistParticipant", targetLocation = "AFTER INVOKE deactivate", action = "$! = false;") }) public void testEnlistFailure() throws IOException, URISyntaxException { try { @@ -1270,26 +1263,18 @@ public void testEnlistFailure() throws IOException, URISyntaxException { } @Test - @BMRules(rules={ + @BMRules(rules = { // a rule to fail store writes when an LRA participant is being enlisted - @BMRule(name = "fail deactivate during close", - targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", - targetMethod = "updateState(LRAStatus, boolean)", - targetLocation = "AFTER INVOKE deactivate", - action = "$! = false;" ) + @BMRule(name = "fail deactivate during close", targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", targetMethod = "updateState(LRAStatus, boolean)", targetLocation = "AFTER INVOKE deactivate", action = "$! = false;") }) public void testCloseFailure() { testEndFailure(true); } @Test - @BMRules(rules={ + @BMRules(rules = { // a rule to fail store writes when an LRA participant is being enlisted - @BMRule(name = "fail deactivate during close", - targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", - targetMethod = "updateState(LRAStatus, boolean)", - targetLocation = "AFTER INVOKE deactivate", - action = "$! = false;" ) + @BMRule(name = "fail deactivate during close", targetClass = "io.narayana.lra.coordinator.domain.model.LongRunningAction", targetMethod = "updateState(LRAStatus, boolean)", targetLocation = "AFTER INVOKE deactivate", action = "$! = false;") }) public void testCancelFailure() { testEndFailure(true); @@ -1397,7 +1382,7 @@ private boolean isFinished(URI lra) { || status == LRAStatus.FailedToClose || status == LRAStatus.FailedToCancel; } - private void assertStatus(String message, URI lraId, LRAStatus ... expectedValues) { + private void assertStatus(String message, URI lraId, LRAStatus... expectedValues) { try { LRAStatus status = getStatus(lraId); @@ -1431,8 +1416,7 @@ private String getCompensatorLinkHeader() { makeLink(prefix, "forget"), makeLink(prefix, "after"), makeLink(prefix, "complete"), - makeLink(prefix, "compensate") - ); + makeLink(prefix, "compensate")); } private static String makeLink(String uriPrefix, String key) { diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATestBase.java b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATestBase.java index 21e7a0092f..732042a9bc 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATestBase.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRATestBase.java @@ -11,35 +11,13 @@ import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; import static org.junit.Assert.assertEquals; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.time.temporal.ChronoUnit; -import java.util.Objects; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.IntStream; - import com.arjuna.ats.arjuna.common.Uid; +import com.arjuna.ats.arjuna.common.arjPropertyManager; import com.arjuna.ats.arjuna.exceptions.ObjectStoreException; import com.arjuna.ats.arjuna.objectstore.RecoveryStore; import com.arjuna.ats.arjuna.objectstore.StoreManager; import com.arjuna.ats.arjuna.state.InputObjectState; import com.arjuna.ats.internal.arjuna.common.UidHelper; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.Forget; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; -import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; -import org.jboss.resteasy.test.TestPortProvider; -import org.junit.rules.TestName; - -import com.arjuna.ats.arjuna.common.arjPropertyManager; - import io.narayana.lra.logging.LRALogger; import jakarta.ws.rs.DELETE; import jakarta.ws.rs.DefaultValue; @@ -55,6 +33,25 @@ import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.time.temporal.ChronoUnit; +import java.util.Objects; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.IntStream; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.Forget; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; +import org.jboss.resteasy.test.TestPortProvider; +import org.junit.rules.TestName; public class LRATestBase { @@ -87,8 +84,8 @@ private Response getResult(boolean cancel, URI lraId) { @Path("start-end") @LRA(value = LRA.Type.REQUIRED) public Response doInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, - @DefaultValue("0") @QueryParam("accept") Integer acceptCount, - @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { + @DefaultValue("0") @QueryParam("accept") Integer acceptCount, + @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { LRATestBase.acceptCount.set(acceptCount); return getResult(cancel, contextId); @@ -98,10 +95,10 @@ public Response doInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, @Path("start") @LRA(value = LRA.Type.REQUIRED, end = false) public Response startInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId, - @DefaultValue("0") @QueryParam("accept") Integer acceptCount, - @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId, + @DefaultValue("0") @QueryParam("accept") Integer acceptCount, + @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { LRATestBase.acceptCount.set(acceptCount); return getResult(cancel, contextId); @@ -111,10 +108,10 @@ public Response startInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, @Path("start-with-recovery") @LRA(value = LRA.Type.REQUIRED, end = false) public Response startInLRAWithRecovery(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId, - @DefaultValue("0") @QueryParam("accept") Integer acceptCount, - @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId, + @DefaultValue("0") @QueryParam("accept") Integer acceptCount, + @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { LRATestBase.acceptCount.set(acceptCount); Response.Status status = cancel ? Response.Status.INTERNAL_SERVER_ERROR : Response.Status.OK; @@ -125,12 +122,11 @@ public Response startInLRAWithRecovery(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI @PUT @Path("end") - @LRA(value = LRA.Type.MANDATORY, - cancelOnFamily = Response.Status.Family.SERVER_ERROR) + @LRA(value = LRA.Type.MANDATORY, cancelOnFamily = Response.Status.Family.SERVER_ERROR) public Response endLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, - @DefaultValue("0") @QueryParam("accept") Integer acceptCount, - @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, + @DefaultValue("0") @QueryParam("accept") Integer acceptCount, + @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { LRATestBase.acceptCount.set(acceptCount); return getResult(cancel, contextId); @@ -164,7 +160,7 @@ public Response timeoutBeforeJoin(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraI @Path("timed-action") @LRA(value = LRA.Type.REQUIRED, end = false, timeLimit = LRA_SHORT_TIMELIMIT) // the default unit is SECONDS public Response actionWithLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, - @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { + @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { status = LRAStatus.Active; server.stop(); //simulate a server crash @@ -177,7 +173,7 @@ public Response actionWithLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextI * invocation to a mandatory LRA endpoint (which should fail with 412) * * @param lraId - * the id of the LRA + * the id of the LRA * @return the JAX-RS response 200 if successful or the received HTTP status call otherwise */ @GET @@ -218,7 +214,7 @@ public Response timeLimitTest(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { @Produces(MediaType.TEXT_PLAIN) @LRA(value = LRA.Type.MANDATORY, end = false) public Response activityWithMandatoryLRA(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId, - @HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { return Response.ok(lraId).header(LRA_HTTP_RECOVERY_HEADER, recoveryId).build(); } @@ -226,8 +222,8 @@ public Response activityWithMandatoryLRA(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) @PUT @Path("nested") public Response nestedLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, - @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA, + @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { return getResult(cancel, contextId); } @@ -235,8 +231,8 @@ public Response nestedLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, @PUT @Path("nested-with-close") public Response nestedLRAWithClose(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId, - @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId, + @DefaultValue("false") @QueryParam("cancel") Boolean cancel) { return getResult(cancel, contextId); } @@ -250,7 +246,7 @@ public Response multiLevelNestedActivity( // invoke resources that enlist nested LRAs String[] lras = new String[nestedCnt + 1]; lras[0] = nestedLRAId.toASCIIString(); - IntStream.range(1, lras.length).forEach(i -> lras[i] = restPutInvocation(nestedLRAId,"nestedActivity", "")); + IntStream.range(1, lras.length).forEach(i -> lras[i] = restPutInvocation(nestedLRAId, "nestedActivity", "")); return Response.ok(String.join(",", lras)).build(); } @@ -259,7 +255,7 @@ public Response multiLevelNestedActivity( @Path("nestedActivity") @LRA(value = LRA.Type.NESTED, end = true) public Response nestedActivity(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId, - @HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI nestedLRAId) { + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI nestedLRAId) { return Response.ok(nestedLRAId.toASCIIString()).build(); } @@ -273,7 +269,7 @@ public Response getStatus() { @Path("/complete") @Complete public Response complete(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextLRA, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA) { if (acceptCount.getAndDecrement() <= 0) { completeCount.incrementAndGet(); acceptCount.set(0); @@ -287,7 +283,7 @@ public Response complete(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextLRA, @Path("/compensate") @Compensate public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextLRA, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA) { if (acceptCount.getAndDecrement() <= 0) { compensateCount.incrementAndGet(); acceptCount.set(0); @@ -300,7 +296,7 @@ public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextLRA, @PUT @Path("/fallback-compensate") public Response alternateCompensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextLRA, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA) { + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentLRA) { Response r = compensate(contextLRA, parentLRA); if (r.getStatus() == Response.Status.OK.getStatusCode()) { @@ -324,7 +320,7 @@ public Response lraEndStatus(LRAStatus endStatus) { @Produces(MediaType.APPLICATION_JSON) @Forget public Response forgetWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId) { forgetCount.incrementAndGet(); return Response.ok().build(); @@ -397,6 +393,7 @@ public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI ignore) { return Response.status(Response.Status.OK).entity(ParticipantStatus.Compensated).build(); } } + @Path("/participant2") public static class Participant2 { @GET @@ -406,7 +403,6 @@ public Response continueInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI ignore) return Response.ok().build(); } - @PUT @Path("complete") @Complete @@ -501,4 +497,4 @@ protected int countRecords() throws ObjectStoreException, IOException { return count; } -} \ No newline at end of file +} diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRAWithParticipantsTest.java b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRAWithParticipantsTest.java index b57fbddba8..856fc51284 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRAWithParticipantsTest.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/LRAWithParticipantsTest.java @@ -10,13 +10,24 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; +import io.narayana.lra.client.internal.NarayanaLRAClient; +import io.narayana.lra.coordinator.api.Coordinator; +import io.narayana.lra.filter.ServerLRAFilter; +import io.narayana.lra.logging.LRALogger; +import io.narayana.lra.provider.ParticipantStatusOctetStreamProvider; +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.HeaderParam; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Application; +import jakarta.ws.rs.core.Response; import java.net.URI; import java.time.temporal.ChronoUnit; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; - import org.eclipse.microprofile.lra.annotation.Compensate; import org.eclipse.microprofile.lra.annotation.ParticipantStatus; import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; @@ -28,19 +39,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import io.narayana.lra.client.internal.NarayanaLRAClient; -import io.narayana.lra.coordinator.api.Coordinator; -import io.narayana.lra.filter.ServerLRAFilter; -import io.narayana.lra.logging.LRALogger; -import io.narayana.lra.provider.ParticipantStatusOctetStreamProvider; -import jakarta.ws.rs.ApplicationPath; -import jakarta.ws.rs.HeaderParam; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Application; -import jakarta.ws.rs.core.Response; - public class LRAWithParticipantsTest extends LRATestBase { @Rule @@ -50,6 +48,7 @@ public class LRAWithParticipantsTest extends LRATestBase { private static ReentrantLock lock = new ReentrantLock(); private static boolean joinAttempted; private static boolean compensateCalled; + @Path("/test") public static class ParticipantExtended extends Participant { @@ -66,8 +65,7 @@ public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextLRA, while (!joinAttempted) { try { lock.wait(); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { fail("Could not wait"); } } @@ -75,6 +73,7 @@ public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI contextLRA, return Response.status(Response.Status.ACCEPTED).entity(ParticipantStatus.Compensating).build(); } } + @ApplicationPath("service2") public static class Service2 extends Application { @@ -87,12 +86,15 @@ public Set> getClasses() { return classes; } } + @ApplicationPath("service3") public static class Service3 extends Service2 { } + @ApplicationPath("service4") public static class Service4 extends Service2 { } + @ApplicationPath("/") public static class LRACoordinator extends Application { @@ -103,6 +105,7 @@ public Set> getClasses() { return classes; } } + @BeforeClass public static void start() { System.setProperty("lra.coordinator.url", TestPortProvider.generateURL('/' + COORDINATOR_PATH_NAME)); @@ -143,16 +146,14 @@ public void testJoinAfterTimeout() { // by Service 2 and Service 3. try { TimeUnit.SECONDS.sleep(1); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (lock) { while (!compensateCalled) { try { lock.wait(); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { fail("Could not wait"); } } @@ -167,4 +168,4 @@ public void testJoinAfterTimeout() { lock.notify(); } } -} \ No newline at end of file +} diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/JDBCObjectStoreTest.java b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/JDBCObjectStoreTest.java index a8c52c69d6..55d8481d19 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/JDBCObjectStoreTest.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/JDBCObjectStoreTest.java @@ -5,16 +5,16 @@ package io.narayana.lra.coordinator.domain.model.objectstore; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean; import com.arjuna.ats.internal.arjuna.objectstore.jdbc.JDBCStore; import com.arjuna.common.internal.util.propertyservice.BeanPopulator; import io.narayana.lra.LRAData; import io.narayana.lra.logging.LRALogger; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - import java.net.URI; import java.sql.Connection; import java.sql.DriverManager; @@ -24,11 +24,10 @@ import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; public class JDBCObjectStoreTest extends TestBase { @@ -50,7 +49,7 @@ public void jdbcStoreTest() { // This test fails if the Object Store is not set to JDBCStore assertEquals("The Object Store type should have been set to JDBCStore", JDBCStore.class.getName(), objectStoreType); - LRALogger.logger.infof("%s: the Object Store type is set to: %s",testName.getMethodName(), objectStoreType); + LRALogger.logger.infof("%s: the Object Store type is set to: %s", testName.getMethodName(), objectStoreType); // Starts a new LRA URI lraIdUri = lraClient.startLRA(testName.getMethodName() + "#newLRA"); @@ -63,7 +62,8 @@ public void jdbcStoreTest() { String lraId = convertLraUriToString(lraIdUri).replace('_', ':'); LRAData lraData = getLastCreatedLRA(); - assertEquals("Expected that the LRA transaction just started matches the LRA transaction fetched through the Narayana LRA client", + assertEquals( + "Expected that the LRA transaction just started matches the LRA transaction fetched through the Narayana LRA client", lraData.getLraId(), lraIdUri); diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/TestBase.java b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/TestBase.java index 08ea27ef9e..c9d67af1f1 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/TestBase.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/TestBase.java @@ -5,21 +5,14 @@ package io.narayana.lra.coordinator.domain.model.objectstore; +import static io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME; + import io.narayana.lra.LRAData; import io.narayana.lra.client.internal.NarayanaLRAClient; import io.narayana.lra.coordinator.api.Coordinator; import io.narayana.lra.filter.ServerLRAFilter; import io.narayana.lra.logging.LRALogger; import io.narayana.lra.provider.ParticipantStatusOctetStreamProvider; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; -import org.jboss.resteasy.test.TestPortProvider; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.rules.TestName; - import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.WebApplicationException; @@ -31,8 +24,14 @@ import java.util.HashSet; import java.util.List; import java.util.Set; - -import static io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; +import org.jboss.resteasy.test.TestPortProvider; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.rules.TestName; public class TestBase { diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/VolatileObjectStoreTest.java b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/VolatileObjectStoreTest.java index 2979839106..b62d139318 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/VolatileObjectStoreTest.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/domain/model/objectstore/VolatileObjectStoreTest.java @@ -5,20 +5,19 @@ package io.narayana.lra.coordinator.domain.model.objectstore; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean; import com.arjuna.ats.internal.arjuna.objectstore.VolatileStore; import com.arjuna.common.internal.util.propertyservice.BeanPopulator; import io.narayana.lra.LRAData; import io.narayana.lra.logging.LRALogger; +import java.net.URI; import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.junit.BeforeClass; import org.junit.Test; -import java.net.URI; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - public class VolatileObjectStoreTest extends TestBase { @BeforeClass @@ -37,9 +36,10 @@ public void volatileStoreTest() { String objectStoreType = BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).getObjectStoreType(); // This test fails if the Object Store is not set to Volatile - assertEquals("The Object Store type should have been set to VolatileStore", VolatileStore.class.getName(), objectStoreType); + assertEquals("The Object Store type should have been set to VolatileStore", VolatileStore.class.getName(), + objectStoreType); - LRALogger.logger.infof("%s: the Object Store type is set to: %s",testName.getMethodName(), objectStoreType); + LRALogger.logger.infof("%s: the Object Store type is set to: %s", testName.getMethodName(), objectStoreType); // Starts a new LRA URI lraIdUri = lraClient.startLRA(testName.getMethodName() + "#newLRA"); @@ -52,7 +52,8 @@ public void volatileStoreTest() { String lraId = convertLraUriToString(lraIdUri).replace('_', ':'); LRAData lraData = getLastCreatedLRA(); - assertEquals("Expected that the LRA transaction just started matches the LRA transaction fetched through the Narayana LRA client", + assertEquals( + "Expected that the LRA transaction just started matches the LRA transaction fetched through the Narayana LRA client", lraData.getLraId(), lraIdUri); } diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/management/BrowserCommandTest.java b/coordinator/src/test/java/io/narayana/lra/coordinator/management/BrowserCommandTest.java index da7a5481e4..e3482fa66c 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/management/BrowserCommandTest.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/management/BrowserCommandTest.java @@ -6,15 +6,14 @@ import io.narayana.lra.coordinator.domain.model.FailedLongRunningAction; import io.narayana.lra.coordinator.domain.model.LongRunningAction; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.junit.Assert; -import org.junit.Test; - import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import java.net.URL; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.junit.Assert; +import org.junit.Test; public class BrowserCommandTest { private static final String TEST_STORE = "test-store"; diff --git a/coordinator/src/test/java/io/narayana/lra/coordinator/tools/osb/mbean/ObjStoreBrowserLRATest.java b/coordinator/src/test/java/io/narayana/lra/coordinator/tools/osb/mbean/ObjStoreBrowserLRATest.java index 332c02e2e6..09531b2cbd 100644 --- a/coordinator/src/test/java/io/narayana/lra/coordinator/tools/osb/mbean/ObjStoreBrowserLRATest.java +++ b/coordinator/src/test/java/io/narayana/lra/coordinator/tools/osb/mbean/ObjStoreBrowserLRATest.java @@ -5,6 +5,12 @@ package io.narayana.lra.coordinator.tools.osb.mbean; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import com.arjuna.ats.arjuna.common.recoveryPropertyManager; import com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean; import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapper; @@ -18,29 +24,23 @@ import io.narayana.lra.coordinator.domain.model.LongRunningAction; import io.narayana.lra.coordinator.internal.Implementations; import io.narayana.lra.coordinator.internal.LRARecoveryModule; +import java.io.File; +import java.net.URI; import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import java.io.File; -import java.net.URI; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; - public class ObjStoreBrowserLRATest { private RecoveryManagerImple recoveryManager; private ObjStoreBrowser osb; private static final String[][] LRA_OSB_TYPES = { // osTypeClassName, beanTypeClassName - see com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBrowser - {LongRunningAction.getType().substring(1), LongRunningAction.class.getName(), LRAActionBean.class.getName()}, - {FailedLongRunningAction.getType().substring(1), FailedLongRunningAction.class.getName(), LRAActionBean.class.getName()} + { LongRunningAction.getType().substring(1), LongRunningAction.class.getName(), LRAActionBean.class.getName() }, + { FailedLongRunningAction.getType().substring(1), FailedLongRunningAction.class.getName(), + LRAActionBean.class.getName() } }; @Before @@ -52,7 +52,7 @@ public void setUp() { // initiating the ObjStoreBrowser osb = ObjStoreBrowser.getInstance(); - for(String[] typeAndBean: LRA_OSB_TYPES) { + for (String[] typeAndBean : LRA_OSB_TYPES) { String typeName = typeAndBean[0].replace("/", File.separator); osb.addOSBTypeHandler(typeName, new OSBTypeHandler(true, true, typeAndBean[1], typeAndBean[2], typeAndBean[0], null, this.getClass().getClassLoader())); @@ -61,7 +61,7 @@ public void setUp() { } @After - public void tearDown () { + public void tearDown() { recoveryManager.removeAllModules(false); recoveryManager.stop(false); Implementations.uninstall(); @@ -109,7 +109,8 @@ public void lraMBeanRemoval() throws Exception { assertNotNull("Expected the LRA MBean uid was probed", uidWrapper); lraOSEntryBean = uidWrapper.getMBean(); assertNotNull("Expecting the UID to contain the LRA mbean", lraOSEntryBean); - assertTrue("The mbean should wrap " + ActionBean.class.getName() + " but it's " + lraOSEntryBean.getClass().getName(), + assertTrue( + "The mbean should wrap " + ActionBean.class.getName() + " but it's " + lraOSEntryBean.getClass().getName(), lraOSEntryBean instanceof ActionBean); ActionBean actionBean = (ActionBean) lraOSEntryBean; assertEquals("One participant was enlisted", 1, actionBean.getParticipants().size()); @@ -171,4 +172,4 @@ private String noSlash(String type) { char firstChar = type.charAt(0); return firstChar == '/' ? type.substring(1) : type; } -} \ No newline at end of file +} diff --git a/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRARequestFilter.java b/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRARequestFilter.java index 95444244a0..4a6f20926d 100644 --- a/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRARequestFilter.java +++ b/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRARequestFilter.java @@ -5,16 +5,15 @@ package io.narayana.lra.filter; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; + import io.narayana.lra.Current; import jakarta.ws.rs.client.ClientRequestContext; import jakarta.ws.rs.client.ClientRequestFilter; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.ext.Provider; -import org.eclipse.microprofile.config.ConfigProvider; - import java.net.URI; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import org.eclipse.microprofile.config.ConfigProvider; @Provider public class ClientLRARequestFilter implements ClientRequestFilter { @@ -23,7 +22,7 @@ public class ClientLRARequestFilter implements ClientRequestFilter { public ClientLRARequestFilter() { canPropagate = ConfigProvider.getConfig() - .getOptionalValue("mp.lra.propagation.active", Boolean.class).orElse(true); + .getOptionalValue("mp.lra.propagation.active", Boolean.class).orElse(true); } @Override @@ -54,4 +53,4 @@ public void filter(ClientRequestContext context) { } } } -} \ No newline at end of file +} diff --git a/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRAResponseFilter.java b/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRAResponseFilter.java index d53e4efa12..0be7aa1842 100644 --- a/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRAResponseFilter.java +++ b/jaxrs/src/main/java/io/narayana/lra/filter/ClientLRAResponseFilter.java @@ -5,8 +5,9 @@ package io.narayana.lra.filter; -import io.narayana.lra.Current; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import io.narayana.lra.Current; import jakarta.ws.rs.client.ClientRequestContext; import jakarta.ws.rs.client.ClientResponseContext; import jakarta.ws.rs.client.ClientResponseFilter; @@ -16,8 +17,6 @@ import java.io.IOException; import java.net.URI; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; - @Provider public class ClientLRAResponseFilter implements ClientResponseFilter { @Context @@ -31,4 +30,4 @@ public void filter(ClientRequestContext requestContext, ClientResponseContext re Current.push((URI) callingContext); } } -} \ No newline at end of file +} diff --git a/jaxrs/src/main/java/io/narayana/lra/filter/ServerLRAFilter.java b/jaxrs/src/main/java/io/narayana/lra/filter/ServerLRAFilter.java index e76eb3d50c..3599de8388 100644 --- a/jaxrs/src/main/java/io/narayana/lra/filter/ServerLRAFilter.java +++ b/jaxrs/src/main/java/io/narayana/lra/filter/ServerLRAFilter.java @@ -5,6 +5,20 @@ package io.narayana.lra.filter; +import static io.narayana.lra.LRAConstants.AFTER; +import static io.narayana.lra.LRAConstants.COMPENSATE; +import static io.narayana.lra.LRAConstants.COMPLETE; +import static io.narayana.lra.LRAConstants.FORGET; +import static io.narayana.lra.LRAConstants.LEAVE; +import static io.narayana.lra.LRAConstants.STATUS; +import static io.narayana.lra.LRAConstants.TIMELIMIT_PARAM_NAME; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.Type.MANDATORY; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.Type.NESTED; + import io.narayana.lra.AnnotationResolver; import io.narayana.lra.Current; import io.narayana.lra.client.LRAParticipantData; @@ -12,21 +26,8 @@ import io.narayana.lra.client.internal.proxy.nonjaxrs.LRAParticipant; import io.narayana.lra.client.internal.proxy.nonjaxrs.LRAParticipantRegistry; import io.narayana.lra.logging.LRALogger; - import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ContextNotActiveException; -import jakarta.ws.rs.core.Link; -import jakarta.ws.rs.core.UriInfo; -import org.eclipse.microprofile.config.ConfigProvider; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.Forget; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.Status; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; -import org.eclipse.microprofile.lra.annotation.ws.rs.Leave; - import jakarta.inject.Inject; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.ProcessingException; @@ -37,9 +38,11 @@ import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.container.ResourceInfo; import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Link; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriInfo; import jakarta.ws.rs.ext.Provider; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; @@ -55,20 +58,15 @@ import java.util.Map; import java.util.StringJoiner; import java.util.regex.Pattern; - -import static io.narayana.lra.LRAConstants.AFTER; -import static io.narayana.lra.LRAConstants.COMPENSATE; -import static io.narayana.lra.LRAConstants.COMPLETE; -import static io.narayana.lra.LRAConstants.FORGET; -import static io.narayana.lra.LRAConstants.LEAVE; -import static io.narayana.lra.LRAConstants.STATUS; -import static io.narayana.lra.LRAConstants.TIMELIMIT_PARAM_NAME; -import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.Type.MANDATORY; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.Type.NESTED; +import org.eclipse.microprofile.config.ConfigProvider; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.Forget; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.Status; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import org.eclipse.microprofile.lra.annotation.ws.rs.Leave; @Provider @ApplicationScoped @@ -96,7 +94,7 @@ public class ServerLRAFilter implements ContainerRequestFilter, ContainerRespons LRAParticipantData data; private boolean isTxInvalid(ContainerRequestContext containerRequestContext, LRA.Type type, URI lraId, - boolean shouldNotBeNull, ArrayList progress) { + boolean shouldNotBeNull, ArrayList progress) { if (lraId == null && shouldNotBeNull) { abortWith(containerRequestContext, null, Response.Status.PRECONDITION_FAILED.getStatusCode(), type.name() + " but no tx", progress); @@ -314,13 +312,13 @@ public void filter(ContainerRequestContext containerRequestContext) { break; case REQUIRES_NEW: -// previous = AtomicAction.suspend(); + // previous = AtomicAction.suspend(); suspendedLRA = incomingLRA; if (progress == null) { progress = new ArrayList<>(); } - newLRA = lraId = startLRA(containerRequestContext,null, method, timeout, progress); + newLRA = lraId = startLRA(containerRequestContext, null, method, timeout, progress); if (newLRA == null) { // startLRA will have called abortWith on the request context @@ -381,12 +379,13 @@ public void filter(ContainerRequestContext containerRequestContext) { if (!endAnnotation) { // don't enlist for methods marked with Compensate, Complete or Leave Map terminateURIs = NarayanaLRAClient.getTerminationUris(resourceInfo.getResourceClass(), - createUriPrefix(containerRequestContext), timeout); + createUriPrefix(containerRequestContext), timeout); String timeLimitStr = terminateURIs.get(TIMELIMIT_PARAM_NAME); long timeLimit = timeLimitStr == null ? DEFAULT_TIMEOUT_MILLIS : Long.parseLong(timeLimitStr); - LRAParticipant participant = lraParticipantRegistry != null ? - lraParticipantRegistry.getParticipant(resourceInfo.getResourceClass().getName()) : null; + LRAParticipant participant = lraParticipantRegistry != null + ? lraParticipantRegistry.getParticipant(resourceInfo.getResourceClass().getName()) + : null; if (terminateURIs.containsKey("Link") || participant != null) { try { @@ -458,18 +457,19 @@ public void filter(ContainerRequestContext containerRequestContext) { private String createUriPrefix(ContainerRequestContext containerRequestContext) { return ConfigProvider.getConfig().getOptionalValue("narayana.lra.base-uri", String.class) - .orElseGet(() -> { - UriInfo uriInfo = containerRequestContext.getUriInfo(); - - /* - * Calculate which path to prepend to the LRA participant methods. If there is more than one matching URI - * then the second matched URI comes from either the class level Path annotation or from a sub-resource locator. - * In both cases the second matched URI can be used as a prefix for the LRA participant URIs: - */ - List matchedURIs = uriInfo.getMatchedURIs(); - int matchedURI = (matchedURIs.size() > 1 ? 1 : 0); - return uriInfo.getBaseUri() + matchedURIs.get(matchedURI); - }); + .orElseGet(() -> { + UriInfo uriInfo = containerRequestContext.getUriInfo(); + + /* + * Calculate which path to prepend to the LRA participant methods. If there is more than one matching URI + * then the second matched URI comes from either the class level Path annotation or from a sub-resource + * locator. + * In both cases the second matched URI can be used as a prefix for the LRA participant URIs: + */ + List matchedURIs = uriInfo.getMatchedURIs(); + int matchedURI = (matchedURIs.size() > 1 ? 1 : 0); + return uriInfo.getBaseUri() + matchedURIs.get(matchedURI); + }); } @Override @@ -538,7 +538,7 @@ public void filter(ContainerRequestContext requestContext, ContainerResponseCont } else { // same as ProcessingException case progress = updateProgress(progress, - isCancel ? ProgressStep.CancelFailed : ProgressStep.CloseFailed, e.getMessage()); + isCancel ? ProgressStep.CancelFailed : ProgressStep.CloseFailed, e.getMessage()); } } catch (ProcessingException e) { progress = updateProgress(progress, @@ -557,8 +557,8 @@ public void filter(ContainerRequestContext requestContext, ContainerResponseCont } if (responseContext.getStatus() == Response.Status.OK.getStatusCode() - && resourceInfo.getResourceMethod() != null - && NarayanaLRAClient.isAsyncCompletion(resourceInfo.getResourceMethod())) { + && resourceInfo.getResourceMethod() != null + && NarayanaLRAClient.isAsyncCompletion(resourceInfo.getResourceMethod())) { LRALogger.i18nLogger.warn_lraParticipantqForAsync( resourceInfo.getResourceMethod().getDeclaringClass().getName(), resourceInfo.getResourceMethod().getName(), @@ -573,7 +573,7 @@ public void filter(ContainerRequestContext requestContext, ContainerResponseCont * different warning code for each scenario: */ if (progress != null) { - String failureMessage = processLRAOperationFailures(progress); + String failureMessage = processLRAOperationFailures(progress); if (failureMessage != null) { responseContext.setEntity(failureMessage); @@ -624,7 +624,7 @@ private boolean isJaxRsCancel(ContainerRequestContext requestContext, ContainerR // the following structure is used to track progress so that such failures can be reported in the response // filter processing private enum ProgressStep { - Left ("leave succeeded"), + Left("leave succeeded"), LeaveFailed("leave failed"), Started("start succeeded"), StartFailed("start failed"), @@ -717,7 +717,7 @@ private ArrayList updateProgress(ArrayList progress, Progres // the processing performed by the request filter caused the request to abort (without executing application code) private void abortWith(ContainerRequestContext containerRequestContext, String lraId, int statusCode, - String message, Collection reasons) { + String message, Collection reasons) { // the response filter will set the entity body containerRequestContext.abortWith(Response.status(statusCode).entity(message).build()); // make the reason for the failure available to the response filter @@ -739,7 +739,7 @@ public static > T cast(Object obj) { } private URI startLRA(ContainerRequestContext containerRequestContext, URI parentLRA, Method method, Long timeout, - ArrayList progress) { + ArrayList progress) { // timeout should already have been converted to milliseconds String clientId = method.getDeclaringClass().getName() + "#" + method.getName(); @@ -800,7 +800,7 @@ private static void makeLink(StringBuilder b, String key, URI value) { } String uri = value.toASCIIString(); - Link link = Link.fromUri(uri).title(key + " URI").rel(key).type(MediaType.TEXT_PLAIN).build(); + Link link = Link.fromUri(uri).title(key + " URI").rel(key).type(MediaType.TEXT_PLAIN).build(); if (b.length() != 0) { b.append(','); @@ -808,4 +808,4 @@ private static void makeLink(StringBuilder b, String key, URI value) { b.append(link); } -} \ No newline at end of file +} diff --git a/jaxrs/src/main/java/io/narayana/lra/provider/ParticipantStatusOctetStreamProvider.java b/jaxrs/src/main/java/io/narayana/lra/provider/ParticipantStatusOctetStreamProvider.java index 9defb61a87..1440b82fb0 100644 --- a/jaxrs/src/main/java/io/narayana/lra/provider/ParticipantStatusOctetStreamProvider.java +++ b/jaxrs/src/main/java/io/narayana/lra/provider/ParticipantStatusOctetStreamProvider.java @@ -5,8 +5,6 @@ package io.narayana.lra.provider; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; - import jakarta.ws.rs.Produces; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.MediaType; @@ -17,6 +15,7 @@ import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; @Provider @Produces(MediaType.APPLICATION_OCTET_STREAM) @@ -27,12 +26,15 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat } @Override - public long getSize(ParticipantStatus participantStatus, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + public long getSize(ParticipantStatus participantStatus, Class type, Type genericType, Annotation[] annotations, + MediaType mediaType) { return -1; } @Override - public void writeTo(ParticipantStatus participantStatus, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { + public void writeTo(ParticipantStatus participantStatus, Class type, Type genericType, Annotation[] annotations, + MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) + throws IOException, WebApplicationException { entityStream.write(participantStatus.name().getBytes()); } } diff --git a/pom.xml b/pom.xml index 5eebbf2faf..7da4a614dd 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ ${maven.build.timestamp} false + false -Djboss.bind.address=[::1] -Djboss.bind.address.management=[::1] -Djboss.bind.address.unsecure=[::1] -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true -Dorg.jboss.byteman.verbose @@ -98,6 +99,7 @@ 4.8.3.1 2.2.224 1.8.1 + 2.26.0 2.2 4.5.14 @@ -705,24 +707,6 @@ - - com.github.ekryd.sortpom - sortpom-maven-plugin - ${version.sortpom} - - ${sortpom.skip} - false - true - - - - - sort - - verify - - - org.apache.maven.plugins maven-surefire-plugin @@ -753,6 +737,25 @@ + + net.revelc.code.formatter + formatter-maven-plugin + ${version.formatter.plugin} + + + .cache/formatter-maven-plugin-${version.formatter.plugin} + eclipse-format.xml + LF + ${format.skip} + + + + io.quarkus + quarkus-ide-config + 3.22.2 + + + @@ -999,5 +1002,64 @@ + + format + + true + + !no-format + + + + + + net.revelc.code.formatter + formatter-maven-plugin + + + + format + + process-sources + + + + + net.revelc.code + impsort-maven-plugin + + true + + + + sort-imports + + sort + + + + + + com.github.ekryd.sortpom + sortpom-maven-plugin + ${version.sortpom} + + ${sortpom.skip} + false + true + + + + + sort + + verify + + + + + + + diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxy.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxy.java index 42240e2397..65b40bdfad 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxy.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxy.java @@ -6,12 +6,11 @@ package io.narayana.lra.client.internal.proxy; import io.narayana.lra.proxy.logging.LRAProxyLogger; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; - import java.net.URI; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; class ParticipantProxy { private final URI lraId; @@ -31,7 +30,6 @@ class ParticipantProxy { this.participantId = participantId; } - private URI getLraId() { return lraId; } @@ -65,7 +63,7 @@ public int hashCode() { return result; } - void setFuture(Future future, boolean compensate) { + void setFuture(Future future, boolean compensate) { this.future = future; this.compensate = compensate; } diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxyResource.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxyResource.java index 21220c90d6..4ffbaddb8b 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxyResource.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ParticipantProxyResource.java @@ -5,6 +5,7 @@ package io.narayana.lra.client.internal.proxy; +import io.narayana.lra.proxy.logging.LRAProxyLogger; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.DELETE; @@ -13,9 +14,6 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.core.Response; - -import io.narayana.lra.proxy.logging.LRAProxyLogger; - import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; @@ -31,31 +29,31 @@ public class ParticipantProxyResource { @Path("{lraId}/{pId}/complete") @PUT - public Response complete(@PathParam("lraId")String lraId, - @PathParam("pId")String participantId, - String participantData) throws URISyntaxException, UnsupportedEncodingException { + public Response complete(@PathParam("lraId") String lraId, + @PathParam("pId") String participantId, + String participantData) throws URISyntaxException, UnsupportedEncodingException { return proxyService.notifyParticipant(toURI(lraId), participantId, participantData, false); } @Path("{lraId}/{pId}/compensate") @PUT - public Response compensate(@PathParam("lraId")String lraId, - @PathParam("pId")String participantId, - String participantData) throws URISyntaxException, UnsupportedEncodingException { + public Response compensate(@PathParam("lraId") String lraId, + @PathParam("pId") String participantId, + String participantData) throws URISyntaxException, UnsupportedEncodingException { return proxyService.notifyParticipant(toURI(lraId), participantId, participantData, true); } @Path("{lraId}/{pId}") @DELETE - public void forget(@PathParam("lraId")String lraId, - @PathParam("pId")String participantId) throws URISyntaxException, UnsupportedEncodingException { + public void forget(@PathParam("lraId") String lraId, + @PathParam("pId") String participantId) throws URISyntaxException, UnsupportedEncodingException { proxyService.notifyForget(toURI(lraId), participantId); } @Path("{lraId}/{pId}") @GET - public String status(@PathParam("lraId")String lraId, - @PathParam("pId")String participantId) throws UnsupportedEncodingException, InvalidLRAStateException { + public String status(@PathParam("lraId") String lraId, + @PathParam("pId") String participantId) throws UnsupportedEncodingException, InvalidLRAStateException { try { return proxyService.getStatus(toURI(lraId), participantId).name(); } catch (URISyntaxException e) { diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ProxyService.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ProxyService.java index 12cb97dae2..53c0ccecf2 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ProxyService.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/ProxyService.java @@ -5,6 +5,9 @@ package io.narayana.lra.client.internal.proxy; +import static io.narayana.lra.client.internal.proxy.ParticipantProxyResource.LRA_PROXY_PATH; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; + import io.narayana.lra.client.internal.NarayanaLRAClient; import io.narayana.lra.proxy.logging.LRAProxyLogger; import jakarta.annotation.PostConstruct; @@ -14,8 +17,6 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilder; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; @@ -31,9 +32,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.Future; - -import static io.narayana.lra.client.internal.proxy.ParticipantProxyResource.LRA_PROXY_PATH; -import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; @ApplicationScoped public class ProxyService { @@ -166,13 +165,13 @@ public URI joinLRA(LRAProxyParticipant participant, URI lraId, Long timeLimit, C return narayanaLRAClient.joinLRA(lraId, timeLimitInSeconds, participantUri, sb); } catch (Exception e) { throw new WebApplicationException(e, Response.status(0) - .entity(lraId + ": Exception whilst joining with this LRA").build()); + .entity(lraId + ": Exception whilst joining with this LRA").build()); } } private static Optional serializeParticipant(final Serializable object) { try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos)) { + ObjectOutputStream oos = new ObjectOutputStream(baos)) { oos.writeObject(object); return Optional.of(Base64.getEncoder().encodeToString(baos.toByteArray())); diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/ClassPathIndexer.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/ClassPathIndexer.java index eda86f3978..ac2c42c309 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/ClassPathIndexer.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/ClassPathIndexer.java @@ -6,12 +6,6 @@ package io.narayana.lra.client.internal.proxy.nonjaxrs; import io.narayana.lra.logging.LRALogger; -import org.jboss.jandex.Index; -import org.jboss.jandex.Indexer; -import org.jboss.logging.Logger; -import org.jboss.modules.ModuleClassLoader; -import org.jboss.modules.Resource; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -25,6 +19,11 @@ import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import org.jboss.jandex.Index; +import org.jboss.jandex.Indexer; +import org.jboss.logging.Logger; +import org.jboss.modules.ModuleClassLoader; +import org.jboss.modules.Resource; class ClassPathIndexer { private static final Logger log = Logger.getLogger(ClassPathIndexer.class); diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRACDIExtension.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRACDIExtension.java index e7eb15b336..db18855629 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRACDIExtension.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRACDIExtension.java @@ -8,12 +8,6 @@ import io.narayana.lra.client.internal.proxy.nonjaxrs.jandex.DotNames; import io.narayana.lra.client.internal.proxy.nonjaxrs.jandex.JandexAnnotationResolver; import io.narayana.lra.logging.LRALogger; -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationTarget; -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.DotName; -import org.jboss.jandex.Index; - import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Any; @@ -29,6 +23,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationTarget; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Index; /** * This CDI extension collects all LRA participants that contain @@ -41,7 +40,8 @@ public class LRACDIExtension implements Extension { private Index index; private final Map participants = new HashMap<>(); - public void observe(@Observes AfterBeanDiscovery event, BeanManager beanManager) throws IOException, ClassNotFoundException { + public void observe(@Observes AfterBeanDiscovery event, BeanManager beanManager) + throws IOException, ClassNotFoundException { index = classPathIndexer.createIndex(); List annotations = index.getAnnotations(DotName.createSimple("jakarta.ws.rs.Path")); @@ -61,13 +61,14 @@ public void observe(@Observes AfterBeanDiscovery event, BeanManager beanManager) LRAParticipant participant = getAsParticipant(classInfo); if (participant != null) { participants.put(participant.getJavaClass().getName(), participant); - Set> participantBeans = beanManager.getBeans(participant.getJavaClass(), new AnnotationLiteral() {}); + Set> participantBeans = beanManager.getBeans(participant.getJavaClass(), new AnnotationLiteral() { + }); if (participantBeans.isEmpty()) { // resource is not registered as managed bean so register a custom managed instance try { participant.setInstance(participant.getJavaClass().getDeclaredConstructor().newInstance()); - } catch (InstantiationException | IllegalAccessException | - InvocationTargetException | NoSuchMethodException e) { + } catch (InstantiationException | IllegalAccessException | InvocationTargetException + | NoSuchMethodException e) { LRALogger.i18nLogger.error_cannotProcessParticipant(e); } } @@ -75,10 +76,10 @@ public void observe(@Observes AfterBeanDiscovery event, BeanManager beanManager) } event.addBean() - .read(beanManager.createAnnotatedType(LRAParticipantRegistry.class)) - .beanClass(LRAParticipantRegistry.class) - .scope(ApplicationScoped.class) - .createWith(context -> new LRAParticipantRegistry(participants)); + .read(beanManager.createAnnotatedType(LRAParticipantRegistry.class)) + .beanClass(LRAParticipantRegistry.class) + .scope(ApplicationScoped.class) + .createWith(context -> new LRAParticipantRegistry(participants)); } /** @@ -114,13 +115,14 @@ private LRAParticipant getAsParticipant(ClassInfo classInfo) throws ClassNotFoun * @throws IllegalStateException if there is LRA annotation but no Compensate or AfterLRA is found */ private boolean isLRAParticipant(ClassInfo classInfo) { - Map> annotations = JandexAnnotationResolver.getAllAnnotationsFromClassInfoHierarchy(classInfo.name(), index); + Map> annotations = JandexAnnotationResolver + .getAllAnnotationsFromClassInfoHierarchy(classInfo.name(), index); if (!annotations.containsKey(DotNames.LRA)) { return false; } else if (!annotations.containsKey(DotNames.COMPENSATE) && !annotations.containsKey(DotNames.AFTER_LRA)) { throw new IllegalStateException(String.format("%s: %s", - classInfo.name(), "The class contains an LRA method and no Compensate or AfterLRA method was found.")); + classInfo.name(), "The class contains an LRA method and no Compensate or AfterLRA method was found.")); } else { return true; } diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipant.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipant.java index 30a0a3117d..e0a1d2f389 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipant.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipant.java @@ -5,16 +5,14 @@ package io.narayana.lra.client.internal.proxy.nonjaxrs; +import static io.narayana.lra.LRAConstants.AFTER; +import static io.narayana.lra.LRAConstants.COMPENSATE; +import static io.narayana.lra.LRAConstants.COMPLETE; +import static io.narayana.lra.LRAConstants.FORGET; +import static io.narayana.lra.LRAConstants.STATUS; + import io.narayana.lra.AnnotationResolver; import io.narayana.lra.logging.LRALogger; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.Forget; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.eclipse.microprofile.lra.annotation.Status; - import jakarta.enterprise.inject.spi.CDI; import jakarta.ws.rs.DELETE; import jakarta.ws.rs.GET; @@ -34,12 +32,13 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletionStage; - -import static io.narayana.lra.LRAConstants.AFTER; -import static io.narayana.lra.LRAConstants.COMPENSATE; -import static io.narayana.lra.LRAConstants.COMPLETE; -import static io.narayana.lra.LRAConstants.FORGET; -import static io.narayana.lra.LRAConstants.STATUS; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.Forget; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.eclipse.microprofile.lra.annotation.Status; /** * Keeps references to individual non-JAX-RS participant methods in @@ -124,17 +123,17 @@ private void processParticipantMethod(Method method) { if (parameterTypes.length > 2) { throw new IllegalStateException(String.format("%s: %s", - method.toGenericString(), "Participant method cannot have more than 2 arguments")); + method.toGenericString(), "Participant method cannot have more than 2 arguments")); } if (parameterTypes.length > 0 && !parameterTypes[0].equals(URI.class)) { throw new IllegalStateException(String.format("%s: %s", - method.toGenericString(), "Invalid argument type in LRA participant method: " + parameterTypes[0])); + method.toGenericString(), "Invalid argument type in LRA participant method: " + parameterTypes[0])); } if (parameterTypes.length > 1 && !parameterTypes[1].equals(URI.class)) { throw new IllegalStateException(String.format("%s: %s", - method.toGenericString(), "Invalid argument type in LRA participant method: " + parameterTypes[1])); + method.toGenericString(), "Invalid argument type in LRA participant method: " + parameterTypes[1])); } } @@ -146,23 +145,23 @@ private boolean setAfterLRAAnnotation(Method method) { // spec defined signature is "void afterLRA(URI, LRAStatus) if (!method.getReturnType().equals(Void.TYPE)) { throw new IllegalStateException(String.format("%s: %s", - method.toGenericString(), "Invalid return type for @AfterLRA method: " + method.getReturnType())); + method.toGenericString(), "Invalid return type for @AfterLRA method: " + method.getReturnType())); } Class[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length > 2) { throw new IllegalStateException(String.format("%s: %s", - method.toGenericString(), "@AfterLRA method cannot have more than 2 arguments")); + method.toGenericString(), "@AfterLRA method cannot have more than 2 arguments")); } if (parameterTypes.length > 0 && !parameterTypes[0].equals(URI.class)) { throw new IllegalStateException(String.format("%s: %s", - method.toGenericString(), "Invalid first argument of @AfterLRA method: " + parameterTypes[0])); + method.toGenericString(), "Invalid first argument of @AfterLRA method: " + parameterTypes[0])); } if (parameterTypes.length > 1 && !parameterTypes[1].equals(LRAStatus.class)) { throw new IllegalStateException(String.format("%s: %s", - method.toGenericString(), "Invalid second argument of @AfterLRA method: " + parameterTypes[1])); + method.toGenericString(), "Invalid second argument of @AfterLRA method: " + parameterTypes[1])); } afterLRAMethod = method; @@ -171,11 +170,11 @@ private boolean setAfterLRAAnnotation(Method method) { private boolean isJaxRsMethod(Method method) { return AnnotationResolver.isAnnotationPresent(GET.class, method) || - AnnotationResolver.isAnnotationPresent(POST.class, method) || - AnnotationResolver.isAnnotationPresent(PUT.class, method) || - AnnotationResolver.isAnnotationPresent(DELETE.class, method) || - AnnotationResolver.isAnnotationPresent(HEAD.class, method) || - AnnotationResolver.isAnnotationPresent(OPTIONS.class, method); + AnnotationResolver.isAnnotationPresent(POST.class, method) || + AnnotationResolver.isAnnotationPresent(PUT.class, method) || + AnnotationResolver.isAnnotationPresent(DELETE.class, method) || + AnnotationResolver.isAnnotationPresent(HEAD.class, method) || + AnnotationResolver.isAnnotationPresent(OPTIONS.class, method); } private boolean setParticipantAnnotation(Method method) { @@ -209,12 +208,12 @@ private void verifyReturnType(Method method) { private void verifyReturnType(Class returnType, String methodGenericString, boolean inCompletionStage) { if (!returnType.equals(Void.TYPE) && - !returnType.equals(Void.class) && - !returnType.equals(ParticipantStatus.class) && - !returnType.equals(Response.class)) { + !returnType.equals(Void.class) && + !returnType.equals(ParticipantStatus.class) && + !returnType.equals(Response.class)) { throw new IllegalStateException(String.format("%s: %s", - methodGenericString, "Invalid return type for participant method " - + (inCompletionStage ? "CompletionStage<" + returnType + ">" : returnType))); + methodGenericString, "Invalid return type for participant method " + + (inCompletionStage ? "CompletionStage<" + returnType + ">" : returnType))); } } @@ -227,7 +226,7 @@ private Response processCompletionStageResult(Method method, URI lraId, URI pare if (shouldInvokeParticipantMethod(result)) { LRALogger.i18nLogger.warn_participantReturnsImmediateStateFromCompletionStage( - getJavaClass().getName(), lraId.toASCIIString()); + getJavaClass().getName(), lraId.toASCIIString()); return invokeParticipantMethod(method, lraId, parentId, type); } @@ -249,7 +248,7 @@ private boolean shouldInvokeParticipantMethod(Object result) { } private Response invokeParticipantMethod(Method method, URI lraId, - URI parentId, String type) { + URI parentId, String type) { Object participant = getInstance(); Object result; @@ -265,7 +264,7 @@ private Response invokeParticipantMethod(Method method, URI lraId, break; default: throw new IllegalStateException( - method.toGenericString() + ": invalid number of arguments: " + method.getParameterCount()); + method.toGenericString() + ": invalid number of arguments: " + method.getParameterCount()); } return processResult(result, lraId, method, type); @@ -290,11 +289,11 @@ private Response processResult(Object result, URI lraId, Method method, String t // store the CompletionStage result and respond compensating / completing participantStatusMap.put(lraId, new ParticipantResult(getCompletionStageActualType(method))); ((CompletionStage) result) - .thenAccept(res -> participantStatusMap.get(lraId).setValue(res)) - .exceptionally(throwable -> { - participantStatusMap.get(lraId).setValue(throwable); - return null; - }); + .thenAccept(res -> participantStatusMap.get(lraId).setValue(res)) + .exceptionally(throwable -> { + participantStatusMap.get(lraId).setValue(throwable); + return null; + }); return Response.status(Response.Status.ACCEPTED).build(); } @@ -352,9 +351,9 @@ public void setInstance(Object instance) { public void augmentTerminationURIs(Map terminateURIs, URI baseUri) { String baseURI = UriBuilder.fromUri(baseUri) - .path(LRAParticipantResource.RESOURCE_PATH) - .path(javaClass.getName()) - .build().toASCIIString(); + .path(LRAParticipantResource.RESOURCE_PATH) + .path(javaClass.getName()) + .build().toASCIIString(); if (!terminateURIs.containsKey(COMPLETE) && completeMethod != null) { terminateURIs.put(COMPLETE, getURI(baseURI, COMPLETE)); @@ -383,10 +382,10 @@ private String getURI(String baseURI, String path) { boolean hasNonJaxRsMethods() { return compensateMethod != null || - completeMethod != null || - statusMethod != null || - forgetMethod != null || - afterLRAMethod != null; + completeMethod != null || + statusMethod != null || + forgetMethod != null || + afterLRAMethod != null; } private static Class getCompletionStageActualType(Method method) { diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantRegistry.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantRegistry.java index 83b38c5100..0664daa3f0 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantRegistry.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantRegistry.java @@ -26,6 +26,6 @@ public LRAParticipantRegistry(Map lraParticipants) { } public LRAParticipant getParticipant(String id) { - return lraParticipants.get(id); + return lraParticipants.get(id); } } diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantResource.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantResource.java index 800f1c8bfe..ebccd1367a 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantResource.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/LRAParticipantResource.java @@ -5,14 +5,16 @@ package io.narayana.lra.client.internal.proxy.nonjaxrs; -import io.narayana.lra.proxy.logging.LRAProxyLogger; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.Forget; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.Status; +import static io.narayana.lra.LRAConstants.AFTER; +import static io.narayana.lra.LRAConstants.COMPENSATE; +import static io.narayana.lra.LRAConstants.COMPLETE; +import static io.narayana.lra.LRAConstants.FORGET; +import static io.narayana.lra.LRAConstants.STATUS; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_ENDED_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER; +import io.narayana.lra.proxy.logging.LRAProxyLogger; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.DELETE; @@ -26,15 +28,12 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.net.URI; - -import static io.narayana.lra.LRAConstants.AFTER; -import static io.narayana.lra.LRAConstants.COMPENSATE; -import static io.narayana.lra.LRAConstants.COMPLETE; -import static io.narayana.lra.LRAConstants.FORGET; -import static io.narayana.lra.LRAConstants.STATUS; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_ENDED_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.Forget; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.Status; @ApplicationScoped @Path(LRAParticipantResource.RESOURCE_PATH) @@ -50,8 +49,8 @@ public class LRAParticipantResource { @Produces(MediaType.TEXT_PLAIN) @Compensate public Response compensate(@PathParam("participantId") String participantId, - @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { return getParticipant(participantId).compensate(createURI(lraId), createURI(parentId)); } @@ -60,8 +59,8 @@ public Response compensate(@PathParam("participantId") String participantId, @Produces(MediaType.TEXT_PLAIN) @Complete public Response complete(@PathParam("participantId") String participantId, - @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { return getParticipant(participantId).complete(createURI(lraId), createURI(parentId)); } @@ -70,8 +69,8 @@ public Response complete(@PathParam("participantId") String participantId, @Produces(MediaType.TEXT_PLAIN) @Status public Response status(@PathParam("participantId") String participantId, - @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { return getParticipant(participantId).status(createURI(lraId), createURI(parentId)); } @@ -80,8 +79,8 @@ public Response status(@PathParam("participantId") String participantId, @Produces(MediaType.TEXT_PLAIN) @Forget public Response forget(@PathParam("participantId") String participantId, - @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, - @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, + @HeaderParam(LRA_HTTP_PARENT_CONTEXT_HEADER) String parentId) { return getParticipant(participantId).forget(createURI(lraId), createURI(parentId)); } @@ -89,8 +88,8 @@ public Response forget(@PathParam("participantId") String participantId, @Path("{participantId}/" + AFTER) @AfterLRA public Response afterLRA(@PathParam("participantId") String participantId, - @HeaderParam(LRA_HTTP_ENDED_CONTEXT_HEADER) URI lraId, - LRAStatus lraStatus) { + @HeaderParam(LRA_HTTP_ENDED_CONTEXT_HEADER) URI lraId, + LRAStatus lraStatus) { return getParticipant(participantId).afterLRA(lraId, lraStatus); } diff --git a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/jandex/JandexAnnotationResolver.java b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/jandex/JandexAnnotationResolver.java index 314dd44b3b..e6492cc419 100644 --- a/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/jandex/JandexAnnotationResolver.java +++ b/proxy/api/src/main/java/io/narayana/lra/client/internal/proxy/nonjaxrs/jandex/JandexAnnotationResolver.java @@ -5,15 +5,14 @@ package io.narayana.lra.client.internal.proxy.nonjaxrs.jandex; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.Index; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class JandexAnnotationResolver { public static Map> getAllAnnotationsFromClassInfoHierarchy(DotName name, Index index) { diff --git a/proxy/api/src/main/java/io/narayana/lra/proxy/logging/lraI18NLogger.java b/proxy/api/src/main/java/io/narayana/lra/proxy/logging/lraI18NLogger.java index 1ff4378d8f..42f43a13a2 100644 --- a/proxy/api/src/main/java/io/narayana/lra/proxy/logging/lraI18NLogger.java +++ b/proxy/api/src/main/java/io/narayana/lra/proxy/logging/lraI18NLogger.java @@ -8,7 +8,6 @@ import static org.jboss.logging.Logger.Level.ERROR; import java.util.concurrent.ExecutionException; - import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; @@ -21,10 +20,10 @@ public interface lraI18NLogger { /* - Message IDs are unique and non-recyclable. - Don't change the purpose of existing messages. - (tweak the message text or params for clarification if you like). - Allocate new messages by following instructions at the bottom of the file. + * Message IDs are unique and non-recyclable. + * Don't change the purpose of existing messages. + * (tweak the message text or params for clarification if you like). + * Allocate new messages by following instructions at the bottom of the file. */ @Message(id = 25001, value = "Participant '%s' serialization problem") @LogMessage(level = ERROR) @@ -41,16 +40,16 @@ public interface lraI18NLogger { String error_missingParticipant(String participant); /* - Allocate new messages directly above this notice. - - id: use the next id number in numeric sequence. Don't reuse ids. - The first two digits of the id(XXyyy) denote the module - all message in this file should have the same prefix. - - value: default (English) version of the log message. - - level: according to severity semantics - - Debug and trace don't get i18n. Everything else MUST be i18n. - By convention methods with String return type have prefix get_, - all others are log methods and have prefix _ + * Allocate new messages directly above this notice. + * - id: use the next id number in numeric sequence. Don't reuse ids. + * The first two digits of the id(XXyyy) denote the module + * all message in this file should have the same prefix. + * - value: default (English) version of the log message. + * - level: according to severity semantics + * + * Debug and trace don't get i18n. Everything else MUST be i18n. + * By convention methods with String return type have prefix get_, + * all others are log methods and have prefix _ */ } diff --git a/proxy/test/src/main/java/io/narayana/lra/proxy/test/api/LRAMgmtEgController.java b/proxy/test/src/main/java/io/narayana/lra/proxy/test/api/LRAMgmtEgController.java index 6731ec29e6..7152af8875 100644 --- a/proxy/test/src/main/java/io/narayana/lra/proxy/test/api/LRAMgmtEgController.java +++ b/proxy/test/src/main/java/io/narayana/lra/proxy/test/api/LRAMgmtEgController.java @@ -5,11 +5,12 @@ package io.narayana.lra.proxy.test.api; +import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.LRAM_PATH; + import io.narayana.lra.client.internal.proxy.ProxyService; import io.narayana.lra.proxy.test.model.Activity; import io.narayana.lra.proxy.test.model.Participant; import io.narayana.lra.proxy.test.service.ActivityService; - import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.PUT; @@ -18,13 +19,10 @@ import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; - import java.net.URI; import java.net.URISyntaxException; import java.time.temporal.ChronoUnit; -import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.LRAM_PATH; - /** * for testing {@link io.narayana.lra.client.internal.proxy.ProxyService} */ diff --git a/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Activity.java b/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Activity.java index 22016f65e3..5c1d1866c0 100644 --- a/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Activity.java +++ b/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Activity.java @@ -5,11 +5,10 @@ package io.narayana.lra.proxy.test.model; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; - import java.io.Serializable; import java.net.URI; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; public class Activity implements Serializable { public String id; @@ -64,7 +63,6 @@ public void setAcceptedCount(int acceptedCount) { this.acceptedCount.set(acceptedCount); } - public int getAndDecrementAcceptCount() { return acceptedCount.getAndDecrement(); } diff --git a/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Participant.java b/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Participant.java index ae5b3cbba9..9dd927576c 100644 --- a/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Participant.java +++ b/proxy/test/src/main/java/io/narayana/lra/proxy/test/model/Participant.java @@ -6,12 +6,11 @@ package io.narayana.lra.proxy.test.model; import io.narayana.lra.client.internal.proxy.LRAProxyParticipant; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; - import jakarta.ws.rs.NotFoundException; import java.io.Serializable; import java.net.URI; import java.util.concurrent.Future; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; public class Participant implements LRAProxyParticipant, Serializable { private Activity activity; diff --git a/proxy/test/src/main/java/io/narayana/lra/proxy/test/service/ActivityService.java b/proxy/test/src/main/java/io/narayana/lra/proxy/test/service/ActivityService.java index b9da83d4e4..5384503241 100644 --- a/proxy/test/src/main/java/io/narayana/lra/proxy/test/service/ActivityService.java +++ b/proxy/test/src/main/java/io/narayana/lra/proxy/test/service/ActivityService.java @@ -5,8 +5,9 @@ package io.narayana.lra.proxy.test.service; -import io.narayana.lra.proxy.test.model.Activity; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import io.narayana.lra.proxy.test.model.Activity; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.Response; @@ -15,8 +16,6 @@ import java.util.List; import java.util.Map; -import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; - @ApplicationScoped public class ActivityService { private Map activities = new HashMap<>(); diff --git a/proxy/test/src/test/java/io/narayana/lra/participant/SpecTest.java b/proxy/test/src/test/java/io/narayana/lra/participant/SpecTest.java index b87bfa4b8a..412b146f36 100644 --- a/proxy/test/src/test/java/io/narayana/lra/participant/SpecTest.java +++ b/proxy/test/src/test/java/io/narayana/lra/participant/SpecTest.java @@ -5,28 +5,24 @@ package io.narayana.lra.participant; -import io.narayana.lra.client.internal.NarayanaLRAClient; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; +import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.GET_ACTIVITY_PATH; +import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.LRAM_PATH; +import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.LRAM_WORK; +import static org.junit.Assert.assertTrue; +import io.narayana.lra.client.internal.NarayanaLRAClient; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.Response; - import java.net.URI; import java.net.URL; - -import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.GET_ACTIVITY_PATH; -import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.LRAM_PATH; -import static io.narayana.lra.proxy.test.api.LRAMgmtEgController.LRAM_WORK; - -import static org.junit.Assert.assertTrue; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; public class SpecTest { private static URL MICROSERVICE_BASE_URL; @@ -93,16 +89,16 @@ public void testLRAMgmt() { assertTrue(activity.contains("status=Completed")); } - private String checkStatusAndClose(Response response, int expected, boolean readEntity) { - try (response) { - if (expected != -1 && response.getStatus() != expected) { - throw new WebApplicationException(response); - } + private String checkStatusAndClose(Response response, int expected, boolean readEntity) { + try (response) { + if (expected != -1 && response.getStatus() != expected) { + throw new WebApplicationException(response); + } - if (readEntity) { - return response.readEntity(String.class); - } - } + if (readEntity) { + return response.readEntity(String.class); + } + } return null; } diff --git a/service-base/src/main/java/io/narayana/lra/AnnotationResolver.java b/service-base/src/main/java/io/narayana/lra/AnnotationResolver.java index 739866fd98..83f46c511d 100644 --- a/service-base/src/main/java/io/narayana/lra/AnnotationResolver.java +++ b/service-base/src/main/java/io/narayana/lra/AnnotationResolver.java @@ -54,7 +54,8 @@ public static boolean isAnnotationPresent(Class annotation return resolveAnnotation(annotationClass, method) != null; } - private static T resolveAnnotationInSuperClass(Class annotationClass, Method method, Class clazz) { + private static T resolveAnnotationInSuperClass(Class annotationClass, Method method, + Class clazz) { if (clazz == null) { return null; } @@ -62,13 +63,15 @@ private static T resolveAnnotationInSuperClass(Class a try { Method superclassMethod = clazz.getMethod(method.getName(), method.getParameterTypes()); T annotation = superclassMethod.getAnnotation(annotationClass); - return annotation != null ? annotation : resolveAnnotationInSuperClass(annotationClass, method, clazz.getSuperclass()); + return annotation != null ? annotation + : resolveAnnotationInSuperClass(annotationClass, method, clazz.getSuperclass()); } catch (NoSuchMethodException e) { return resolveAnnotationInSuperClass(annotationClass, method, clazz.getSuperclass()); } } - private static T resolveAnnotationInInterfaces(Class annotationClass, Method method, Class clazz) { + private static T resolveAnnotationInInterfaces(Class annotationClass, Method method, + Class clazz) { if (clazz == null) { return null; } diff --git a/service-base/src/main/java/io/narayana/lra/Current.java b/service-base/src/main/java/io/narayana/lra/Current.java index e9f23fcc10..47f81dbcc2 100644 --- a/service-base/src/main/java/io/narayana/lra/Current.java +++ b/service-base/src/main/java/io/narayana/lra/Current.java @@ -5,6 +5,11 @@ package io.narayana.lra; +import static io.narayana.lra.LRAConstants.PARENT_LRA_PARAM_NAME; +import static io.narayana.lra.LRAConstants.QUERY_FIELD_SEPARATOR; +import static io.narayana.lra.LRAConstants.QUERY_PAIR_SEPARATOR; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; + import jakarta.ws.rs.container.ContainerResponseContext; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.UriBuilder; @@ -20,11 +25,6 @@ import java.util.Stack; import java.util.concurrent.ConcurrentHashMap; -import static io.narayana.lra.LRAConstants.PARENT_LRA_PARAM_NAME; -import static io.narayana.lra.LRAConstants.QUERY_FIELD_SEPARATOR; -import static io.narayana.lra.LRAConstants.QUERY_PAIR_SEPARATOR; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; - // similar to ThreadActionData except it need to be available on the client side // for use by NarayanaLRAClient and ServerLRAFilter public class Current { @@ -245,6 +245,7 @@ private static boolean isParentOf(URI parent, URI child) { /** * push the current context onto the stack of contexts for this thread + * * @param lraId id of context to push (must not be null) */ public static void push(URI lraId) { diff --git a/service-base/src/main/java/io/narayana/lra/LRAConstants.java b/service-base/src/main/java/io/narayana/lra/LRAConstants.java index c0c9215b69..340e011a87 100644 --- a/service-base/src/main/java/io/narayana/lra/LRAConstants.java +++ b/service-base/src/main/java/io/narayana/lra/LRAConstants.java @@ -6,7 +6,6 @@ package io.narayana.lra; import io.narayana.lra.logging.LRALogger; - import java.net.URI; import java.net.URISyntaxException; import java.util.regex.Pattern; @@ -75,8 +74,8 @@ private LRAConstants() { /** * Extract the uid part from an LRA id. * - * @param lraId LRA id to extract the uid from - * @return uid of LRA + * @param lraId LRA id to extract the uid from + * @return uid of LRA */ public static String getLRAUid(String lraId) { return lraId == null ? null : UID_REGEXP_EXTRACT_MATCHER.matcher(lraId).replaceFirst("$1"); @@ -85,31 +84,38 @@ public static String getLRAUid(String lraId) { /** * Extract the uid part from an LRA id. * - * @param lraId LRA id to extract the uid from - * @return uid of LRA + * @param lraId LRA id to extract the uid from + * @return uid of LRA */ public static String getLRAUid(URI lraId) { - if (lraId == null) return null; + if (lraId == null) + return null; String path = lraId.getPath(); - if (path == null) return null; + if (path == null) + return null; return path.substring(path.lastIndexOf('/') + 1); } /* * Extract the coordinator URL from the provided LRA id. * - * @implNote Narayana LRA id is defined as an URL, e.g. {@code http://localhost:8080/deployment/lra-coordinator/0_ffff0a28054b_9133_5f855916_a7}. - * The LRA coordinator is available at {@code http://localhost:8080/deployment/lra-coordinator} - * and the {@code 0_ffff0a28054b_9133_5f855916_a7} is the LRA uid. + * @implNote Narayana LRA id is defined as an URL, e.g. {@code + * http://localhost:8080/deployment/lra-coordinator/0_ffff0a28054b_9133_5f855916_a7}. + * The LRA coordinator is available at {@code http://localhost:8080/deployment/lra-coordinator} + * and the {@code 0_ffff0a28054b_9133_5f855916_a7} is the LRA uid. + * + * @param lraId LRA id to extract the LRA coordinator URI from * - * @param lraId LRA id to extract the LRA coordinator URI from * @return LRA Coordinator URL + * * @throws IllegalStateException if the LRA coordinator URL, extracted from the LRA id, is not assignable to URI */ public static URI getLRACoordinatorUrl(URI lraId) { - if (lraId == null) return null; + if (lraId == null) + return null; String lraIdPath = lraId.getPath(); - String lraCoordinatorPath = lraIdPath.substring(0, lraIdPath.lastIndexOf(COORDINATOR_PATH_NAME)) + COORDINATOR_PATH_NAME; + String lraCoordinatorPath = lraIdPath.substring(0, lraIdPath.lastIndexOf(COORDINATOR_PATH_NAME)) + + COORDINATOR_PATH_NAME; try { return new URI(lraId.getScheme(), lraId.getUserInfo(), lraId.getHost(), lraId.getPort(), lraCoordinatorPath, null, null); diff --git a/service-base/src/main/java/io/narayana/lra/LRAData.java b/service-base/src/main/java/io/narayana/lra/LRAData.java index 5f556d6c1d..6c0458eea0 100644 --- a/service-base/src/main/java/io/narayana/lra/LRAData.java +++ b/service-base/src/main/java/io/narayana/lra/LRAData.java @@ -5,10 +5,9 @@ package io.narayana.lra; -import org.eclipse.microprofile.lra.annotation.LRAStatus; - import java.beans.Transient; import java.net.URI; +import org.eclipse.microprofile.lra.annotation.LRAStatus; /** * DTO object which serves to transfer data of particular LRA instance. @@ -25,10 +24,11 @@ public class LRAData { private long finishTime; private int httpStatus; - public LRAData() {} + public LRAData() { + } public LRAData(URI lraId, String clientId, LRAStatus status, boolean isTopLevel, boolean isRecovering, - long startTime, long finishTime, int httpStatus) { + long startTime, long finishTime, int httpStatus) { this.lraId = lraId; this.clientId = clientId; this.status = status; @@ -126,7 +126,7 @@ public int hashCode() { @Override public String toString() { return String.format( - "%s {lraId='%s', clientId='%s', status='%s', isTopLevel=%b, isRecovering=%b, startTime=%d, finishTime=%d, httpStatus=%d}", + "%s {lraId='%s', clientId='%s', status='%s', isTopLevel=%b, isRecovering=%b, startTime=%d, finishTime=%d, httpStatus=%d}", this.getClass().getSimpleName(), lraId, clientId, status, isTopLevel, isRecovering, startTime, finishTime, httpStatus); } diff --git a/service-base/src/main/java/io/narayana/lra/logging/LraI18nLogger.java b/service-base/src/main/java/io/narayana/lra/logging/LraI18nLogger.java index cc151d7632..b3c319f4c6 100644 --- a/service-base/src/main/java/io/narayana/lra/logging/LraI18nLogger.java +++ b/service-base/src/main/java/io/narayana/lra/logging/LraI18nLogger.java @@ -11,7 +11,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; - import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; @@ -24,10 +23,10 @@ public interface LraI18nLogger { /* - Message IDs are unique and non-recyclable. - Don't change the purpose of existing messages. - (tweak the message text or params for clarification if you like). - Allocate new messages by following instructions at the bottom of the file. + * Message IDs are unique and non-recyclable. + * Don't change the purpose of existing messages. + * (tweak the message text or params for clarification if you like). + * Allocate new messages by following instructions at the bottom of the file. */ @Message(id = 25001, value = "LRA created with an unexpected status code: %d, coordinator response '%s'") String error_lraCreationUnexpectedStatus(int status, String response); @@ -123,10 +122,10 @@ String info_failedToEnlistingLRANotFound(URL lraId, URI coordinatorUri, int coor @Message(id = 25029, value = "Cannot notify AfterLRA URL at %s") void warn_cannotNotifyAfterLRAURI(URI target, @Cause Throwable t); - @Message(id=25030, value = "%s: Invalid link URI (%s): %s") + @Message(id = 25030, value = "%s: Invalid link URI (%s): %s") String error_invalidCompensator(URI id, String reason, String linkURI); - @Message(id=25031, value = "%s: Invalid link URI (%s): missing compensator or after LRA callback") + @Message(id = 25031, value = "%s: Invalid link URI (%s): missing compensator or after LRA callback") String error_missingCompensator(URI id, String linkURI); @Message(id = 25032, value = "LRA Record: Cannot save state (reason: %s)") @@ -176,16 +175,16 @@ String info_failedToEnlistingLRANotFound(URL lraId, URI coordinatorUri, int coor String warn_timelimit_too_long(long timeLimit, long newTimeLimit); /* - Allocate new messages directly above this notice. - - id: use the next id number in numeric sequence. Don't reuse ids. - The first two digits of the id(XXyyy) denote the module - all message in this file should have the same prefix. - - value: default (English) version of the log message. - - level: according to severity semantics - - Debug and trace don't get i18n. Everything else MUST be i18n. - By convention methods with String return type have prefix get_, - all others are log methods and have prefix _ + * Allocate new messages directly above this notice. + * - id: use the next id number in numeric sequence. Don't reuse ids. + * The first two digits of the id(XXyyy) denote the module + * all message in this file should have the same prefix. + * - value: default (English) version of the log message. + * - level: according to severity semantics + * + * Debug and trace don't get i18n. Everything else MUST be i18n. + * By convention methods with String return type have prefix get_, + * all others are log methods and have prefix _ */ } diff --git a/service-base/src/test/java/io/narayana/lra/LRAConstantsTest.java b/service-base/src/test/java/io/narayana/lra/LRAConstantsTest.java index 34da6d4c86..c0107520f9 100644 --- a/service-base/src/test/java/io/narayana/lra/LRAConstantsTest.java +++ b/service-base/src/test/java/io/narayana/lra/LRAConstantsTest.java @@ -5,11 +5,10 @@ package io.narayana.lra; +import java.net.URI; import org.junit.Assert; import org.junit.Test; -import java.net.URI; - public class LRAConstantsTest { @Test diff --git a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/ArquillianParametrized.java b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/ArquillianParametrized.java index 75990b61cb..e2c89fef07 100644 --- a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/ArquillianParametrized.java +++ b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/ArquillianParametrized.java @@ -5,6 +5,11 @@ package io.narayana.lra.arquillian; +import java.lang.reflect.Field; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import org.jboss.arquillian.junit.Arquillian; import org.junit.Ignore; import org.junit.runner.Description; @@ -14,11 +19,6 @@ import org.junit.runners.model.FrameworkField; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; -import java.lang.reflect.Field; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; /** * Parameterized Arquillian JUnit runner adding the possibility to run parameterized JUnit test cases , @@ -88,7 +88,8 @@ private Object createTestUsingFieldInjection() throws Exception { List annotatedFieldsByParameter = getAnnotatedFieldsByParameter(); if (annotatedFieldsByParameter.size() != fParameters.length) { throw new Exception("Wrong number of parameters and @Parameter fields." + - " @Parameter fields counted: " + annotatedFieldsByParameter.size() + ", available parameters: " + fParameters.length + "."); + " @Parameter fields counted: " + annotatedFieldsByParameter.size() + ", available parameters: " + + fParameters.length + "."); } Object testClassInstance = getTestClass().getJavaClass().getDeclaredConstructor().newInstance(); for (FrameworkField each : annotatedFieldsByParameter) { @@ -137,8 +138,7 @@ protected void validateFields(List errors) { errors.add( new Exception("Invalid @Parameter value: " + index + ". @Parameter fields counted: " + annotatedFieldsByParameter.size() + ". Please use an index between 0 and " + - (annotatedFieldsByParameter.size() - 1) + ".") - ); + (annotatedFieldsByParameter.size() - 1) + ".")); } else { usedIndices[index]++; } @@ -163,8 +163,8 @@ private Iterable allParameters() throws Throwable { if (iter.hasNext()) { if (!(iter.next() instanceof Object[])) { // it's single value List multiValue = new ArrayList<>(); - for (Object parameter: (Iterable) parameters) { - multiValue.add(new Object[]{parameter}); + for (Object parameter : (Iterable) parameters) { + multiValue.add(new Object[] { parameter }); } return multiValue; } @@ -189,7 +189,7 @@ private FrameworkMethod getParametersMethod() throws Exception { } private void createRunnersForParameters(Iterable allParameters, - String namePattern) throws InitializationError, Exception { + String namePattern) throws InitializationError, Exception { try { int i = 0; for (Object[] parametersOfSingleTest : allParameters) { diff --git a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/MpLraTckExtension.java b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/MpLraTckExtension.java index 5d8f4d7e82..7230d93913 100644 --- a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/MpLraTckExtension.java +++ b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/MpLraTckExtension.java @@ -12,7 +12,7 @@ /** * This class is the activation point to use {@link MpLraTckAuxiliaryArchiveAppender}. */ -public class MpLraTckExtension implements LoadableExtension { +public class MpLraTckExtension implements LoadableExtension { @Override public void register(ExtensionBuilder extensionBuilder) { diff --git a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/appender/MpLraTckAuxiliaryArchiveAppender.java b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/appender/MpLraTckAuxiliaryArchiveAppender.java index b4a0f95b20..2b02b844d5 100644 --- a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/appender/MpLraTckAuxiliaryArchiveAppender.java +++ b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/appender/MpLraTckAuxiliaryArchiveAppender.java @@ -6,6 +6,8 @@ package io.narayana.lra.arquillian.appender; import io.narayana.lra.arquillian.spi.NarayanaLRARecovery; +import java.util.Map; +import java.util.Optional; import org.jboss.arquillian.config.descriptor.api.ArquillianDescriptor; import org.jboss.arquillian.config.descriptor.api.ExtensionDef; import org.jboss.arquillian.container.test.spi.client.deployment.AuxiliaryArchiveAppender; @@ -16,18 +18,22 @@ import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; -import java.util.Map; -import java.util.Optional; - /** - *

As the MicroProfile LRA TCK is implementation agnostic, deployments created within the TCK must be + *

+ * As the MicroProfile LRA TCK is implementation agnostic, deployments created within the TCK must be * enriched with dependencies, services and other needed properties/files in order to run the Narayana * implementation of the MicroProfile LRA specification. This class is an ad-hoc AuxiliaryArchiveAppender - * developed exactly for this purpose and it can be activated specifying the activation class {@link io.narayana.lra.arquillian.MpLraTckExtension} + * developed exactly for this purpose and it can be activated specifying the activation class + * {@link io.narayana.lra.arquillian.MpLraTckExtension} * in src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension. Moreover, this - * extension is activated when an extension section is defined in arquillian.xml of the module

- *

To activate this extension in your arquillian.xml, use the following construct:

- *

{@code }

+ * extension is activated when an extension section is defined in arquillian.xml of the module + *

+ *

+ * To activate this extension in your arquillian.xml, use the following construct: + *

+ *

+ * {@code } + *

*/ public class MpLraTckAuxiliaryArchiveAppender implements AuxiliaryArchiveAppender { @@ -69,7 +75,8 @@ public Archive createAuxiliaryArchive() { // registration of LRACDIExtension as Weld extension to be booted-up .addAsResource("META-INF/services/jakarta.enterprise.inject.spi.Extension") // explicitly define to work with annotated beans - .addAsManifestResource(new StringAsset(""), "beans.xml") + .addAsManifestResource(new StringAsset(""), + "beans.xml") // for WildFly we need dependencies to be part of the deployment's class path .addAsManifestResource(new StringAsset(ManifestMF), "MANIFEST.MF"); @@ -80,7 +87,7 @@ public Archive createAuxiliaryArchive() { archive.addPackages(true, io.narayana.lra.filter.ClientLRARequestFilter.class.getPackage()) .addAsResource(new StringAsset(filtersAsset), "META-INF/services/jakarta.ws.rs.ext.Providers") .addAsResource(new StringAsset("org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder"), - "META-INF/services/jakarta.ws.rs.client.ClientBuilder"); + "META-INF/services/jakarta.ws.rs.client.ClientBuilder"); // adding TCK required SPI implementation archive.addClass(NarayanaLRARecovery.class); @@ -90,4 +97,4 @@ public Archive createAuxiliaryArchive() { return archive; } -} \ No newline at end of file +} diff --git a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/WildflyLRACoordinatorDeployment.java b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/WildflyLRACoordinatorDeployment.java index 6651bf2fe9..09e122dce8 100644 --- a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/WildflyLRACoordinatorDeployment.java +++ b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/WildflyLRACoordinatorDeployment.java @@ -61,11 +61,11 @@ public Archive create(String deploymentName) { "org.jboss.narayana.lra:lra-service-base:" + projectVersion) .withoutTransitivity().asFile()) // Adds a manifest to activate jts and logging submodules of Wildfly - .addAsManifestResource(new StringAsset(ManifestMF),"MANIFEST.MF") + .addAsManifestResource(new StringAsset(ManifestMF), "MANIFEST.MF") // Adds an empty beans.xml to activate the bean in discovery-mode set to "all" - .addAsWebInfResource(EmptyAsset.INSTANCE,"beans.xml"); + .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); - if(log.isDebugEnabled()) { + if (log.isDebugEnabled()) { log.debugf("Content of the LRA Coordinator WAR is:%n%s%n", war.toString(Formatters.VERBOSE)); } diff --git a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/LRACoordinatorScenarioGenerator.java b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/LRACoordinatorScenarioGenerator.java index 5fa10956fa..9cafe181eb 100644 --- a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/LRACoordinatorScenarioGenerator.java +++ b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/LRACoordinatorScenarioGenerator.java @@ -6,6 +6,9 @@ package io.narayana.lra.arquillian.deployment.scenario; import io.narayana.lra.arquillian.deployment.WildflyLRACoordinatorDeployment; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import org.jboss.arquillian.config.descriptor.api.ContainerDef; import org.jboss.arquillian.config.descriptor.api.GroupDef; import org.jboss.arquillian.container.spi.client.deployment.DeploymentDescription; @@ -14,25 +17,37 @@ import org.jboss.arquillian.test.spi.TestClass; import org.jboss.shrinkwrap.api.spec.WebArchive; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - /** - *

This class is an implementation of Arquillian SPI DeploymentScenarioGenerator. The purpose of this class + *

+ * This class is an implementation of Arquillian SPI DeploymentScenarioGenerator. The purpose of this class * is creating an lra-coordinator DeploymentDescription to be deployed to a specific container. The information * identifying the container are fetched from arquillian.xml in the module that uses LRACoordinatoExtension. * Properties have to be specified according with the pre-fixed names within this class. Moreover, if the extension * is activated in the file src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension * but there is not mention of the extension in arquillian.xml, this extension returns without generating a - * DeploymentDescription.

- *

To activate this extension in your arquillian.xml, use the following construct:

- *

{@code }

- *

{@code ...}

- *

{@code ...}

- *

{@code ...}

- *

{@code ...}

- *

{@code }

+ * DeploymentDescription. + *

+ *

+ * To activate this extension in your arquillian.xml, use the following construct: + *

+ *

+ * {@code } + *

+ *

+ * {@code ...} + *

+ *

+ * {@code ...} + *

+ *

+ * {@code ...} + *

+ *

+ * {@code ...} + *

+ *

+ * {@code } + *

*/ public class LRACoordinatorScenarioGenerator extends ScenarioGeneratorBase implements DeploymentScenarioGenerator { @@ -85,11 +100,12 @@ public List generate(TestClass testClass) { String containerName = container.getContainerName(); - WebArchive archive = (WebArchive) new WildflyLRACoordinatorDeployment().create(extensionProperties.get(EXTENSION_DEPLOYMENT_NAME)); + WebArchive archive = (WebArchive) new WildflyLRACoordinatorDeployment() + .create(extensionProperties.get(EXTENSION_DEPLOYMENT_NAME)); - DeploymentDescription deploymentDescription = - new DeploymentDescription(extensionProperties.get(EXTENSION_DEPLOYMENT_NAME), archive) - .setTarget(new TargetDescription(containerName)); + DeploymentDescription deploymentDescription = new DeploymentDescription( + extensionProperties.get(EXTENSION_DEPLOYMENT_NAME), archive) + .setTarget(new TargetDescription(containerName)); deploymentDescription.shouldBeTestable(Boolean.parseBoolean(extensionProperties.get(EXTENSION_TESTABLE))); // Auto-define if the deployment should be managed or unmanaged deploymentDescription.shouldBeManaged(!container.getMode().equals("manual")); diff --git a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/ScenarioGeneratorBase.java b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/ScenarioGeneratorBase.java index ed2c3169f7..40b152208c 100644 --- a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/ScenarioGeneratorBase.java +++ b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/deployment/scenario/ScenarioGeneratorBase.java @@ -6,6 +6,12 @@ package io.narayana.lra.arquillian.deployment.scenario; import io.narayana.lra.arquillian.deployment.Deployment; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; import org.jboss.arquillian.config.descriptor.api.ArquillianDescriptor; import org.jboss.arquillian.config.descriptor.api.ContainerDef; import org.jboss.arquillian.config.descriptor.api.ExtensionDef; @@ -14,26 +20,21 @@ import org.jboss.arquillian.core.api.annotation.Inject; import org.jboss.logging.Logger; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - /** *

- * This class is composed by a collection of methods useful to classes implementing + * This class is composed by a collection of methods useful to classes implementing * the interface DeploymentScenarioGenerator. In particular, this class represents * a main point of control when it comes to classes that use the "extension" section * in the Arquillian.xml file. In fact, this class supplies basic methods to identify * a particular extension section and handle properties defined in it. *

*

- * The concept behind this class comes from the project deploymentscenario, which can be found + * The concept behind this class comes from the project deploymentscenario, which can be found * among the showcases of Arquillian. *

- * @see Arquillian Deployment Scenario + * + * @see Arquillian + * Deployment Scenario */ public class ScenarioGeneratorBase { @@ -45,6 +46,7 @@ public class ScenarioGeneratorBase { /** * This method return a {@link Map} representing the properties defined in the extension * section and identifiable with the parameter extensionName + * * @return {@link Map} representing a set of properties */ Map getExtensionProperties() { @@ -70,6 +72,7 @@ Map getExtensionProperties() { /** * This method checks that the properties in the {@link List} toCheck * are present in the {@link Map} properties + * * @param properties {@link Map} representing the properties of an extension * @param toCheck {@link List} of properties that need to be defined * @throws RuntimeException if a property is not found @@ -91,6 +94,7 @@ void checkPropertiesExistence(final Map properties, final String * This method extracts a {@link Method} that represents a deployment method that * should be called to create an {@link org.jboss.shrinkwrap.api.Archive} to deploy * in an Arquillian container + * * @param properties {@link Map} representing the properties of an extension * @param deploymentMethodPropertyName name of the deployment method property * @return {@link Method} @@ -98,7 +102,7 @@ void checkPropertiesExistence(final Map properties, final String * @throws RuntimeException if anything else goes wrong */ Method getDeploymentMethodFromConfiguration(final Map properties, final String deploymentMethodPropertyName) - throws ClassNotFoundException, RuntimeException{ + throws ClassNotFoundException, RuntimeException { String property = properties.get(deploymentMethodPropertyName).trim(); @@ -141,6 +145,7 @@ Method getDeploymentMethodFromConfiguration(final Map properties /** * This method checks if a container with qualifier name containerName is * listed in the Arquillian.xml file. + * * @param containerName the qualifier name of the container * @return {@link ContainerDef} representing the wanted container * @throws RuntimeException if the container is not found @@ -172,6 +177,7 @@ ContainerDef getContainerWithName(String containerName) /** * This method checks if a container with qualifier name containerName is * listed in the group with qualifier group. + * * @param group the qualifier of the group * @param containerName the qualifier name of the container * @return {@link ContainerDef} representing the wanted container @@ -184,7 +190,8 @@ ContainerDef getContainerWithName(GroupDef group, String containerName) .filter(x -> x.getContainerName().equals(containerName)).collect(Collectors.toList()); if (containers.isEmpty()) { - String message = String.format("%s: there is not a container with qualifier %s in the group %s defined in the %s file!", + String message = String.format( + "%s: there is not a container with qualifier %s in the group %s defined in the %s file!", this.getClass().getSimpleName(), containerName, group.getGroupName(), @@ -200,6 +207,7 @@ ContainerDef getContainerWithName(GroupDef group, String containerName) /** * This method checks if a group with qualifier name groupName is * listed in the Arquillian.xml file. + * * @param groupName the qualifier name of the group * @return {@link GroupDef} representing the wanted group * @throws RuntimeException if the group is not found diff --git a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/spi/NarayanaLRARecovery.java b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/spi/NarayanaLRARecovery.java index 425ab3b1bd..993bc4072c 100644 --- a/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/spi/NarayanaLRARecovery.java +++ b/test/arquillian-extension/src/main/java/io/narayana/lra/arquillian/spi/NarayanaLRARecovery.java @@ -5,20 +5,19 @@ package io.narayana.lra.arquillian.spi; -import io.narayana.lra.LRAConstants; - -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.ConfigProvider; -import org.eclipse.microprofile.lra.tck.service.spi.LRARecoveryService; -import org.jboss.logging.Logger; +import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; +import io.narayana.lra.LRAConstants; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilder; import java.net.URI; -import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; +import org.eclipse.microprofile.lra.tck.service.spi.LRARecoveryService; +import org.jboss.logging.Logger; public class NarayanaLRARecovery implements LRARecoveryService { private static final Logger log = Logger.getLogger(NarayanaLRARecovery.class); @@ -37,8 +36,7 @@ public void waitForCallbacks(URI lraId) { log.trace("waitForCallbacks for: " + lraId.toASCIIString()); try { Thread.sleep(WAIT_CALLBACK_TIMEOUT); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { log.error("waitForCallbacks interrupted by " + e.getMessage()); } } @@ -85,12 +83,11 @@ private static Integer initWaitForCallbackTimeout() { if (config != null) { try { return config.getOptionalValue(WAIT_CALLBACK_TIMEOUT_PROPERTY, Integer.class).orElse(defaultValue); - } - catch (IllegalArgumentException e) { + } catch (IllegalArgumentException e) { log.error("property " + WAIT_CALLBACK_TIMEOUT_PROPERTY + " not set correctly, using the default value: " + defaultValue); } } return defaultValue; } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/Deployer.java b/test/basic/src/test/java/io/narayana/lra/arquillian/Deployer.java index 53291d4b35..1944dfa0bf 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/Deployer.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/Deployer.java @@ -36,7 +36,8 @@ public static WebArchive deploy(String appName, Class... participants) { // activates Wildfly modules .addAsManifestResource(new StringAsset(ManifestMF), "MANIFEST.MF") // activates the bean and explicitly specifies to work with annotated classes - .addAsWebInfResource(new StringAsset(""), "beans.xml") + .addAsWebInfResource(new StringAsset(""), + "beans.xml") .addAsResource(new StringAsset("org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder"), "META-INF/services/jakarta.ws.rs.client.ClientBuilder"); } diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/FailedLRAIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/FailedLRAIT.java index 8d71b6ee20..3dce41ba70 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/FailedLRAIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/FailedLRAIT.java @@ -5,25 +5,22 @@ package io.narayana.lra.arquillian; +import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; +import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.RESET_ACCEPTED_PATH; +import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.SIMPLE_PARTICIPANT_RESOURCE_PATH; +import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.START_LRA_PATH; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.AnyOf.anyOf; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import io.narayana.lra.LRAConstants; import io.narayana.lra.arquillian.resource.LRAParticipantWithStatusURI; import io.narayana.lra.arquillian.resource.LRAParticipantWithoutStatusURI; import io.narayana.lra.arquillian.resource.SimpleLRAParticipant; import io.narayana.lra.arquillian.spi.NarayanaLRARecovery; import io.narayana.lra.coordinator.domain.model.FailedLongRunningAction; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.test.api.ArquillianResource; -import org.jboss.logging.Logger; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.AnyOf.anyOf; -import static org.hamcrest.core.IsEqual.equalTo; - import jakarta.json.Json; import jakarta.json.JsonArray; import jakarta.json.JsonReader; @@ -35,13 +32,15 @@ import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; - -import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.RESET_ACCEPTED_PATH; -import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.SIMPLE_PARTICIPANT_RESOURCE_PATH; -import static io.narayana.lra.LRAConstants.RECOVERY_COORDINATOR_PATH_NAME; -import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.START_LRA_PATH; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.logging.Logger; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; /** * There is a spec requirement to report failed LRAs but the spec only requires that a failure message is reported @@ -154,7 +153,8 @@ public void testCannotDeleteNonFailedLRAs() throws Exception { int status3 = removeFailedLRA(getRecoveryUrl(lraId), "http://example.com"); // there is a difference on handling this url format in different REST Easy versions - assertThat("deleting an LRA in wrong format that JAX-RS understands as non-existent URL binding or as method not-allowed", + assertThat( + "deleting an LRA in wrong format that JAX-RS understands as non-existent URL binding or as method not-allowed", status3, anyOf(equalTo(404), equalTo(405))); int status4 = removeFailedLRA(getRecoveryUrl(lraId), URLEncoder.encode("http://example.com", StandardCharsets.UTF_8)); @@ -223,7 +223,7 @@ private boolean validateFailedRecordMoved(URI lra) { } private URI invokeInTransaction(String resourcePrefix, String resourcePath, int expectedStatus) { - try(Response response = client.target(baseURL.toURI()) + try (Response response = client.target(baseURL.toURI()) .path(resourcePrefix) .path(resourcePath) .request() @@ -276,7 +276,7 @@ private boolean validateStateAndRemove(URI lra, LRAStatus state) { private JsonArray getFailedRecords(URI lra) { String recoveryUrl = getRecoveryUrl(lra); - try (Response response = client.target(recoveryUrl).path("failed").request().get()){ + try (Response response = client.target(recoveryUrl).path("failed").request().get()) { Assert.assertTrue("Missing response body when querying for failed LRAs", response.hasEntity()); String failedLRAs = response.readEntity(String.class); @@ -299,4 +299,4 @@ private int removeFailedLRA(String recoveryUrl, String lra) { return response.getStatus(); } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/FailingParticipantCallsIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/FailingParticipantCallsIT.java index d663483133..4e3ee2edb3 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/FailingParticipantCallsIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/FailingParticipantCallsIT.java @@ -7,6 +7,12 @@ import io.narayana.lra.arquillian.resource.FailingAfterLRAListener; import io.narayana.lra.arquillian.spi.NarayanaLRARecovery; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; +import java.net.URI; +import java.net.URL; import org.eclipse.microprofile.lra.tck.service.spi.LRACallbackException; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; @@ -17,13 +23,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriBuilder; -import java.net.URI; -import java.net.URL; - public class FailingParticipantCallsIT extends TestBase { private static final Logger log = Logger.getLogger(FailingParticipantCallsIT.class); @@ -53,10 +52,10 @@ public void testFailingAfterLRA() throws LRACallbackException { try { response = client.target(UriBuilder.fromUri(baseURL.toExternalForm()) - .path(FailingAfterLRAListener.ROOT_PATH) - .path(FailingAfterLRAListener.ACTION_PATH).build()) - .request() - .get(); + .path(FailingAfterLRAListener.ROOT_PATH) + .path(FailingAfterLRAListener.ACTION_PATH).build()) + .request() + .get(); Assert.assertEquals(200, response.getStatus()); Assert.assertTrue(response.hasEntity()); @@ -73,8 +72,8 @@ public void testFailingAfterLRA() throws LRACallbackException { try { response = client.target(UriBuilder.fromUri(baseURL.toExternalForm()) - .path(FailingAfterLRAListener.ROOT_PATH).path("counter").build()) - .request().get(); + .path(FailingAfterLRAListener.ROOT_PATH).path("counter").build()) + .request().get(); Assert.assertEquals(2, Integer.parseInt(response.readEntity(String.class))); } finally { @@ -84,4 +83,4 @@ public void testFailingAfterLRA() throws LRACallbackException { } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/LRACustomBaseURIIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/LRACustomBaseURIIT.java index 20e34bbf5b..a92152bf88 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/LRACustomBaseURIIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/LRACustomBaseURIIT.java @@ -5,9 +5,14 @@ package io.narayana.lra.arquillian; +import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.SIMPLE_PARTICIPANT_RESOURCE_PATH; +import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.START_LRA_PATH; +import static org.junit.Assert.assertTrue; + import io.narayana.lra.arquillian.filter.LinkCapturingFilter; import io.narayana.lra.arquillian.resource.SimpleLRAParticipant; import jakarta.ws.rs.core.Response; +import java.net.URL; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.logging.Logger; @@ -17,12 +22,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import java.net.URL; - -import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.SIMPLE_PARTICIPANT_RESOURCE_PATH; -import static io.narayana.lra.arquillian.resource.SimpleLRAParticipant.START_LRA_PATH; -import static org.junit.Assert.assertTrue; - /** * Test that the Link header sent to coordinator can be changed with the custom base URI. */ @@ -44,21 +43,21 @@ public void before() { @Deployment public static WebArchive deploy() { return Deployer.deploy(LRACustomBaseURIIT.class.getSimpleName(), SimpleLRAParticipant.class, LinkCapturingFilter.class) - .addAsManifestResource( - new StringAsset("narayana.lra.base-uri=http://example.com"), "microprofile-config.properties"); + .addAsManifestResource( + new StringAsset("narayana.lra.base-uri=http://example.com"), "microprofile-config.properties"); } @Test public void noLRATest() throws Exception { - try(Response response = client.target(baseURL.toURI()) - .path(SIMPLE_PARTICIPANT_RESOURCE_PATH) - .path(START_LRA_PATH) - .request() - .get()) { + try (Response response = client.target(baseURL.toURI()) + .path(SIMPLE_PARTICIPANT_RESOURCE_PATH) + .path(START_LRA_PATH) + .request() + .get()) { System.out.println(response.getHeaderString("Link")); assertTrue("The base URI was not overridden by the configuration", - response.getHeaderString("Link").contains("http://example.com/compensate?method=jakarta.ws.rs.PUT")); + response.getHeaderString("Link").contains("http://example.com/compensate?method=jakarta.ws.rs.PUT")); } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/LRAParticipantAfterLRAIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/LRAParticipantAfterLRAIT.java index bdd6ba66c4..ac6f3526a9 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/LRAParticipantAfterLRAIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/LRAParticipantAfterLRAIT.java @@ -6,6 +6,11 @@ package io.narayana.lra.arquillian; import io.narayana.lra.arquillian.resource.LRAParticipantAfterLRA; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; +import java.net.URL; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.logging.Logger; @@ -15,12 +20,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriBuilder; -import java.net.URL; - public class LRAParticipantAfterLRAIT extends TestBase { private static final Logger log = Logger.getLogger(LRAParticipantAfterLRAIT.class); @@ -73,4 +72,4 @@ public void testAfterLRACount() { } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/LRAPropagationIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/LRAPropagationIT.java index a7a8dd3608..59b289ba3e 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/LRAPropagationIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/LRAPropagationIT.java @@ -5,10 +5,14 @@ package io.narayana.lra.arquillian; +import static org.junit.Assert.assertNotEquals; + import io.narayana.lra.arquillian.resource.LRAUnawareResource; import io.narayana.lra.arquillian.resource.SimpleLRAParticipant; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; +import java.net.URI; +import java.net.URL; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.logging.Logger; @@ -18,11 +22,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import java.net.URI; -import java.net.URL; - -import static org.junit.Assert.assertNotEquals; - public class LRAPropagationIT extends TestBase { private static final Logger log = Logger.getLogger(LRAPropagationIT.class); @@ -41,8 +40,8 @@ public void before() { @Deployment public static WebArchive deploy() { return Deployer.deploy(LRAPropagationIT.class.getSimpleName(), LRAUnawareResource.class, SimpleLRAParticipant.class) - .addAsManifestResource( - new StringAsset("mp.lra.propagation.active=false"), "microprofile-config.properties"); + .addAsManifestResource( + new StringAsset("mp.lra.propagation.active=false"), "microprofile-config.properties"); } @Test @@ -52,9 +51,10 @@ public void noLRATest() throws WebApplicationException { URI returnedLraId = invokeInTransaction(baseURL, Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - assertNotEquals("While calling non-LRA method the resource should not propagate the LRA id when mp.lra.propagation.active=false", - lraId, returnedLraId); + assertNotEquals( + "While calling non-LRA method the resource should not propagate the LRA id when mp.lra.propagation.active=false", + lraId, returnedLraId); lraClient.closeLRA(lraId); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/NestedParticipantIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/NestedParticipantIT.java index c68dba2253..19c90bd226 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/NestedParticipantIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/NestedParticipantIT.java @@ -5,8 +5,21 @@ package io.narayana.lra.arquillian; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; + import io.narayana.lra.arquillian.resource.NestedParticipant; import io.narayana.lra.arquillian.spi.NarayanaLRARecovery; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; +import java.net.URI; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; import org.eclipse.microprofile.lra.tck.service.LRAMetricType; @@ -19,20 +32,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import jakarta.ws.rs.NotFoundException; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriBuilder; -import java.net.URI; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; - -import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; - public class NestedParticipantIT extends TestBase { private static final Logger log = Logger.getLogger(NestedParticipantIT.class); private final NarayanaLRARecovery narayanaLRARecovery = new NarayanaLRARecovery(); @@ -76,11 +75,11 @@ public void nestedParticipantAfterLRACallTest() { try { response = client.target(UriBuilder.fromUri(baseURL.toExternalForm()) - .path(NestedParticipant.ROOT_PATH) - .path(NestedParticipant.ENLIST_PATH)) - .request() - .header(LRA.LRA_HTTP_CONTEXT_HEADER, parentLRA) - .get(); + .path(NestedParticipant.ROOT_PATH) + .path(NestedParticipant.ENLIST_PATH)) + .request() + .header(LRA.LRA_HTTP_CONTEXT_HEADER, parentLRA) + .get(); assertEquals(200, response.getStatus()); Assert.assertTrue(response.hasEntity()); @@ -215,8 +214,8 @@ public void testParentContext() { URI child = lraClient.startLRA(NestedParticipantIT.class.getName() + "#testParentContext child"); try (Response response = client.target(UriBuilder.fromUri(baseURL.toExternalForm()) - .path(NestedParticipant.ROOT_PATH) - .path(NestedParticipant.PATH)) + .path(NestedParticipant.ROOT_PATH) + .path(NestedParticipant.PATH)) .request() .get()) { @@ -243,4 +242,4 @@ private void assertClosed(String msg, URI lra) { } catch (NotFoundException ignore) { } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/NonRootLRAParticipantIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/NonRootLRAParticipantIT.java index f782e28a0e..2d02cdf991 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/NonRootLRAParticipantIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/NonRootLRAParticipantIT.java @@ -5,8 +5,16 @@ package io.narayana.lra.arquillian; +import static org.eclipse.microprofile.lra.annotation.LRAStatus.Closing; +import static org.junit.Assert.fail; + import io.narayana.lra.arquillian.resource.NonRootLRAParticipant; import io.narayana.lra.arquillian.resource.RootResource; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; @@ -17,15 +25,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -import static org.eclipse.microprofile.lra.annotation.LRAStatus.Closing; -import static org.junit.Assert.fail; - public class NonRootLRAParticipantIT extends TestBase { private static final Logger log = Logger.getLogger(NonRootLRAParticipantIT.class); @@ -57,13 +56,14 @@ public void testNonRootLRAParticipantEnlist() { Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); int counterValue = response.readEntity(Integer.class); Assert.assertEquals("Non root JAX-RS participant should have been enlisted and invoked", - 1, counterValue); + 1, counterValue); } /* * Test that a participant can join an LRA using the Narayana specific client API * Test that the LRA has the correct status of Closing if a participant * returns 202 Accepted when asked to complete. + * * @throws URISyntaxException if arquillian URL is invalid */ @Test @@ -87,4 +87,4 @@ public void testFinishLRA() throws URISyntaxException { + ") getting LRA status " + e.getMessage()); } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/OpenAPIIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/OpenAPIIT.java index 442462a7d2..6b74cd0d25 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/OpenAPIIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/OpenAPIIT.java @@ -5,6 +5,14 @@ package io.narayana.lra.arquillian; +import static java.lang.System.getProperty; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import jakarta.ws.rs.core.Response; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.logging.Logger; import org.jboss.shrinkwrap.api.spec.WebArchive; @@ -12,15 +20,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import jakarta.ws.rs.core.Response; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; - -import static java.lang.System.getProperty; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - public class OpenAPIIT extends TestBase { private static final Logger log = Logger.getLogger(OpenAPIIT.class); @@ -41,8 +40,8 @@ public static WebArchive deploy() { @Test public void test() throws URISyntaxException, MalformedURLException { URL url = new URL("http://" - + getProperty("lra.coordinator.host", "localhost")+":" - + getProperty("lra.coordinator.port", "8080")+"/openapi"); + + getProperty("lra.coordinator.host", "localhost") + ":" + + getProperty("lra.coordinator.port", "8080") + "/openapi"); Response response = client.target(url.toURI()).request().get(); String output = response.readEntity(String.class); assertFalse("WildFly OpenAPI document has paths at wrong location", @@ -52,4 +51,4 @@ public void test() throws URISyntaxException, MalformedURLException { assertTrue("WildFly OpenAPI document does not have server URL", output.contains("url: /lra-coordinator")); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/ParticipantDataIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/ParticipantDataIT.java index 174ec1e183..a702f27174 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/ParticipantDataIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/ParticipantDataIT.java @@ -5,14 +5,20 @@ package io.narayana.lra.arquillian; -import io.narayana.lra.arquillian.resource.ParticipantDataResource; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; + import io.narayana.lra.arquillian.resource.LRAParticipantWithStatusURI; import io.narayana.lra.arquillian.resource.LRAParticipantWithoutStatusURI; +import io.narayana.lra.arquillian.resource.ParticipantDataResource; import io.narayana.lra.arquillian.resource.ParticipantDataResource2; import io.narayana.lra.arquillian.spi.NarayanaLRARecovery; import jakarta.ws.rs.core.MultivaluedHashMap; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import org.eclipse.microprofile.lra.tck.service.spi.LRACallbackException; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; @@ -23,13 +29,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; - /** * There is a spec requirement to report failed LRAs but the spec only requires that a failure message is reported * (not how it is reported). Failure records are vital pieces of data needed to aid failure tracking and analysis. @@ -84,7 +83,8 @@ public void testSimple() throws LRACallbackException, URISyntaxException { public void testPropagateLRAData() throws URISyntaxException { // invoke a resource that starts an LRA URI lraId = new URI(invoke(null, ParticipantDataResource2.DATA_PARTICIPANT_RESOURCE_PATH, - ParticipantDataResource2.START_LRA_PATH, Response.Status.OK.getStatusCode(), ParticipantDataResource2.START_DATA)); + ParticipantDataResource2.START_LRA_PATH, Response.Status.OK.getStatusCode(), + ParticipantDataResource2.START_DATA)); // invoke a second resource in the same context String data = invoke(lraId, ParticipantDataResource2.DATA_PARTICIPANT_RESOURCE_PATH, ParticipantDataResource2.END_LRA_PATH, Response.Status.OK.getStatusCode(), ParticipantDataResource2.END_DATA); @@ -99,7 +99,7 @@ private String invoke(URI lraId, String resourcePrefix, String resourcePath, int MultivaluedMap headers = new MultivaluedHashMap<>(); headers.add(LRA_HTTP_CONTEXT_HEADER, lraId); - if(data!= null) { + if (data != null) { headers.add(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME, data); } @@ -122,4 +122,4 @@ private String invoke(URI lraId, String resourcePrefix, String resourcePath, int throw new IllegalStateException("response cannot be converted to URI: " + e.getMessage()); } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/TestBase.java b/test/basic/src/test/java/io/narayana/lra/arquillian/TestBase.java index 677a642d1b..b27c807a72 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/TestBase.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/TestBase.java @@ -14,14 +14,6 @@ import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.core.Response; -import org.jboss.arquillian.container.test.api.RunAsClient; -import org.jboss.arquillian.junit.Arquillian; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; - import java.io.StringReader; import java.net.URI; import java.net.URISyntaxException; @@ -29,6 +21,13 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; @RunAsClient @RunWith(Arquillian.class) @@ -54,7 +53,7 @@ public void before() { @After public void after() { List lraURIList = lraClient.getAllLRAs().stream().map(LRAData::getLraId).collect(Collectors.toList()); - for (URI lraToFinish: lrasToAfterFinish) { + for (URI lraToFinish : lrasToAfterFinish) { if (lraURIList.contains(lraToFinish)) { lraClient.cancelLRA(lraToFinish); } @@ -78,19 +77,23 @@ protected JsonArray getAllRecords(URI lra) { } protected URI invokeInTransaction(URL baseURL, int expectedStatus) { - try(Response response = client.target(baseURL.toURI()) + try (Response response = client.target(baseURL.toURI()) .path(io.narayana.lra.arquillian.resource.LRAUnawareResource.ROOT_PATH) .path(io.narayana.lra.arquillian.resource.LRAUnawareResource.RESOURCE_PATH) .request() .get()) { - Assert.assertTrue("Expecting a non empty body in response from " + io.narayana.lra.arquillian.resource.LRAUnawareResource.ROOT_PATH + "/" + io.narayana.lra.arquillian.resource.LRAUnawareResource.RESOURCE_PATH, + Assert.assertTrue( + "Expecting a non empty body in response from " + + io.narayana.lra.arquillian.resource.LRAUnawareResource.ROOT_PATH + "/" + + io.narayana.lra.arquillian.resource.LRAUnawareResource.RESOURCE_PATH, response.hasEntity()); String entity = response.readEntity(String.class); Assert.assertEquals( - "response from " + io.narayana.lra.arquillian.resource.LRAUnawareResource.ROOT_PATH + "/" + io.narayana.lra.arquillian.resource.LRAUnawareResource.RESOURCE_PATH + " was " + entity, + "response from " + io.narayana.lra.arquillian.resource.LRAUnawareResource.ROOT_PATH + "/" + + io.narayana.lra.arquillian.resource.LRAUnawareResource.RESOURCE_PATH + " was " + entity, expectedStatus, response.getStatus()); return new URI(entity); diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/api/CoordinatorApiIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/api/CoordinatorApiIT.java index db4cea6c39..7c74c510a4 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/api/CoordinatorApiIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/api/CoordinatorApiIT.java @@ -5,20 +5,19 @@ package io.narayana.lra.arquillian.api; +import static io.narayana.lra.LRAConstants.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.emptyCollectionOf; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.lessThan; +import static org.hamcrest.core.IsCollectionContaining.hasItem; +import static org.hamcrest.core.IsCollectionContaining.hasItems; +import static org.hamcrest.core.IsNot.not; + import io.narayana.lra.LRAConstants; import io.narayana.lra.LRAData; import io.narayana.lra.arquillian.ArquillianParametrized; import io.narayana.lra.arquillian.TestBase; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.hamcrest.MatcherAssert; -import org.jboss.arquillian.container.test.api.RunAsClient; -import org.jboss.logging.Logger; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.GenericType; import jakarta.ws.rs.core.HttpHeaders; @@ -35,15 +34,15 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; - -import static io.narayana.lra.LRAConstants.*; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.emptyCollectionOf; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.lessThan; -import static org.hamcrest.core.IsCollectionContaining.hasItem; -import static org.hamcrest.core.IsCollectionContaining.hasItems; -import static org.hamcrest.core.IsNot.not; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.hamcrest.MatcherAssert; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.logging.Logger; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; /** *

@@ -59,11 +58,11 @@ *

* When a new API version is added - when the new version *

    - *
  • does not change the functionality of the API endpoint - * then nothing is needed - the test will be executed with the new version as well
  • - *
  • changes the functionality of the API endpoint - * then the test needs to be limited for execution with preceding API versions - * and the creation of a new test to document the new behaviour should be considered
  • + *
  • does not change the functionality of the API endpoint + * then nothing is needed - the test will be executed with the new version as well
  • + *
  • changes the functionality of the API endpoint + * then the test needs to be limited for execution with preceding API versions + * and the creation of a new test to document the new behaviour should be considered
  • *
*

*/ @@ -119,14 +118,17 @@ public void getAllLRAs() { Assert.assertEquals("Expected that the call succeeds, GET/200.", Status.OK.getStatusCode(), response.getStatus()); Assert.assertEquals("Provided API header, expected that one is returned", version, response.getHeaderString(LRA_API_VERSION_HEADER_NAME)); - data = response.readEntity(new GenericType<>() {}); + data = response.readEntity(new GenericType<>() { + }); } Optional lraTopOptional = data.stream().filter(record -> record.getLraId().equals(lraId1)).findFirst(); - Assert.assertTrue("Expected to find the top-level LRA id " + lraId1 + " from REST get all call", lraTopOptional.isPresent()); + Assert.assertTrue("Expected to find the top-level LRA id " + lraId1 + " from REST get all call", + lraTopOptional.isPresent()); LRAData lraTop = lraTopOptional.get(); Optional lraNestedOptional = data.stream().filter(record -> record.getLraId().equals(lraId2)).findFirst(); - Assert.assertTrue("Expected to find the nested LRA id " + lraId2 + " from REST get all call", lraNestedOptional.isPresent()); + Assert.assertTrue("Expected to find the nested LRA id " + lraId2 + " from REST get all call", + lraNestedOptional.isPresent()); LRAData lraNested = lraNestedOptional.get(); Assert.assertEquals("Expected top-level LRA '" + lraTop + "' being active", @@ -175,7 +177,8 @@ public void getAllLRAsStatusFilter() { try (Response response = client.target(coordinatorUrl) .queryParam(STATUS_PARAM_NAME, "Active").request().get()) { Assert.assertEquals("Expected that the call succeeds, GET/200.", Status.OK.getStatusCode(), response.getStatus()); - List data = response.readEntity(new GenericType<>() {}); + List data = response.readEntity(new GenericType<>() { + }); Collection returnedLraIds = data.stream().map(LRAData::getLraId).collect(Collectors.toList()); MatcherAssert.assertThat("Expected the coordinator returns the first started top-level LRA", returnedLraIds, hasItem(lraId1)); @@ -215,7 +218,8 @@ public void getLRAStatus() { String encodedLraId = URLEncoder.encode(lraId.toString(), StandardCharsets.UTF_8); try (Response response = client.target(coordinatorUrl).path(encodedLraId).path("status") .request().header(LRA_API_VERSION_HEADER_NAME, version).get()) { - Assert.assertEquals("Expected that the get status call succeeds, GET/200.", Status.OK.getStatusCode(), response.getStatus()); + Assert.assertEquals("Expected that the get status call succeeds, GET/200.", Status.OK.getStatusCode(), + response.getStatus()); Assert.assertEquals("Expected API header to be returned with the version provided in request", version, response.getHeaderString(LRA_API_VERSION_HEADER_NAME)); Assert.assertEquals("Expected the returned LRA status is Active", @@ -229,7 +233,8 @@ public void getLRAStatus() { */ public void getLRAStatusFailed() { String nonExistingLRAId = "http://localhost:1234/Non-Existing-LRA-id"; - String nonExistingLRAIdEncodedForUrl = URLEncoder.encode("http://localhost:1234/Non-Existing-LRA-id", StandardCharsets.UTF_8); + String nonExistingLRAIdEncodedForUrl = URLEncoder.encode("http://localhost:1234/Non-Existing-LRA-id", + StandardCharsets.UTF_8); try (Response response = client.target(coordinatorUrl).path(nonExistingLRAIdEncodedForUrl).path("status") .request().header(LRA_API_VERSION_HEADER_NAME, version).get()) { Assert.assertEquals("LRA ID " + nonExistingLRAIdEncodedForUrl + " was expected not being found, GET/404.", @@ -241,11 +246,13 @@ public void getLRAStatusFailed() { } String nonExistingLRAWrongUrlFormat = "Non-Existing-LRA-id"; - try (Response response = client.target(coordinatorUrl).path(nonExistingLRAWrongUrlFormat).path("status").request().get()) { + try (Response response = client.target(coordinatorUrl).path(nonExistingLRAWrongUrlFormat).path("status").request() + .get()) { Assert.assertEquals("LRA id " + nonExistingLRAWrongUrlFormat + " was expected not being found , GET/404.", Status.NOT_FOUND.getStatusCode(), response.getStatus()); MatcherAssert.assertThat("Expected the failure message to contain the wrong LRA id", - response.readEntity(String.class), containsString(lraClient.getCoordinatorUrl() + "/" + nonExistingLRAWrongUrlFormat)); + response.readEntity(String.class), + containsString(lraClient.getCoordinatorUrl() + "/" + nonExistingLRAWrongUrlFormat)); } } @@ -261,7 +268,8 @@ public void getLRAInfo() { String encodedLraId = URLEncoder.encode(lraId.toString(), StandardCharsets.UTF_8); try (Response response = client.target(coordinatorUrl).path(encodedLraId) .request().header(LRA_API_VERSION_HEADER_NAME, version).get()) { - Assert.assertEquals("Expected that the get status call succeeds, GET/200.", Status.OK.getStatusCode(), response.getStatus()); + Assert.assertEquals("Expected that the get status call succeeds, GET/200.", Status.OK.getStatusCode(), + response.getStatus()); Assert.assertEquals("Expected API header to be returned with the version provided in request", version, response.getHeaderString(LRA_API_VERSION_HEADER_NAME)); LRAData data = response.readEntity(new GenericType<>() { @@ -397,7 +405,8 @@ public void startCancelLRA() { lraId = URI.create(response.readEntity(String.class)); Assert.assertNotNull("Expected non null LRA id to be returned from start call", lraId); lrasToAfterFinish.add(lraId); - Assert.assertTrue("API version header is expected on response despite no API version header was provided on request", + Assert.assertTrue( + "API version header is expected on response despite no API version header was provided on request", response.getHeaders().containsKey(LRA_API_VERSION_HEADER_NAME)); } @@ -412,7 +421,8 @@ public void startCancelLRA() { Status.OK.getStatusCode(), response.getStatus()); Assert.assertEquals("Canceling top-level LRA should return the right status.", LRAStatus.Cancelled.name(), response.readEntity(String.class)); - Assert.assertTrue("API version header is expected on response despite no API header parameter was provided on request", + Assert.assertTrue( + "API version header is expected on response despite no API header parameter was provided on request", response.getHeaders().containsKey(LRA_API_VERSION_HEADER_NAME)); } @@ -556,7 +566,7 @@ public void renewTimeLimitNotExistingLRA() { * Joining an LRA participant via entity body. */ @Test - @ValidTestVersions({API_VERSION_1_0, API_VERSION_1_1}) // the recovery url was unusable in previous versions + @ValidTestVersions({ API_VERSION_1_0, API_VERSION_1_1 }) // the recovery url was unusable in previous versions public void joinLRAWithBody() { URI lraId = lraClient.startLRA(testRule.getMethodName()); lrasToAfterFinish.add(lraId); @@ -587,7 +597,7 @@ public void joinLRAWithBody() { } @Test - @ValidTestVersions({API_VERSION_1_2}) // the recovery url is usable versions after API_VERSION_1_1 + @ValidTestVersions({ API_VERSION_1_2 }) // the recovery url is usable versions after API_VERSION_1_1 // Remark if the API version is incremented then the new value for the version will need adding to annotation public void joinLRAWithBodyWithCorrectRecoveryHeader() { URI lraId = lraClient.startLRA(testRule.getMethodName()); @@ -623,7 +633,7 @@ public void joinLRAWithBodyWithCorrectRecoveryHeader() { * Joining an LRA participant via link header. */ @Test - @ValidTestVersions({API_VERSION_1_0, API_VERSION_1_1}) + @ValidTestVersions({ API_VERSION_1_0, API_VERSION_1_1 }) public void joinLRAWithLinkSimple() { URI lraId = lraClient.startLRA(testRule.getMethodName()); lrasToAfterFinish.add(lraId); @@ -654,7 +664,7 @@ public void joinLRAWithLinkSimple() { } @Test - @ValidTestVersions({API_VERSION_1_2}) + @ValidTestVersions({ API_VERSION_1_2 }) public void joinLRAWithLinkSimpleWithCorrectRecoveryHeader() { URI lraId = lraClient.startLRA(testRule.getMethodName()); lrasToAfterFinish.add(lraId); @@ -702,7 +712,8 @@ public void joinLRAWithLinkCompensate() { .put(null)) { Assert.assertEquals("Expected joining LRA succeeded, PUT/200 is expected.", Status.OK.getStatusCode(), response.getStatus()); - Assert.assertTrue("API version header is expected on response despite no API version header was provided on request", + Assert.assertTrue( + "API version header is expected on response despite no API version header was provided on request", response.getHeaders().containsKey(LRA_API_VERSION_HEADER_NAME)); String recoveryHeaderUrlMessage = response.getHeaderString(RECOVERY_HEADER_NAME); String recoveryUrlBody = response.readEntity(String.class); @@ -892,7 +903,8 @@ public void leaveLRANonExistingFailure() { String nonExistingParticipantUrl = "http://localhost:1234/Non-Existing-participant-LRA"; try (Response response = client.target(coordinatorUrl).path(encodedLRAId).path("remove").request() .header(LRA_API_VERSION_HEADER_NAME, version).put(Entity.text(nonExistingParticipantUrl))) { - Assert.assertEquals("Expected that the call fails on LRA participant " + nonExistingParticipantUrl + " not found , PUT/400.", + Assert.assertEquals( + "Expected that the call fails on LRA participant " + nonExistingParticipantUrl + " not found , PUT/400.", Status.BAD_REQUEST.getStatusCode(), response.getStatus()); Assert.assertEquals("Expected API header to be returned with the version provided in request", version, response.getHeaderString(LRA_API_VERSION_HEADER_NAME)); @@ -901,4 +913,4 @@ public void leaveLRANonExistingFailure() { } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersions.java b/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersions.java index d3ed86fb9a..7177b93a55 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersions.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersions.java @@ -22,7 +22,7 @@ */ @Inherited @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) +@Target({ ElementType.METHOD }) public @interface ValidTestVersions { String[] value(); } \ No newline at end of file diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersionsRule.java b/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersionsRule.java index 560f1b87d2..734920c00e 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersionsRule.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/api/ValidTestVersionsRule.java @@ -5,14 +5,13 @@ package io.narayana.lra.arquillian.api; +import java.lang.reflect.Field; +import java.util.Arrays; import org.junit.AssumptionViolatedException; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; -import java.lang.reflect.Field; -import java.util.Arrays; - /** * This rule works with annotation {@link ValidTestVersions}. * It verifies that the test contains a field named 'version' @@ -39,7 +38,8 @@ public Statement apply(Statement base, FrameworkMethod method, Object target) { @Override public void evaluate() { throw new AssumptionViolatedException("Test " + method.getName() + " annotated with annotation " + - ValidTestVersions.class.getSimpleName() + " and the current '" + VERSION_FIELD_NAME + "' field is not in set " + + ValidTestVersions.class.getSimpleName() + " and the current '" + VERSION_FIELD_NAME + + "' field is not in set " + "of the versions to run with"); } }; @@ -53,16 +53,17 @@ public String getMethodName() { } private String findVersionField(Object objectToSearch) { - for (Field field: objectToSearch.getClass().getDeclaredFields()) { + for (Field field : objectToSearch.getClass().getDeclaredFields()) { if (field.getName().equals(VERSION_FIELD_NAME) && field.getType().isAssignableFrom(String.class)) { try { field.setAccessible(true); return (String) field.get(objectToSearch); } catch (IllegalAccessException iae) { - throw new IllegalStateException("Cannot get value of '" + VERSION_FIELD_NAME + "' field with reflection", iae); + throw new IllegalStateException("Cannot get value of '" + VERSION_FIELD_NAME + "' field with reflection", + iae); } } } return null; } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAAsyncIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAAsyncIT.java index 887977c340..9481f93f81 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAAsyncIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAAsyncIT.java @@ -5,11 +5,18 @@ package io.narayana.lra.arquillian.client; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import io.narayana.lra.arquillian.Deployer; +import io.narayana.lra.arquillian.TestBase; +import io.narayana.lra.arquillian.resource.LRAParticipant; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; import java.net.URI; import java.net.URL; import java.util.ArrayList; @@ -19,7 +26,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; - import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; @@ -29,15 +35,6 @@ import org.junit.Test; import org.junit.rules.TestName; -import io.narayana.lra.arquillian.Deployer; -import io.narayana.lra.arquillian.TestBase; -import io.narayana.lra.arquillian.resource.LRAParticipant; -import jakarta.ws.rs.client.Invocation; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriBuilder; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; - public class LRAAsyncIT extends TestBase { private static final Logger log = Logger.getLogger(LRAAsyncIT.class); @@ -131,7 +128,6 @@ public void testNoCurrent() { return lra; }; - List> callableTasks = new ArrayList<>(); for (int i = 0; i < NUMBER_OF_TASKS; i++) callableTasks.add(callableTask); diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAIT.java index d07dab24bf..fc987780e7 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/client/LRAIT.java @@ -5,10 +5,20 @@ package io.narayana.lra.arquillian.client; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import io.narayana.lra.arquillian.Deployer; import io.narayana.lra.arquillian.TestBase; import io.narayana.lra.arquillian.resource.LRAParticipant; import io.narayana.lra.client.internal.NarayanaLRAClient; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; +import java.net.URI; +import java.net.URL; import org.eclipse.microprofile.lra.annotation.LRAStatus; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.test.api.ArquillianResource; @@ -18,23 +28,11 @@ import org.junit.Test; import org.junit.rules.TestName; -import jakarta.ws.rs.client.Invocation; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriBuilder; -import java.net.URI; -import java.net.URL; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - public class LRAIT extends TestBase { private static final Logger log = Logger.getLogger(LRAIT.class); - private static final String SHOULD_NOT_BE_ASSOCIATED = - "The narayana implementation (of the MP-LRA specification) still thinks that there is " - + "an active LRA associated with the current thread even though all LRAs should now be finished"; + private static final String SHOULD_NOT_BE_ASSOCIATED = "The narayana implementation (of the MP-LRA specification) still thinks that there is " + + "an active LRA associated with the current thread even though all LRAs should now be finished"; @ArquillianResource public URL baseURL; @@ -184,4 +182,4 @@ private URI invokeInTransaction(URI lra, String resourcePath) { } } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/client/NarayanaLRAClientIT.java b/test/basic/src/test/java/io/narayana/lra/arquillian/client/NarayanaLRAClientIT.java index 134fdf6b6d..e7155b0bee 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/client/NarayanaLRAClientIT.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/client/NarayanaLRAClientIT.java @@ -7,15 +7,14 @@ import io.narayana.lra.LRAData; import io.narayana.lra.arquillian.TestBase; +import java.net.URI; +import java.util.List; import org.jboss.logging.Logger; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; -import java.net.URI; -import java.util.List; - public class NarayanaLRAClientIT extends TestBase { private static final Logger log = Logger.getLogger(NarayanaLRAClientIT.class); @@ -45,4 +44,4 @@ public void testGetAllLRAs() { allLRAs.stream().noneMatch(lraData -> lraData.getLraId().equals(lra))); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/filter/LinkCapturingFilter.java b/test/basic/src/test/java/io/narayana/lra/arquillian/filter/LinkCapturingFilter.java index c65caad3a9..aa56dcc1d8 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/filter/LinkCapturingFilter.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/filter/LinkCapturingFilter.java @@ -12,12 +12,12 @@ import jakarta.ws.rs.container.ContainerResponseContext; import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.ext.Provider; - import java.io.IOException; /** * JAX-RS filter that captures outgoing Link header and adds it to the server response filter. * Note that this is client request and server response. + * * @see LRACustomBaseURIIT */ @Provider diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/FailingAfterLRAListener.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/FailingAfterLRAListener.java index 1c724597e8..847aa1b0b2 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/FailingAfterLRAListener.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/FailingAfterLRAListener.java @@ -5,9 +5,6 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; - import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.PUT; @@ -15,6 +12,8 @@ import jakarta.ws.rs.core.Response; import java.net.URI; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; @Path(FailingAfterLRAListener.ROOT_PATH) public class FailingAfterLRAListener { @@ -47,4 +46,4 @@ public Response afterLRA(@HeaderParam(LRA.LRA_HTTP_ENDED_CONTEXT_HEADER) URI end public Response getCounterValue() { return Response.ok(afterLRACounter.get()).build(); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipant.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipant.java index 60904d45ea..2386c7e36f 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipant.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipant.java @@ -5,11 +5,9 @@ package io.narayana.lra.arquillian.resource; -import io.narayana.lra.client.internal.NarayanaLRAClient; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import io.narayana.lra.client.internal.NarayanaLRAClient; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; @@ -17,16 +15,17 @@ import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.Response; -import java.net.URI; -import jakarta.ws.rs.client.Invocation; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilder; import jakarta.ws.rs.core.UriInfo; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import java.net.URI; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; @ApplicationScoped @Path(LRAParticipant.RESOURCE_PATH) @@ -175,4 +174,4 @@ private void validateLRAIsNotActive(LRAStatus status) { "lra2 should no longer be active").build()); } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantAfterLRA.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantAfterLRA.java index cfbb12df55..c685cfc72c 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantAfterLRA.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantAfterLRA.java @@ -5,12 +5,8 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.LRAResponse; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.LRAStatus; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; -import org.jboss.logging.Logger; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_ENDED_CONTEXT_HEADER; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.GET; @@ -22,12 +18,14 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriInfo; - import java.net.URI; import java.util.concurrent.atomic.AtomicInteger; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_ENDED_CONTEXT_HEADER; +import org.eclipse.microprofile.lra.LRAResponse; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.LRAStatus; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import org.jboss.logging.Logger; @ApplicationScoped @Path(LRAParticipantAfterLRA.SIMPLE_PARTICIPANT_RESOURCE_PATH) @@ -85,4 +83,4 @@ public Response getCounterValue() { return Response.ok(afterLRACounter.get()).build(); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithStatusURI.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithStatusURI.java index 6e508cca1b..6fe7c27952 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithStatusURI.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithStatusURI.java @@ -5,12 +5,8 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.Forget; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.eclipse.microprofile.lra.annotation.Status; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.DELETE; @@ -24,9 +20,12 @@ import jakarta.ws.rs.core.Response; import java.net.URI; import java.util.concurrent.atomic.AtomicInteger; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.Forget; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.eclipse.microprofile.lra.annotation.Status; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; @ApplicationScoped @Path(LRAParticipantWithStatusURI.LRA_PARTICIPANT_PATH) @@ -96,7 +95,7 @@ public Response forget() { @Produces(MediaType.APPLICATION_JSON) @Status public Response status(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId) { if (completeCount.get() == 1) { return Response.ok(ParticipantStatus.FailedToComplete.name()).build(); } else if (compensateCount.get() == 1) { @@ -105,4 +104,4 @@ public Response status(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, return Response.ok(ParticipantStatus.Active.name()).build(); } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithoutStatusURI.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithoutStatusURI.java index 891ce89012..c77b515c99 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithoutStatusURI.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAParticipantWithoutStatusURI.java @@ -5,11 +5,7 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.Forget; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.DELETE; @@ -23,8 +19,11 @@ import jakarta.ws.rs.core.Response; import java.net.URI; import java.util.concurrent.atomic.AtomicInteger; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.Forget; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; @ApplicationScoped @Path(LRAParticipantWithoutStatusURI.LRA_PARTICIPANT_PATH) @@ -82,4 +81,4 @@ public Response forget() { return Response.ok().build(); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAUnawareResource.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAUnawareResource.java index 7114c3a4ce..af79173e74 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAUnawareResource.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/LRAUnawareResource.java @@ -32,10 +32,10 @@ public Response doInLRA() { // if this method propagates LRA context it will be reused in SimpleLRAParticipant // but if it doesn't, a new LRA will be started return client.target(context.getBaseUri()) - .path(SimpleLRAParticipant.SIMPLE_PARTICIPANT_RESOURCE_PATH) - .path(SimpleLRAParticipant.START_LRA_PATH) - .request() - .get(); + .path(SimpleLRAParticipant.SIMPLE_PARTICIPANT_RESOURCE_PATH) + .path(SimpleLRAParticipant.START_LRA_PATH) + .request() + .get(); } } } diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NestedParticipant.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NestedParticipant.java index b93ada5e6c..d35a03e491 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NestedParticipant.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NestedParticipant.java @@ -5,14 +5,6 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.annotation.AfterLRA; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; -import org.eclipse.microprofile.lra.tck.service.LRAMetricService; -import org.eclipse.microprofile.lra.tck.service.LRAMetricType; - import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.GET; @@ -26,6 +18,13 @@ import jakarta.ws.rs.core.Response; import java.net.URI; import java.net.URISyntaxException; +import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import org.eclipse.microprofile.lra.tck.service.LRAMetricService; +import org.eclipse.microprofile.lra.tck.service.LRAMetricType; @Path(NestedParticipant.ROOT_PATH) @ApplicationScoped @@ -43,9 +42,9 @@ public class NestedParticipant { @LRA(end = false) @GET @Path(PATH) - @Produces({MediaType.TEXT_PLAIN}) + @Produces({ MediaType.TEXT_PLAIN }) public Response runWithNestedContext(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { + @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { if (parentId == null || lraId == null) { throw new WebApplicationException( Response.status(Response.Status.PRECONDITION_FAILED) @@ -60,7 +59,7 @@ public Response runWithNestedContext(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) U @Path(NestedParticipant.ENLIST_PATH) @Produces(MediaType.TEXT_PLAIN) public Response enlist(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { + @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { lraMetricService.incrementMetric(LRAMetricType.Nested, parentId, NestedParticipant.class); return Response.ok(lraId).build(); } @@ -73,8 +72,8 @@ public Response counter( @QueryParam("type") String type) throws URISyntaxException { return Response.ok(lraMetricService.getMetric( - LRAMetricType.valueOf(type), new URI(lraId))) - .build(); + LRAMetricType.valueOf(type), new URI(lraId))) + .build(); } @GET @@ -89,7 +88,7 @@ public Response counter() { @Path("/complete") @Produces(MediaType.TEXT_PLAIN) public Response complete(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { + @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { lraMetricService.incrementMetric(LRAMetricType.Nested, parentId, NestedParticipant.class); lraMetricService.incrementMetric(LRAMetricType.Completed, lraId, NestedParticipant.class); return Response.ok(ParticipantStatus.Completed).build(); @@ -109,9 +108,9 @@ public Response compensate() { @Path("/after") @Produces(MediaType.TEXT_PLAIN) public Response afterLRA(@HeaderParam(LRA.LRA_HTTP_ENDED_CONTEXT_HEADER) URI endedLraId, - @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { + @HeaderParam(LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) URI parentId) { lraMetricService.incrementMetric(LRAMetricType.Nested, parentId, NestedParticipant.class); lraMetricService.incrementMetric(LRAMetricType.AfterLRA, endedLraId, NestedParticipant.class); return Response.ok(endedLraId).build(); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NonRootLRAParticipant.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NonRootLRAParticipant.java index df44c38578..b5b4990363 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NonRootLRAParticipant.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/NonRootLRAParticipant.java @@ -5,9 +5,6 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; - import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.PUT; @@ -15,6 +12,8 @@ import jakarta.ws.rs.core.Response; import java.net.URI; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; public class NonRootLRAParticipant { @@ -45,4 +44,4 @@ public void compensate(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId) { public int getCounterValue() { return counter.intValue(); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource.java index 308ef5f596..1a7113bc9f 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource.java @@ -5,6 +5,11 @@ package io.narayana.lra.arquillian.resource; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_ENDED_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; + import io.narayana.lra.client.LRAParticipantData; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -16,6 +21,7 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import java.net.URI; import org.eclipse.microprofile.lra.annotation.AfterLRA; import org.eclipse.microprofile.lra.annotation.Compensate; import org.eclipse.microprofile.lra.annotation.Complete; @@ -25,13 +31,6 @@ import org.eclipse.microprofile.lra.annotation.Status; import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; -import java.net.URI; - -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_ENDED_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; - @ApplicationScoped @Path(ParticipantDataResource.SIMPLE_PARTICIPANT_RESOURCE_PATH) public class ParticipantDataResource { @@ -54,7 +53,7 @@ public class ParticipantDataResource { @Path(START_LRA_PATH) @LRA(value = LRA.Type.REQUIRED) public Response doInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { data.setData(CONTEXT_DATA); calls.setLength(0); status = ParticipantStatus.Active; @@ -69,7 +68,7 @@ public Response doInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, @Path(BEGIN_LRA_PATH) @LRA(value = LRA.Type.REQUIRES_NEW, end = false) public Response doStartLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { data.setData(BEGIN_DATA); calls.setLength(0); status = ParticipantStatus.Active; @@ -84,7 +83,7 @@ public Response doStartLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, @Path(END_LRA_PATH) @LRA(value = LRA.Type.REQUIRED) public Response doEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { status = ParticipantStatus.Active; return Response.status(Response.Status.OK) @@ -141,8 +140,8 @@ public Response forget(@HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) S @Produces(MediaType.APPLICATION_JSON) @Status public Response status(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId, - @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId, + @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { if (CONTEXT_DATA.equals(pData)) { calls.append("@Status"); } else { @@ -156,8 +155,8 @@ public Response status(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, @Path("/after") @AfterLRA public Response afterLRA(LRAStatus status, - @HeaderParam(LRA_HTTP_ENDED_CONTEXT_HEADER) URI endedLRAId, - @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { + @HeaderParam(LRA_HTTP_ENDED_CONTEXT_HEADER) URI endedLRAId, + @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { if (CONTEXT_DATA.equals(pData)) { calls.append("@AfterLRA"); } else { @@ -172,4 +171,4 @@ public Response afterLRA(LRAStatus status, public Response getCalls() { return Response.ok(calls.toString()).build(); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource2.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource2.java index 49e42c20d5..5ffa5a1ece 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource2.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/ParticipantDataResource2.java @@ -5,6 +5,10 @@ package io.narayana.lra.arquillian.resource; +import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; + import io.narayana.lra.client.LRAParticipantData; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -13,16 +17,11 @@ import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.core.Response; +import java.net.URI; import org.eclipse.microprofile.lra.annotation.Compensate; import org.eclipse.microprofile.lra.annotation.ParticipantStatus; import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; -import java.net.URI; - -import static io.narayana.lra.LRAConstants.NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; - @ApplicationScoped @Path(ParticipantDataResource2.DATA_PARTICIPANT_RESOURCE_PATH) public class ParticipantDataResource2 { @@ -39,8 +38,8 @@ public class ParticipantDataResource2 { @Path(START_LRA_PATH) @LRA(value = LRA.Type.REQUIRES_NEW, end = false) public Response doStartLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl, - @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl, + @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { data.setData(pData); return Response.status(Response.Status.OK) @@ -53,8 +52,8 @@ public Response doStartLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, @Path(END_LRA_PATH) @LRA(value = LRA.Type.REQUIRED) public Response doEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, - @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl, - @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl, + @HeaderParam(NARAYANA_LRA_PARTICIPANT_DATA_HEADER_NAME) String pData) { String prevData = data.getData(); data.setData(pData); @@ -86,4 +85,4 @@ private Response checkBean(boolean compensate, String actualData) { return Response.ok(compensate ? ParticipantStatus.FailedToCompensate : ParticipantStatus.FailedToComplete).build(); } } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/SimpleLRAParticipant.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/SimpleLRAParticipant.java index c6566eac53..96f8f897f4 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/SimpleLRAParticipant.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/SimpleLRAParticipant.java @@ -5,9 +5,8 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.ParticipantStatus; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; +import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.GET; @@ -17,9 +16,9 @@ import jakarta.ws.rs.core.Response; import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; - -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER; -import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.ParticipantStatus; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; @ApplicationScoped @Path(SimpleLRAParticipant.SIMPLE_PARTICIPANT_RESOURCE_PATH) @@ -33,7 +32,8 @@ public class SimpleLRAParticipant { @GET @Path(START_LRA_PATH) @LRA(value = LRA.Type.REQUIRED) - public Response doInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { + public Response doInLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId, + @HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryUrl) { accepted.set(true); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) @@ -60,4 +60,4 @@ public Response compensate() { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ParticipantStatus.FailedToCompensate).build(); } -} \ No newline at end of file +} diff --git a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/TestLRAParticipant.java b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/TestLRAParticipant.java index e2e9218334..0cd8fbbe27 100644 --- a/test/basic/src/test/java/io/narayana/lra/arquillian/resource/TestLRAParticipant.java +++ b/test/basic/src/test/java/io/narayana/lra/arquillian/resource/TestLRAParticipant.java @@ -5,15 +5,14 @@ package io.narayana.lra.arquillian.resource; -import org.eclipse.microprofile.lra.annotation.Compensate; -import org.eclipse.microprofile.lra.annotation.Complete; -import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; - import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.core.Response; import java.net.URI; +import org.eclipse.microprofile.lra.annotation.Compensate; +import org.eclipse.microprofile.lra.annotation.Complete; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; @Path("/participant") public class TestLRAParticipant { @@ -30,4 +29,4 @@ public Response compensate(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId) public Response complete(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId) { return Response.status(Response.Status.ACCEPTED).build(); } -} \ No newline at end of file +}