From 8a21bd67b7cf95f7231421f4ed87c2da27431f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Sapp=C3=A9=20Griot?= Date: Tue, 14 Jun 2022 11:10:38 +0200 Subject: [PATCH] More tests for @LRA defined at the class level are needed --- .../microprofile/lra/tck/TckTests.java | 62 ++++++++++++ .../api/LRAOnClassParticipant.java | 86 +++++++++++++++++ .../api/LRAOnClassParticipantCompensate.java | 95 +++++++++++++++++++ 3 files changed, 243 insertions(+) create mode 100644 tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipant.java create mode 100644 tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipantCompensate.java diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java index 687e830..c14007d 100644 --- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java +++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTests.java @@ -24,6 +24,10 @@ import static org.eclipse.microprofile.lra.tck.participant.api.AfterLRAListener.AFTER_LRA_LISTENER_WORK; import static org.eclipse.microprofile.lra.tck.participant.api.AfterLRAParticipant.AFTER_LRA_PARTICIPANT_PATH; import static org.eclipse.microprofile.lra.tck.participant.api.AfterLRAParticipant.AFTER_LRA_PARTICIPANT_WORK; +import static org.eclipse.microprofile.lra.tck.participant.api.LRAOnClassParticipant.LRA_PARTICIPANT_PATH; +import static org.eclipse.microprofile.lra.tck.participant.api.LRAOnClassParticipant.LRA_PARTICIPANT_WORK; +import static org.eclipse.microprofile.lra.tck.participant.api.LRAOnClassParticipantCompensate.LRA_PARTICIPANT_PATH_COMPENSATE; +import static org.eclipse.microprofile.lra.tck.participant.api.LRAOnClassParticipantCompensate.LRA_PARTICIPANT_START; import static org.eclipse.microprofile.lra.tck.participant.api.LraResource.ACCEPT_WORK; import static org.eclipse.microprofile.lra.tck.participant.api.LraResource.CANCEL_PATH; import static org.eclipse.microprofile.lra.tck.participant.api.LraResource.LRA_RESOURCE_PATH; @@ -47,9 +51,12 @@ import java.util.stream.IntStream; import org.eclipse.microprofile.lra.annotation.AfterLRA; +import org.eclipse.microprofile.lra.annotation.ws.rs.LRA; import org.eclipse.microprofile.lra.tck.participant.api.AfterLRAListener; import org.eclipse.microprofile.lra.tck.participant.api.AfterLRAParticipant; import org.eclipse.microprofile.lra.tck.participant.api.GenericLRAException; +import org.eclipse.microprofile.lra.tck.participant.api.LRAOnClassParticipant; +import org.eclipse.microprofile.lra.tck.participant.api.LRAOnClassParticipantCompensate; import org.eclipse.microprofile.lra.tck.participant.api.LraResource; import org.eclipse.microprofile.lra.tck.participant.api.NoLRAResource; import org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckResource; @@ -698,4 +705,59 @@ private void multiLevelNestedActivity(CompletionType how, int nestedCnt) throws resourcePath.getUri() + ")", 1); } } + + /** + * TCK test to verify that classes annotated with {@link LRA} are notified correctly the participant has afterLRA + * method + * + * @throws InterruptedException + * when waiting for the finishing the callbacks is interrupted + */ + @Test + public void testLRAParticipantAnnotationOnClass() throws WebApplicationException, InterruptedException { + URI lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS); + WebTarget resourcePath = tckSuiteTarget.path(LRA_PARTICIPANT_PATH).path(LRA_PARTICIPANT_WORK); + Response response = resourcePath + .request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text("")); + checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath); + lraClient.closeLRA(lra); + lraTestService.waitForCallbacks(lra); + + // verify that the LRA is now in one of the terminal states + lraMetric.assertFinished("testLRAParticipantAnnotationOnClass: LRA did not finish", lra, + LRAOnClassParticipant.class); + + // verify that the resource was notified of the final state of the LRA + lraMetric.assertClosed("testLRAParticipantAnnotationOnClass: end synchronization was not invoked on resource " + + resourcePath.getUri(), lra, LRAOnClassParticipant.class); + } + + /** + * TCK test to verify that classes annotated with {@link LRA} are notified correctly the participant has afterLRA + * and compensate methods + * + * @throws InterruptedException + * when waiting for the finishing the callbacks is interrupted + */ + @Test + public void testLRAParticipantAnnotationOnClassWithCompensate() + throws WebApplicationException, InterruptedException { + URI lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS); + WebTarget resourcePath = tckSuiteTarget.path(LRA_PARTICIPANT_PATH_COMPENSATE).path(LRA_PARTICIPANT_START); + Response response = resourcePath + .request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text("")); + checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath); + lraClient.closeLRA(lra); + lraTestService.waitForCallbacks(lra); + + // verify that the LRA is now in one of the terminal states + lraMetric.assertFinished("testLRAParticipantAnnotationOnClassWithCompensate: LRA did not finish", lra, + LRAOnClassParticipantCompensate.class); + + // verify that the resource was notified of the final state of the LRA + lraMetric.assertClosed( + "testLRAParticipantAnnotationOnClassWithCompensate: end synchronization was not invoked on resource " + + resourcePath.getUri(), + lra, LRAOnClassParticipantCompensate.class); + } } diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipant.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipant.java new file mode 100644 index 0000000..2f07fc4 --- /dev/null +++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipant.java @@ -0,0 +1,86 @@ +/********************************************************************** +* Copyright (c) 2022 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +* +* SPDX-License-Identifier: Apache-2.0 +**********************************************************************/package org.eclipse.microprofile.lra.tck.participant.api; +package org.eclipse.microprofile.lra.tck.participant.api; + +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 java.net.URI; + +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.eclipse.microprofile.lra.tck.service.LRAMetricService; +import org.eclipse.microprofile.lra.tck.service.LRAMetricType; +import org.eclipse.microprofile.lra.tck.service.LRATestService; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.HeaderParam; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Response; + +/** + * resource for testing that methods annotated with {@link AfterLRA} are notified correctly when an LRA terminates + */ +@ApplicationScoped +@LRA(value = LRA.Type.REQUIRED) +@Path(LRAOnClassParticipant.LRA_PARTICIPANT_PATH) +public class LRAOnClassParticipant { + public static final String LRA_PARTICIPANT_PATH = "lra-participant-class-annotation"; + public static final String LRA_PARTICIPANT_WORK = "work"; + + private static final String AFTER_LRA = "/after"; + + @Inject + private LRAMetricService lraMetricService; + + @Inject + private LRATestService lraTestService; + + @PUT + @Path("/complete") + @Complete + public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { + lraMetricService.incrementMetric(LRAMetricType.Completed, lraId, LRAOnClassParticipant.class); + return LRAResponse.completed(); + } + + @PUT + @Path(LRA_PARTICIPANT_WORK) + @LRA(value = LRA.Type.REQUIRED, end = false) + public Response activityWithLRA(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId, + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { + return Response.ok().build(); + } + + @PUT + @Path(AFTER_LRA) + @AfterLRA // this method will be called when the LRA associated with the method activityWithLRA finishes + public Response afterEnd(@HeaderParam(LRA_HTTP_ENDED_CONTEXT_HEADER) URI lraId, LRAStatus status) { + return lraTestService.processAfterLRAInfo(lraId, status, LRAOnClassParticipant.class, + LRA_PARTICIPANT_PATH + AFTER_LRA); + } +} diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipantCompensate.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipantCompensate.java new file mode 100644 index 0000000..b0610bb --- /dev/null +++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRAOnClassParticipantCompensate.java @@ -0,0 +1,95 @@ +/********************************************************************** +* Copyright (c) 2022 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +* +* SPDX-License-Identifier: Apache-2.0 +**********************************************************************/package org.eclipse.microprofile.lra.tck.participant.api; +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 java.net.URI; + +import org.eclipse.microprofile.lra.LRAResponse; +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.LRAStatus; +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 org.eclipse.microprofile.lra.tck.service.LRATestService; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.HeaderParam; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Response; + +/** + * resource for testing that methods annotated with {@link AfterLRA} are notified correctly when an LRA terminates + */ +@ApplicationScoped +@LRA(value = LRA.Type.REQUIRES_NEW) +@Path(LRAOnClassParticipantCompensate.LRA_PARTICIPANT_PATH_COMPENSATE) +public class LRAOnClassParticipantCompensate { + public static final String LRA_PARTICIPANT_PATH_COMPENSATE = "lra-participant-compensate-class-annotation"; + public static final String LRA_PARTICIPANT_START = "work"; + + private static final String AFTER_LRA = "/after"; + + @Inject + private LRAMetricService lraMetricService; + + @Inject + private LRATestService lraTestService; + + @PUT + @Path("/complete") + @Complete + public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { + lraMetricService.incrementMetric(LRAMetricType.Completed, lraId, LRAOnClassParticipantCompensate.class); + return LRAResponse.completed(); + } + + @PUT + @Path("/compensate") + @Compensate + public Response compensateWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { + lraMetricService.incrementMetric(LRAMetricType.Compensated, lraId, LRAOnClassParticipant.class); + + return LRAResponse.compensated(); + } + + @PUT + @Path(LRA_PARTICIPANT_START) + @LRA(value = LRA.Type.REQUIRED, end = false) + public Response activityWithLRA(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) URI recoveryId, + @HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lraId) { + return Response.ok().build(); + } + + @PUT + @Path(AFTER_LRA) + @AfterLRA // this method will be called when the LRA associated with the method + // activityWithLRA finishes + public Response afterEnd(@HeaderParam(LRA_HTTP_ENDED_CONTEXT_HEADER) URI lraId, LRAStatus status) { + return lraTestService.processAfterLRAInfo(lraId, status, LRAOnClassParticipantCompensate.class, + LRA_PARTICIPANT_PATH_COMPENSATE + AFTER_LRA); + } +}