Repository: eclipse/microprofile-lra (java)

Issue:
Harmonise expectations of implementations when detecting non-JAX-RS business logic
As per https://github.com/eclipse/microprofile-lra/blob/17e8b9d91f0563b189142f649e91283e0979cc85/spec/src/main/asciidoc/microprofile-lra-spec.adoc

I see the following:
> Non-JAX-RS afterLRA method
> A method annotated with @AfterLRA that is not a JAX-RS resource method MUST accept two arguments of type URI and LRAStatus, in that order. The first parameter holds an LRA context and the second parameter holds the final status of the LRA. If the signature does not conform to this requirement then the behaviour of the implementation is unspecified.

Which appears to impose a different expectation on the vendor from the way they should treat non-JAX-RS participant methods:

> Non-JAX-RS participant methods
> Declaring more than two arguments, different types of arguments or different return type for any non-JAX-RS method annotatated with the participant marker annotation MUST result in the prohibition of the successful application startup (e.g. through the deployment time runtime exception).

I think it would be useful to adopt one of these approaches and require it of both categories

Pull request description:
issue184 Harmonise expectations of implementations when detecting non…
…-JAX-RS business logic

resolves #184 

Signed-off-by: xstefank <xstefank122@gmail.com>

Patch:
diff --git a/spec/src/main/asciidoc/microprofile-lra-spec.adoc b/spec/src/main/asciidoc/microprofile-lra-spec.adoc
index 4f85c70..356347e 100644
--- a/spec/src/main/asciidoc/microprofile-lra-spec.adoc
+++ b/spec/src/main/asciidoc/microprofile-lra-spec.adoc
@@ -802,8 +802,9 @@ implementation of the LRA specification will not influence any running LRA.
 A method annotated with `@AfterLRA` that is not a JAX-RS resource method MUST accept
 two arguments of type URI and LRAStatus, in that order. The first parameter holds
 an LRA context and the second parameter holds the final status of the LRA. If the
-signature does not conform to this requirement then the behaviour of the implementation
-is unspecified.
+signature does not conform to this requirement then the implementation MUST
+prohibit the successful startup of the application (e.g. through the deployment time
+runtime exception).
 
 An example of a valid signature is:
 
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidAfterLRASignatureListener.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidAfterLRASignatureListener.java
new file mode 100644
index 0000000..29b09f0
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidAfterLRASignatureListener.java
@@ -0,0 +1,52 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE 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.
+ *******************************************************************************/
+package org.eclipse.microprofile.lra.tck.participant.nonjaxrs;
+
+import org.eclipse.microprofile.lra.annotation.AfterLRA;
+import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
+import org.eclipse.microprofile.lra.tck.TckInvalidSignaturesTests;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+
+/**
+ * TCK invalid LRA resource containing invalid signature for <code>&#64;AfterLRA</code> method. It's
+ * used for verification of deployment time invalid signature detection and error report in 
+ * {@link TckInvalidSignaturesTests}.
+ */
+@Path(InvalidAfterLRASignatureListener.RESOURCE_PATH)
+public class InvalidAfterLRASignatureListener {
+
+    public static final String RESOURCE_PATH = "invalid-after-lra";
+    public static final String START_LRA = "start-lra";
+
+    @GET
+    @Path(START_LRA)
+    @LRA(LRA.Type.REQUIRED)
+    public Response doInLRA() {
+        return Response.ok().build();
+    }
+
+    @AfterLRA
+    public void onLRAEnd(String lraId, String lraStatus) {
+        // intentionally empty
+    }
+}
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidArgumentTypesParticipant.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidArgumentTypesParticipant.java
index af01f48..8c4b4ec 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidArgumentTypesParticipant.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidArgumentTypesParticipant.java
@@ -23,6 +23,7 @@ import org.eclipse.microprofile.lra.annotation.Compensate;
 import org.eclipse.microprofile.lra.annotation.Forget;
 import org.eclipse.microprofile.lra.annotation.ParticipantStatus;
 import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
+import org.eclipse.microprofile.lra.tck.TckInvalidSignaturesTests;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -32,7 +33,7 @@ import java.net.URI;
 /**
  * TCK invalid LRA participant containing invalid type of arguments in the participant method signature
  * used for verification of deployment time invalid signature detection and error report in 
- * {@link org.eclipse.microprofile.lra.tck.TckInvalidParticipantSignaturesTests}
+ * {@link TckInvalidSignaturesTests}.
  */
 @Path("nonjaxrs-argument-type-nonjaxrs")
 public class InvalidArgumentTypesParticipant {
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidReturnTypeParticipant.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidReturnTypeParticipant.java
index dc1608d..3ee6515 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidReturnTypeParticipant.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/InvalidReturnTypeParticipant.java
@@ -21,6 +21,7 @@ package org.eclipse.microprofile.lra.tck.participant.nonjaxrs;
 
 import org.eclipse.microprofile.lra.annotation.Compensate;
 import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
+import org.eclipse.microprofile.lra.tck.TckInvalidSignaturesTests;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -29,7 +30,7 @@ import javax.ws.rs.core.Response;
 /**
  * TCK invalid LRA participant containing invalid return type in the participant method signature
  * used for verification of deployment time invalid signature detection and error report in  
- * {@link org.eclipse.microprofile.lra.tck.TckInvalidParticipantSignaturesTests}
+ * {@link TckInvalidSignaturesTests}.
  */
 @Path("nonjaxrs-return-type")
 public class InvalidReturnTypeParticipant {
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/TooManyArgsParticipant.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/TooManyArgsParticipant.java
index 9759d74..f8a9140 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/TooManyArgsParticipant.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/nonjaxrs/TooManyArgsParticipant.java
@@ -23,6 +23,7 @@ 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.TckInvalidSignaturesTests;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -32,7 +33,7 @@ import java.net.URI;
 /**
  * TCK invalid LRA participant containing too many arguments in the participant method signature
  * used for verification of deployment time invalid signature detection and error report in 
- * {@link org.eclipse.microprofile.lra.tck.TckInvalidParticipantSignaturesTests}
+ * {@link TckInvalidSignaturesTests}.
  */
 @Path("too-many-args-nonjaxrs")
 public class TooManyArgsParticipant {


Test patch:
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckInvalidParticipantSignaturesTests.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckInvalidSignaturesTests.java
similarity index 82%
rename from tck/src/main/java/org/eclipse/microprofile/lra/tck/TckInvalidParticipantSignaturesTests.java
rename to tck/src/main/java/org/eclipse/microprofile/lra/tck/TckInvalidSignaturesTests.java
index 54f0e53..d7018a1 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckInvalidParticipantSignaturesTests.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckInvalidSignaturesTests.java
@@ -19,6 +19,7 @@
  *******************************************************************************/
 package org.eclipse.microprofile.lra.tck;
 
+import org.eclipse.microprofile.lra.tck.participant.nonjaxrs.InvalidAfterLRASignatureListener;
 import org.eclipse.microprofile.lra.tck.participant.nonjaxrs.InvalidArgumentTypesParticipant;
 import org.eclipse.microprofile.lra.tck.participant.nonjaxrs.InvalidReturnTypeParticipant;
 import org.eclipse.microprofile.lra.tck.participant.nonjaxrs.TooManyArgsParticipant;
@@ -48,11 +49,12 @@ import org.junit.runner.RunWith;
  * </p>
  */
 @RunWith(Arquillian.class)
-public class TckInvalidParticipantSignaturesTests {
+public class TckInvalidSignaturesTests {
     
     private static final String INVALID_RETURN_TYPE_DEPLOYMENT = "nonjaxrs-return-type-deploy";
     private static final String TOO_MANY_ARGS_DEPLOYMENT = "too-many-args-deploy";
     private static final String INVALID_ARGUMENT_TYPE_DEPLOYMENT = "nonjaxrs-argument-type-deploy";
+    private static final String INVALID_AFTER_LRA_SIGNATURE_DEPLOYMENT = "invalid-after-lra-deploy";
 
     @Rule
     public ExpectedException expectedException = ExpectedException.none();
@@ -77,12 +79,17 @@ public class TckInvalidParticipantSignaturesTests {
     public static WebArchive deployInvalidArgumentTypeParticipant() {
         return createArchive(InvalidArgumentTypesParticipant.class);
     }
+    
+    @Deployment(name = INVALID_AFTER_LRA_SIGNATURE_DEPLOYMENT, managed = false)
+    public static WebArchive deployInvalidAfterLRASignatureResource() {
+        return createArchive(InvalidAfterLRASignatureListener.class);
+    }
 
-    private static WebArchive createArchive(Class<?> participantClass) {
-        String archiveName = participantClass.getSimpleName();
+    private static WebArchive createArchive(Class<?> resourceClass) {
+        String archiveName = resourceClass.getSimpleName();
         return ShrinkWrap
             .create(WebArchive.class, archiveName + ".war")
-            .addClasses(participantClass, JaxRsActivator.class)
+            .addClasses(resourceClass, JaxRsActivator.class)
             .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
     }
     
@@ -108,13 +115,21 @@ public class TckInvalidParticipantSignaturesTests {
     }
 
     /**
-     * Verigy that invalid type of argument (int) in participant method is detected
+     * Verify that invalid type of argument (int) in participant method is detected
      */
     @Test
     public void invalidArgumentTypeInParticipantMethodTest() {
         testInvalidDeployment(INVALID_ARGUMENT_TYPE_DEPLOYMENT);
     }
 
+    /**
+     * Verify that invalid <code>&#64;AfterLRA</code> method signature is detected
+     */
+    @Test
+    public void invalidAfterLRASignatureTest() {
+        testInvalidDeployment(INVALID_AFTER_LRA_SIGNATURE_DEPLOYMENT);
+    }
+
     private void testInvalidDeployment(String deploymentName) {
         deploymentNameRule.deploymentName = deploymentName;
         expectedException.expect(DeploymentException.class);