Repository: eclipse/microprofile-lra
Pull request #124 (2019-03-24 13:45:00)

issue122 Clarify LRA context on @Leave methods
#122 

The PR adds some text to clarify the LRA context and in particular clarifies the interaction between `@Leave` and `@LRA`

mmusgrov: Check that this PR is clear about the expected behaviour when the user sets the context in request and response headers.
rdebusscher: Spec and Javadoc are clear now around @Leave and @LRA interaction.
Thx @mmusgrov !
mmusgrov: @rdebusscher and @xstefank I added more text about the expected behaviour when the user sets the context in request and response headers. Can you re-verify that I still have the approval to merge.
Leave: Thanks, I think this will help. 
#include<iostream.h> #include<conio.h> #include<fstream.h> #include<stdio.h> #include<stdlib.h> void main() { clrscr(); ifstream fs; ofstream ft; char ch, fname1[20], fname2[20]; cout<<"Enter source file name with extension (like files.txt) : "; 	gets(fname1); fs.open(fname1); if(!fs) 	{ cout<<"Error in opening source file..!!"; getch(); exit(1); } cout<<"Enter target file name with extension (like filet.txt) : "; gets(fname2); ft.open(fname2); if(!ft) 	{ cout<<"Error in opening target file..!!"; fs.close(); getch(); exit(2); } while(fs.eof()==0) { fs>>ch; ft<<ch; } cout<<"File copied successfully..!!"; fs.close(); ft.close(); getch();

Sent from my iPhone

> On Mar 28, 2019, at 5:47 AM, Michael Musgrove <notifications@github.com> wrote:
> 
> @mmusgrov commented on this pull request.
> 
> In spec/src/main/asciidoc/microprofile-lra-spec.adoc:
> 
> > @@ -322,6 +326,35 @@ annotations defined in this specification then the LRA will not be made
>  available to the invoked method. However, any outgoing JAX-RS invocations
>  made during the execution of the method will still carry the original context.
>  
> +The user is allowed to manually assign the `context header` on JAX-RS requests
> +and responses:
> +
> +===== Setting the context on outgoing JAX-RS requests
> +
> +If the context is set on an outgoing JAX-RS request then it becomes the `active
> +context` for that invocation. When the invocation returns the `active context`
> +will depend on the behaviour of the remote resource:
> +
> +- if the remote resouce ends the context (and does not start a new one) then
> +  the `active context` will be whatever the client was using before it manually set
> +  the context on the outgoing header;
> +- if the remote resouce does not end the context (and does not start a new one)
> I think the problem is that I am wanting to support "implicit context propagation" where the spec implementation manages the association. We currently have both explicit (where the user is allowed to manage the context) and implicit. I acknowledge that supporting both can be a challenge to specify in a clear and unambiguous way. Manage thread association can also be tricky in reactive environments.
> 
> So would people be more comfortable if we say that the user has to manage the context on outgoing requests (I think Martin asked for this a while back) and the container manages the response header according to what is dictated by the @lra annotation.
> 
> If so then I will update this PR to remove the requirement for "implicit context propagation". Thoughts?
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or mute the thread.


Patch:
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Compensate.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Compensate.java
index 148d90c..cda13a4 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Compensate.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Compensate.java
@@ -27,12 +27,23 @@ import java.lang.annotation.Target;
 import java.time.temporal.ChronoUnit;
 
 /**
- * When a bean method executes in the context of an LRA any methods in the bean
- * class that are annotated with @Compensate will be used as a participant for
- * that LRA. If it is applied to multiple methods an arbitrary one is chosen.
+ * When a resource method executes in the context of an LRA and if the containing
+ * class contains a method annotated with `@Compensate` then the resource will
+ * be used as a participant for the LRA. If this associated LRA is subsequently
+ * cancelled then the method that this annotation is applied to will be invoked
+ * (if the annotation is present on more than one method then an arbitrary one
+ * will be chosen).
  *
- * If the associated LRA is subsequently cancelled the method on which this
- * annotation is present will be invoked.
+ * The id of the currently running LRA can be obtained by inspecting the incoming
+ * JAX-RS headers.
+ *
+ * Note that, according to the state model {@link LRAStatus} once an LRA has been
+ * asked to cancel it is no longer possible to join with it as a participant.
+ * Therefore combining this annotation with an `@LRA` annotation that does not
+ * start a new LRA will result in a `412 PreCondition Failed` status code and is
+ * not advised. On the other hand, combining it with an `@LRA` annotation that
+ * begins a new LRA can in certain use case make sense, but in this case the LRA
+ * that this method is being asked to compensate for will be unavailable.
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Complete.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Complete.java
index 187ebb5..a0cbc8c 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Complete.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Complete.java
@@ -27,12 +27,23 @@ import java.lang.annotation.Target;
 import java.time.temporal.ChronoUnit;
 
 /**
- * When a bean method executes in the context of an LRA any methods in the bean
- * class that are annotated with @Complete will be used as a participant for
- * that LRA. If it is applied to multiple methods an arbitrary one is chosen.
+ * When a resource method executes in the context of an LRA and if the containing
+ * class contains a method annotated with `@Complete` then the resource will
+ * be used as a participant for the LRA. If this associated LRA is subsequently
+ * closed then the method that this annotation is applied to will be invoked
+ * (if the annotation is present on more than one method then an arbitrary one
+ * will be chosen).
  *
- * If the associated LRA is subsequently closed the method on which this
- * annotation is present will be invoked.
+ * The id of the currently running LRA can be obtained by inspecting the incoming
+ * JAX-RS headers.
+ *
+ * Note that, according to the state model {@link LRAStatus} once an LRA has been
+ * asked to close it is no longer possible to join with it as a participant.
+ * Therefore combining this annotation with an `@LRA` annotation that does not
+ * start a new LRA will result in a `412 PreCondition Failed` status code and is
+ * not advised. On the other hand, combining it with an `@LRA` annotation that
+ * begins a new LRA can in certain use case make sense, but in this case the LRA
+ * that this method is being asked to complete for will be unavailable.
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Forget.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Forget.java
index cf3043f..3af5840 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Forget.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Forget.java
@@ -35,6 +35,13 @@ import java.lang.annotation.Target;
  * must be a standard JAX-RS endpoint annotated with the JAX-RS
  * <em>@DELETE</em> annotation.
  *
+ * The id of the currently running LRA can be obtained by inspecting the
+ * incoming JAX-RS headers.
+ *
+ * Since the participant generally needs to know the id of the LRA in order
+ * to clean up there is generally no benefit to combining this annotation
+ * with the `@LRA` annotation (though it is not prohibited).
+ *
  * Related information is provided in the javadoc for the {@link Status}
  */
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/LRAStatus.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/LRAStatus.java
index 59b003c..283d954 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/LRAStatus.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/LRAStatus.java
@@ -24,7 +24,7 @@ package org.eclipse.microprofile.lra.annotation;
  * A representation of the status of a Long Running Action according to a
  * LRA state model:
  *
- * The initial state Active is entered when a LRA is created.
+ * The initial state Active is entered when an LRA is created.
  *
  * The state Cancelling is entered when a request to cancel
  * an LRA is received. The transition to end state Cancelled
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Status.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Status.java
index ec6e905..b00081c 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/Status.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/Status.java
@@ -27,7 +27,7 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * LRA annoations support distributed communications amongst software
+ * LRA annotations support distributed communications amongst software
  * components and due to the unreliable nature of networks,
  * messages/requests can be lost, delayed or duplicated etc and the
  * implementation component responsible for invoking {@link Compensate}
@@ -53,6 +53,13 @@ import java.lang.annotation.Target;
  * status code (such as
  * {@link org.eclipse.microprofile.lra.client.IllegalLRAStateException}
  * but any exception that maps to 412 will do).
+ *
+ * The id of the currently running LRA can be obtained by inspecting the
+ * incoming JAX-RS headers.
+ *
+ * Since the participant generally needs to know the id of the LRA in order
+ * to report its status there is generally no benefit to combining this
+ * annotation with the `@LRA` annotation (though it is not prohibited).
  */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/LRA.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/LRA.java
index 588b7bb..4dc3740 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/LRA.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/LRA.java
@@ -64,7 +64,8 @@ import java.time.temporal.ChronoUnit;
  *
  * <p>
  * If an LRA is propagated to a resource that is not annotated with any
- * particular LRA behaviour then the LRA will be suspended. But if this resource
+ * particular LRA behaviour then the LRA will be suspended (ie the context
+ * will not be available to the resource). But if this resource
  * then performs an outgoing JAX-RS request then the suspended LRA must be propagated
  * on this second outgoing request. For example, suppose resource <code>A</code> starts an LRA
  * and then performs a JAX-RS request to resource <code>B</code> which does not contain any LRA
@@ -75,8 +76,9 @@ import java.time.temporal.ChronoUnit;
  * </p>
  *
  * <p>
- * Resource methods can access the LRA context id, if required, by injecting it via
- * the JAX-RS {@link HeaderParam} annotation. This may be useful, for example, for
+ * Resource methods can access the LRA context id, if required, by inspecting the request headers
+ * using standard JAX-RS mechanisms, ie `@Context` or by injecting it via the JAX-RS {@link HeaderParam}
+ * annotation with value {@value #LRA_HTTP_HEADER}. This may be useful, for example, for
  * associating business work with an LRA.
  * </p>
  */
@@ -100,7 +102,7 @@ public @interface LRA {
     /**
      * <p>
      * The Type element of the LRA annotation indicates whether a bean method
-     * is to be executed within the context of a LRA.
+     * is to be executed within the context of an LRA.
      *
      * <p>
      * If the method is to run in the context of an LRA and the annotated class
@@ -136,13 +138,13 @@ public @interface LRA {
     enum Type {
         /**
          * <p>
-         * If called outside a LRA context a new LRA will be created for the
+         * If called outside an LRA context a new LRA will be created for the
          * the duration of the method call and when the call completes it will
          * be closed.
          * </p>
          *
          * <p>
-         * If called inside a LRA context the invoked method will run with the
+         * If called inside an LRA context the invoked method will run with the
          * same context and the context will remain active after the method
          * completes.
          * </p>
@@ -151,13 +153,13 @@ public @interface LRA {
 
         /**
          * <p>
-         * If called outside a LRA context a new LRA will be created for the
+         * If called outside an LRA context a new LRA will be created for the
          * the duration of the method call and when the call completes it will
          * be terminated (closed or cancelled).
          * </p>
          *
          * <p>
-         * If called inside a LRA context it will be suspended and a new LRA
+         * If called inside an LRA context it will be suspended and a new LRA
          * context will be created for the duration of the call. When the method
          * finishes this new LRA will be terminated (closed or cancelled) and
          * the original context will be resumed.
@@ -187,19 +189,19 @@ public @interface LRA {
 
         /**
          *  <p>
-         *  If called outside a LRA context the bean method execution
-         *  must then continue outside a LRA context.
+         *  If called outside an LRA context the bean method execution
+         *  must then continue outside an LRA context.
          *  </p>
          *
          *  <p>
-         *  If called inside a LRA context the managed bean method execution
+         *  If called inside an LRA context the managed bean method execution
          *  must then continue inside this LRA context.
          *  </p>
          */
         SUPPORTS,
 
         /**
-         * The bean method is executed without a LRA context. If a context is
+         * The bean method is executed without an LRA context. If a context is
          * present on entry then it is suspended and then resumed after the
          * execution has completed.
          */
@@ -207,12 +209,12 @@ public @interface LRA {
 
         /**
          * <p>
-         * If called outside a LRA context the managed bean method execution
-         * must then continue outside a LRA context.
+         * If called outside an LRA context the managed bean method execution
+         * must then continue outside an LRA context.
          * </p>
          *
          * <p>
-         * If called inside a LRA context the method is not executed and a
+         * If called inside an LRA context the method is not executed and a
          * <code>412 Precondition Failed</code> HTTP status code is returned
          * to the caller.
          * </p>
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/Leave.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/Leave.java
index 393c94b..932d030 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/Leave.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/Leave.java
@@ -26,22 +26,42 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * A resource may be enlisted with an LRA if one of its resource methods
- * annotated with @LRA is invoked. If the resource also contains a method
- * annotated with @Leave, then invoking such a method in the context of the
- * same LRA that it has joined will result in the resource leaving the LRA
- * (ie it will not receive any callbacks when the LRA is later closed or
- * cancelled). However, leaving an LRA does not prohibit the resource from
- * rejoining the LRA if one of the @LRA methods is invoked again in the
- * context of the same LRA.
+ * <p>
+ * If a resource method is annotated with `@Leave` and is invoked in the context of
+ * an LRA and if the bean class has registered a participant with that LRA then
+ * it will be removed from the LRA just before the bean method is entered.
+ * The participant can forget about this LRA, in particular it will not
+ * be asked to complete or compensate when the LRA is subsequently ended.
+ * Even though the method runs without an LRA context, the implementation
+ * MUST still make the context available via a JAX-RS header and any outgoing
+ * JAX-RS invocations performed by the method will still carry the context that
+ * the participant has just left. Therefore the business logic must be
+ * careful about any JAX-RS invocations it makes in the body of the annotated
+ * method which may result in other resources being enlisted with the LRA.
+ * </p>
  *
- * Note that it is not possible to join or leave an LRA that has already
- * been asked to cancel or close.
+ * <p>
+ * If the resource method (or class) is also annotated with `@LRA` the method will
+ * execute with the context dictated by the `@LRA` annotation. If this `@LRA` annotation
+ * results in the creation of a new LRA then the participant will still be removed
+ * from the incoming context and will be enlisted with the new context (and the method
+ * will execute with this new context). Note that in this case the context exposed in
+ * the `LRA_HTTP_HEADER` JAX-RS header will be set to the new LRA (and not the original
+ * one), ie the orignal context will not be available to the business logic.
+ * </p>
  *
+ * <p>
+ * Also note that it is not possible to join or leave an LRA that has already
+ * been asked to cancel or close (since that would conflict with the
+ * the participant state model as defined in the LRA specification).
+ * </p>
+ *
+ * <p>
  * Leaving a particular LRA has no effect on any other LRA - ie the same
- * resource can be enlisted with many different LRA's and leaving one
+ * resource can be enlisted with many different LRAs and leaving one
  * particular LRA will not affect its participation in any of the other
  * LRA's it has joined.
+ * </p>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
diff --git a/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/NestedLRA.java b/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/NestedLRA.java
index d4697cf..994d97c 100644
--- a/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/NestedLRA.java
+++ b/api/src/main/java/org/eclipse/microprofile/lra/annotation/ws/rs/NestedLRA.java
@@ -49,9 +49,9 @@ import java.lang.annotation.Target;
  *   <li>SUPPORTS if there is an LRA present a new LRA is nested under otherwise
  *   a new top level LRA is begun
  *   <li>NOT_SUPPORTED nested does not make sense and operations on this resource
- *   that contain a LRA context will immediately return with a
+ *   that contain an LRA context will immediately return with a
  *   <code>412 Precondition Failed</code> HTTP status code
- *   <li>NEVER nested does not make sense and requests that carry a LRA context
+ *   <li>NEVER nested does not make sense and requests that carry an LRA context
  *   will immediately return with a <code>412 Precondition Failed</code> HTTP
  *   status code
  * </ul>
diff --git a/spec/src/main/asciidoc/microprofile-lra-spec.adoc b/spec/src/main/asciidoc/microprofile-lra-spec.adoc
index d816a0b..f271b47 100644
--- a/spec/src/main/asciidoc/microprofile-lra-spec.adoc
+++ b/spec/src/main/asciidoc/microprofile-lra-spec.adoc
@@ -304,6 +304,43 @@ that it could not until explicitly told that it can clean up by providing a meth
 
 If multiple methods are annotated with the same annotation an arbitrary one will be chosen.
 
+[[lra-context]]
+==== The LRA Context
+
+When a method is invoked in the context of an LRA its identifier MUST be made
+available to the business logic. This LRA is referred to as the `active context`.
+For JAX-RS resource methods the identifier is made available via request and
+response headers which the business method can obtain using standard JAX-RS mechanisms,
+ie `@Context` or by injecting a JAX-RS header param with the name specified by
+the Java constant `LRA_HTTP_HEADER` as defined <<source-LRA, in the LRA annotation class>>.
+This header is referred to as the `context header`.
+
+The implementation MUST propagate the `active context` on outgoing JAX-RS
+requests.
+footnote:[issue #35 (Do not define JAX-RS annotations on `@Compensate` methods)
+removes the requirement for some methods to be JAX-RS resources. The resolution
+of that issue should ensure the context is still available to business logic.
+
+If an LRA is propagated to a resource that is not annotated with any of the
+annotations defined in this specification then the LRA will not be made
+available to the invoked method. However, any outgoing JAX-RS invocations
+made during the execution of the method will still carry the original context.
+
+The user is allowed to manually assign the `context header` on JAX-RS requests
+and responses:
+
+===== Setting the context on outgoing JAX-RS requests
+
+If the context is set on an outgoing JAX-RS request then it becomes the `active
+context` for that invocation. When the invocation returns the context that
+was active before the invocation once again becomes the active context.
+
+===== Setting the context on JAX-RS responses
+
+A resource is allowed to manually set the `context header` on JAX-RS responses.
+Users should be careful when using this capability since this context will
+overwrite whatever the implementation has set.
+
 [[java-annotations]]
 ==== Starting and Ending LRAs
 
@@ -315,7 +352,7 @@ The annotation SHOULD be applied to JAX-RS annotated methods otherwise
 it MAY have no effect. It determines whether or not the annotated method
 will run in the context of an LRA and controls whether or not:
 
-- any incomming context should be suspended and if so if a new one should be started.
+- any incoming context should be suspended and if so if a new one should be started.
 - to start an new LRA.
 - to end any LRA context when the method ends.
 - to throw an exception if there should be an LRA present on method entry.
@@ -334,11 +371,6 @@ header param with name defined by the Java constant `LRA_HTTP_RECOVERY_HEADER` a
 Enlisting in an LRA is explained in more detail
 <<compensating-activities,in a later section>> of this document.
 
-A method which executes with an LRA context
-can obtain the context by injecting a JAX-RS header param with the name
-specified by the Java constant `LRA_HTTP_HEADER` as defined
-<<source-LRA, in the LRA annotation>>
-
 It is the `LRA.Type` element that provides fine grained control over the
 LRA for the duration of the execution of the annotated method:
 
@@ -346,20 +378,20 @@ The possible values of the `LRA.Type` element are defined in the javadoc
 provided in the quick overview links above but are worth repeating here:
 
 `LRA.Type.REQUIRED`::
-    If called outside a LRA context a new LRA will be created for the
+    If called outside an LRA context a new LRA will be created for the
     the duration of the method call and when the call completes it will
     be closed. +
      +
-    If called inside a LRA context the invoked method will run with the
+    If called inside an LRA context the invoked method will run with the
     same context and the context will remain active after the method
     completes.
 
 `LRA.Type.REQUIRES_NEW`::
-    If called outside a LRA context a new LRA will be created for the
+    If called outside an LRA context a new LRA will be created for the
     the duration of the method call and when the call completes it will
     be terminated (closed or cancelled). +
      +
-    If called inside a LRA context it will be suspended and a new LRA
+    If called inside an LRA context it will be suspended and a new LRA
     context will be created for the duration of the call. When the method
     finishes this new LRA will be terminated (closed or cancelled) and
     the original context will be resumed. +
@@ -379,22 +411,22 @@ provided in the quick overview links above but are worth repeating here:
     then continue within that context.
 
 `LRA.Type.SUPPORTS`::
-    If called outside a LRA context the bean method execution
-    must then continue outside a LRA context. +
+    If called outside an LRA context the bean method execution
+    must then continue outside an LRA context. +
      +
-    If called inside a LRA context the managed bean method execution
+    If called inside an LRA context the managed bean method execution
     must then continue inside this LRA context.
 
 `LRA.Type.NOT_SUPPORTED`::
-    The bean method is executed without a LRA context. If a context is
+    The bean method is executed without an LRA context. If a context is
     present on entry then it is suspended and then resumed after the
     execution has completed.
 
 `LRA.Type.NEVER`::
-    If called outside a LRA context the managed bean method execution
-    must then continue outside a LRA context. +
+    If called outside an LRA context the managed bean method execution
+    must then continue outside an LRA context. +
      +
-    If called inside a LRA context the method is not executed and a
+    If called inside an LRA context the method is not executed and a
     <code>412 Precondition Failed</code> HTTP status code is returned
     to the caller.
 
@@ -605,6 +637,12 @@ participant registration) allows participants to register opaque data when
 joining with an LRA. This data is made available to the completion and
 compensation callbacks]
 
+The javadoc for the <<source-Compensate,Compensate annotation>> provides
+more details about this annotation. 
+
+Similarly, the javadoc for the <<source-Complete,Complete annotation>>
+provides details about the `@Complete` annotation. 
+
 [[nesting-lras]]
 ==== Nesting LRAs
 
@@ -683,12 +721,15 @@ automatically cancel the LRA which will result in this method being invoked.
 [[leaving-an-lra]]
 ==== Leaving an LRA
 
-If a resource method annotated with `@Leave` is invoked in the context of
-a LRA and if the bean class has registered a participant with the active LRA
+If a resource method annotated with @Leave is invoked in the context of an
+LRA and if the bean class has registered a participant with the active LRA
 it will be removed from the LRA just before the bean method is entered
-(and will not be asked to complete or compensate when the LRA is subsequently
-ended). Even though the method runs without an LRA context the implementation
-MUST still make the context available via a JAX-RS header.
+(and will not be asked to complete or compensate when the LRA is
+subsequently ended). Even though the method runs without an LRA context
+the implementation MUST still make the context available via a JAX-RS header.
+
+The javadoc for the <<source-Leave,Leave annotation>> provides greater detail
+about this annotation. 
 
 An example of this annotation is shown next:
 
@@ -711,7 +752,7 @@ duplicated etc and the implementation component responsible for invoking
 participant completion/compensation logic may loose track of the status of
 a participant. In this case, ideally it would just resend the
 completion or compensation notification but if the participant does not
-support idempotency then it MUST be able to report its' status by
+support idempotency then it MUST be able to report its status by
 annotating one of the methods with the `@Status` annotation which should
 report the status according to the
 <<participant-state-model,participant state model>> by returning one of the
@@ -851,6 +892,27 @@ include::{sourcedir}/org/eclipse/microprofile/lra/annotation/ws/rs/LRA.java[LRA]
 ----
 <<<
 
+=== Leave Annotation
+[[source-Leave]]
+----
+include::{sourcedir}/org/eclipse/microprofile/lra/annotation/ws/rs/Leave.java[Leave]
+----
+<<<
+
+=== Compensate Annotation
+[[source-Compensate]]
+----
+include::{sourcedir}/org/eclipse/microprofile/lra/annotation/Compensate.java[Compensate]
+----
+<<<
+
+=== Complete Annotation
+[[source-Complete]]
+----
+include::{sourcedir}/org/eclipse/microprofile/lra/annotation/Complete.java[Leave]
+----
+<<<
+
 === IllegalLRAStateException
 [[source-IllegalLRAStateException]]
 ----
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/LRAClientOps.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/LRAClientOps.java
index 210c341..f7105e7 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/LRAClientOps.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/LRAClientOps.java
@@ -30,14 +30,6 @@ import javax.ws.rs.core.Response;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.time.temporal.ChronoUnit;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
 
 import static junit.framework.TestCase.fail;
 import static org.eclipse.microprofile.lra.tck.participant.api.NonParticipatingTckResource.END_PATH;
@@ -49,11 +41,8 @@ import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckR
 import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckResource.TCK_PARTICIPANT_RESOURCE_PATH;
 
 public class LRAClientOps {
-    private static final Logger LOGGER = Logger.getLogger(TckLRATypeTests.class.getName());
-
     /**
-     * TODO recovery needs to be properly speced: see the proposal
-     * on issue https://github.com/eclipse/microprofile-lra/issues/116
+     * TODO recovery needs to be properly speced
      * It is used in the two tests for participants that return 202:
      * {@link TckTests#acceptCancelTest()}  and {@link TckTests#acceptCloseTest()}
      * to connect to an endpoint that will trigger recovery (the alternative would
@@ -79,13 +68,9 @@ public class LRAClientOps {
     static final String LRA_RECOVERY_PATH_KEY = "lra.http.recovery.path";
 
     private final WebTarget target;
-    private final ScheduledExecutorService executor;
-    private final Map<LRATask, ScheduledFuture<?>> lraTasks;
 
     public LRAClientOps(WebTarget target) {
         this.target = target;
-        this.executor = Executors.newSingleThreadScheduledExecutor();
-        this.lraTasks = new HashMap<>();
     }
 
     // see if it is possible to join with an LRA - if it is possible to do that then the LRA is still active
@@ -120,8 +105,7 @@ public class LRAClientOps {
         return invokeRestEndpoint(lra == null ? null : lra.toASCIIString(), basePath, path, coerceResponse);
     }
 
-    // synchronize access to the connection since it is shared with the LRA background cancellation code
-    private synchronized Response invokeRestEndpoint(String lra, String basePath, String path, int coerceResponse) {
+    private Response invokeRestEndpoint(String lra, String basePath, String path, int coerceResponse) {
         WebTarget resourcePath = target.path(basePath).path(path).queryParam(STATUS_CODE_QUERY_NAME, coerceResponse);
         Invocation.Builder builder = resourcePath.request();
 
@@ -160,122 +144,26 @@ public class LRAClientOps {
         }
     }
 
-    public URI startLRA(URI parentLRA, String clientID, long timeout, ChronoUnit unit)
+    public URI startLRA(URI parentLRA, String clientID, Long timeout, ChronoUnit unit)
             throws GenericLRAException {
-        String lra = invokeRestEndpoint(parentLRA,
+        return toURI(invokeRestEndpoint(parentLRA,
                 TCK_NON_PARTICIPANT_RESOURCE_PATH, START_BUT_DONT_END_PATH, 200)
-                .readEntity(String.class);
-
-        if (timeout > 0L) {
-            scheduleCancelation(clientID, toURI(lra), timeout, unit);
-        }
+                .readEntity(String.class));
+    }
 
-        return toURI(lra);
+    void cancelLRA(String lra) {
+        invokeRestEndpointAndReturnLRA(lra, TCK_NON_PARTICIPANT_RESOURCE_PATH, END_PATH, 200);
     }
 
     void cancelLRA(URI lraId) throws GenericLRAException {
-        cancelCancelation(lraId);
-
         invokeRestEndpointAndReturnLRA(lraId.toASCIIString(), TCK_NON_PARTICIPANT_RESOURCE_PATH, END_PATH, 500);
     }
 
-    private void cancelLRA(String clientId, URI lra) {
-        LOGGER.warning("cancelling LRA from the timer: clientId: " + clientId + " LRA id: " + lra.toASCIIString());
-        cancelLRA(lra);
-        throw new IllegalArgumentException("LRA timed out prematurely");
-    }
-
     void closeLRA(URI lraId) throws GenericLRAException {
-        cancelCancelation(lraId);
-
         invokeRestEndpointAndReturnLRA(lraId.toASCIIString(), TCK_NON_PARTICIPANT_RESOURCE_PATH, END_PATH, 200);
     }
 
-    void closeLRA(String lraId) {
-        closeLRA(toURI(lraId));
-    }
-
-    private void leaveLRA(URI lra, String basePath, String resourcePath) throws GenericLRAException {
+    void leaveLRA(URI lra, String basePath, String resourcePath) throws GenericLRAException {
         invokeRestEndpoint(lra, basePath, resourcePath, 200);
     }
-
-    /*
-     * Include support for timing out LRAs. A timed out LRA will generally produce a test failure.
-     */
-
-    private static TimeUnit timeUnit(ChronoUnit unit) {
-        switch (unit) {
-            case NANOS:
-                return TimeUnit.NANOSECONDS;
-            case MICROS:
-                return TimeUnit.MICROSECONDS;
-            case MILLIS:
-                return TimeUnit.MILLISECONDS;
-            case SECONDS:
-                return TimeUnit.SECONDS;
-            case MINUTES:
-                return TimeUnit.MINUTES;
-            case HOURS:
-                return TimeUnit.HOURS;
-            case DAYS:
-                return TimeUnit.DAYS;
-            default:
-                throw new IllegalArgumentException("ChronoUnit cannot be converted to TimeUnit: " + unit);
-        }
-    }
-
-    /**
-     * arrange for an LRA to be automatically cancelled after a specified timeout
-     *
-     * @param clientId client assigned arbitrary identifier for the LRA
-     * @param lra the LRA that should be cancelled when the time limit is reached
-     * @param timeout the time to wait before attempting cancellation of the LRA
-     * @param unit the time unit
-     */
-    private void scheduleCancelation(String clientId, URI lra, long timeout, ChronoUnit unit) {
-        lraTasks.put(new LRATask(clientId, lra), executor.schedule(() -> cancelLRA(clientId, lra), timeout, timeUnit(unit)));
-    }
-
-    private void cancelCancelation(URI lraId) {
-        LRATask lra = new LRATask(null, lraId);
-
-        if (lraTasks.containsKey(lra)) {
-            lraTasks.remove(lra).cancel(false);
-        }
-    }
-
-    void cleanUp(Logger logger, String testName) {
-        lraTasks.forEach((lra, future) -> {
-            logger.warning("Test: " + testName + " didn't finish LRA " + lra.lra + " with clientId " + lra.clientId);
-            cancelLRA(lra.lra);
-        });
-    }
-
-    // class to store the clientId associated with an LRA
-    private class LRATask {
-        final String clientId; // client assigned arbitrary identifier for the LRA
-        final URI lra; // the LRA that clientId is associated with
-
-        LRATask(String clientId, URI lra) {
-            this.clientId = clientId;
-            this.lra = lra;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-            LRATask lraTask = (LRATask) o;
-            return lra.equals(lraTask.lra);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(lra);
-        }
-    }
 }
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRATypeTckResource.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRATypeTckResource.java
deleted file mode 100644
index 230279d..0000000
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LRATypeTckResource.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *******************************************************************************
- * 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.api;
-
-import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.ws.rs.HeaderParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.core.Response;
-
-import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_HEADER;
-
-@ApplicationScoped
-@Path(LRATypeTckResource.TCK_LRA_TYPE_RESOURCE_PATH)
-public class LRATypeTckResource {
-    public static final String TCK_LRA_TYPE_RESOURCE_PATH = "lra-type-tck-resource";
-
-    public static final String REQUIRED_PATH = "/required";
-    public static final String REQUIRES_NEW_PATH = "/requires-new";
-    public static final String SUPPORTS_PATH = "/supports";
-    public static final String NOT_SUPPORTED_PATH = "/not-supported";
-    public static final String MANDATORY_PATH = "/mandatory";
-    public static final String NEVER_PATH = "/never";
-
-    public static final String REQUIRED_WITH_END_FALSE_PATH = "/end-required";
-    public static final String REQUIRES_NEW_WITH_END_FALSE_PATH = "/end-requires-new";
-    public static final String SUPPORTS_WITH_END_FALSE_PATH = "/end-supports";
-    public static final String NOT_SUPPORTED_WITH_END_FALSE_PATH = "/end-not-supported";
-    public static final String MANDATORY_WITH_END_FALSE_PATH = "/end-mandatory";
-    public static final String NEVER_WITH_END_FALSE_PATH = "/end-never";
-
-    // resource methods for each LRA.Type attribute
-    @GET
-    @Path(REQUIRED_PATH)
-    @LRA(value = LRA.Type.REQUIRED)
-    public Response requiredLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(REQUIRES_NEW_PATH)
-    @LRA(value = LRA.Type.REQUIRES_NEW)
-    public Response requiresNewLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(MANDATORY_PATH)
-    @LRA(value = LRA.Type.MANDATORY)
-    public Response mandatoryLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(SUPPORTS_PATH)
-    @LRA(value = LRA.Type.SUPPORTS)
-    public Response supportsLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(NOT_SUPPORTED_PATH)
-    @LRA(value = LRA.Type.NOT_SUPPORTED)
-    public Response notSupportedLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(NEVER_PATH)
-    @LRA(value = LRA.Type.NEVER)
-    public Response neverLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-
-    // similar set of resources methods but with the LRA.end attribute set to false
-    @GET
-    @Path(REQUIRED_WITH_END_FALSE_PATH)
-    @LRA(value = LRA.Type.REQUIRED, end = false)
-    public Response requiredEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(REQUIRES_NEW_WITH_END_FALSE_PATH)
-    @LRA(value = LRA.Type.REQUIRES_NEW, end = false)
-    public Response requiresNewEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(MANDATORY_WITH_END_FALSE_PATH)
-    @LRA(value = LRA.Type.MANDATORY, end = false)
-    public Response mandatoryEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(SUPPORTS_WITH_END_FALSE_PATH)
-    @LRA(value = LRA.Type.SUPPORTS, end = false)
-    public Response supportsEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(NOT_SUPPORTED_WITH_END_FALSE_PATH)
-    @LRA(value = LRA.Type.NOT_SUPPORTED, end = false)
-    public Response notSupportedEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-    @GET
-    @Path(NEVER_WITH_END_FALSE_PATH)
-    @LRA(value = LRA.Type.NEVER, end = false)
-    public Response neverEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok(lraId).build();
-    }
-}
\ No newline at end of file
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraCancelOnController.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraCancelOnController.java
index 70be30a..cc37905 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraCancelOnController.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraCancelOnController.java
@@ -66,7 +66,6 @@ public class LraCancelOnController {
     public static final String CANCEL_ON_FAMILY_DEFAULT_4XX = "cancelOnFamilyDefault4xx";
     /**
      * Default return status for cancelling LRA is <code>4xx</code> and <code>5xx</code>
-     * @return JAX-RS response
      */
     @GET
     @Path(CANCEL_ON_FAMILY_DEFAULT_4XX)
@@ -78,7 +77,6 @@ public class LraCancelOnController {
     public static final String CANCEL_ON_FAMILY_DEFAULT_5XX = "cancelOnFamilyDefault5xx";
     /**
      * Default return status for cancelling LRA is <code>4xx</code> and <code>5xx</code>
-     * @return JAX-RS response
      */
     @GET
     @Path(CANCEL_ON_FAMILY_DEFAULT_5XX)
@@ -91,7 +89,6 @@ public class LraCancelOnController {
     /**
      * Cancel on family is set to <code>3xx</code>. The <code>3xx</code> return code
      * has to cancel the LRA.
-     * @return JAX-RS response
      */
     @GET
     @Path(CANCEL_ON_FAMILY_3XX)
@@ -105,7 +102,6 @@ public class LraCancelOnController {
     /**
      * Cancel on is set to <code>301</code>. The <code>301</code> return code
      * has to cancel the LRA.
-     * @return JAX-RS response
      */
     @GET
     @Path(CANCEL_ON_301)
@@ -120,7 +116,6 @@ public class LraCancelOnController {
      * Cancel on family is set to <code>4xx</code>,
      * the code from other families (e.g. for <code>5xx</code>
      * should not cancel but should go with close the LRA.
-     * @return JAX-RS response
      */
     @GET
     @Path(NOT_CANCEL_ON_FAMILY_5XX)
@@ -146,7 +141,6 @@ public class LraCancelOnController {
      * the {@link Compensate} method {@link #compensateWork(String, String)}
      * will be called only once for the test invocation.
      * </p>
-     * @return JAX-RS response
      */
     @GET
     @Path(CANCEL_FROM_REMOTE_CALL)
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/ParticipatingTckResource.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/ParticipatingTckResource.java
index c6e2d50..be4dcc0 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/ParticipatingTckResource.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/ParticipatingTckResource.java
@@ -25,7 +25,6 @@ import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
 import org.eclipse.microprofile.lra.annotation.ws.rs.Leave;
 
 import javax.enterprise.context.ApplicationScoped;
-import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.PUT;
@@ -45,7 +44,6 @@ public class ParticipatingTckResource {
 
     public static final String TCK_PARTICIPANT_RESOURCE_PATH = "participating-tck-resource";
     public static final String JOIN_WITH_EXISTNG_LRA_PATH = "/join-with-existing-lra";
-    public static final String JOIN_WITH_EXISTNG_LRA_PATH2 = "/join-with-existing-lra2";
     public static final String JOIN_WITH_NEW_LRA_PATH = "/join-with-new-LRA";
     public static final String COMPLETED_CNT_PATH = "/completed-count";
     public static final String COMPENSATED_CNT_PATH = "/compensated-count";
@@ -94,7 +92,7 @@ public class ParticipatingTckResource {
         return Response.ok().build();
     }
 
-    @GET
+    @PUT
     @Path(COMPLETED_CNT_PATH)
     @Produces(MediaType.APPLICATION_JSON)
     @LRA(LRA.Type.NOT_SUPPORTED)
@@ -102,7 +100,7 @@ public class ParticipatingTckResource {
         return Response.ok(COMPLETED_COUNT.get()).build();
     }
 
-    @GET
+    @PUT
     @Path(COMPENSATED_CNT_PATH)
     @Produces(MediaType.APPLICATION_JSON)
     @LRA(LRA.Type.NOT_SUPPORTED)
@@ -119,13 +117,6 @@ public class ParticipatingTckResource {
         return Response.ok().build();
     }
 
-    @PUT
-    @Path(ParticipatingTckResource.JOIN_WITH_EXISTNG_LRA_PATH2)
-    @LRA(value = LRA.Type.MANDATORY, end = false)
-    public Response joinWithExistingLRA2(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
-        return Response.ok().build();
-    }
-
     @PUT
     @Path(ParticipatingTckResource.JOIN_WITH_NEW_LRA_PATH)
     @LRA(value = LRA.Type.REQUIRES_NEW, end = false)
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/Util.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/Util.java
index 2138acc..58c315d 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/Util.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/Util.java
@@ -163,8 +163,6 @@ public class Util {
 
     /**
      * see {@link Util#adjust(int, double)}
-     *
-     * @return adjusted value by factor
      */
     public static long adjust(long value, double factor) {
         if(value < 0){


Test patch:
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckLRATypeTests.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckLRATypeTests.java
deleted file mode 100644
index 03b5f8f..0000000
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckLRATypeTests.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- *******************************************************************************
- * 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;
-
-import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
-import org.eclipse.microprofile.lra.tck.participant.api.Util;
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.asset.EmptyAsset;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-
-import javax.inject.Inject;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Invocation;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.Response;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.time.temporal.ChronoUnit;
-import java.util.logging.Logger;
-
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.MANDATORY_WITH_END_FALSE_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.MANDATORY_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.NEVER_WITH_END_FALSE_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.NEVER_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.NOT_SUPPORTED_WITH_END_FALSE_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.NOT_SUPPORTED_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.REQUIRED_WITH_END_FALSE_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.REQUIRED_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.REQUIRES_NEW_WITH_END_FALSE_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.REQUIRES_NEW_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.SUPPORTS_WITH_END_FALSE_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.SUPPORTS_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.LRATypeTckResource.TCK_LRA_TYPE_RESOURCE_PATH;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * <p>
- * Tests that validate that the implementation of the {@link LRA.Type} attribute is correct
- * </p>
- *
- * <p>
- * For each of the type values there are 4 tests:
- * <ul>
- *     <li>start an LRA before invoking the resource method annotated with {@link LRA#end()} set to true</li>
- *     <li>do not start an LRA before invoking the resource method annotated with {@link LRA#end()} set to true</li>
- *     <li>start an LRA before invoking the resource method annotated with {@link LRA#end()} set to false</li>
- *     <li>do not start an LRA before invoking the resource method annotated with {@link LRA#end()} set to false</li>
- * </ul>
- *  *
- * <p>
- * Each test then validates {@link TckLRATypeTests#resourceRequest} that:
- * <ul>
- *     <li>the correct JAX-RS status was returned</li>
- *     <li>the resource method executed with the correct LRA context</li>
- *     <li>the LRA started by the resource method is closed if {@link LRA#end()} is true</li>
- *     <li>the LRA started by the resource method is not closed if {@link LRA#end()} is false</li>
- * </ul>
- */
-@RunWith(Arquillian.class)
-public class TckLRATypeTests {
-    private static final Logger LOGGER = Logger.getLogger(TckLRATypeTests.class.getName());
-
-    @Rule public TestName testName = new TestName();
-
-    @Inject
-    private LraTckConfigBean config;
-
-    private LRAClientOps lraClient;
-
-    private static Client tckSuiteClient;
-
-    private WebTarget tckSuiteTarget;
-
-    @Deployment(name = "lra-type-tck-tests")
-    public static WebArchive deploy() {
-        String archiveName = TckLRATypeTests.class.getSimpleName().toLowerCase();
-        return ShrinkWrap
-            .create(WebArchive.class, archiveName + ".war")
-            .addPackages(true, "org.eclipse.microprofile.lra.tck")
-            .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
-    }
-    
-    @AfterClass
-    public static void afterClass() {
-        if(tckSuiteClient != null) {
-            tckSuiteClient.close();
-        }
-    }
-
-    @Before
-    public void before() {
-        LOGGER.info("Running test: " + testName.getMethodName());
-        setUpTestCase();
-
-        try {
-            tckSuiteTarget = tckSuiteClient.target(URI.create(new URL(config.tckSuiteBaseUrl()).toExternalForm()));
-            lraClient = new LRAClientOps(tckSuiteTarget);
-        } catch (MalformedURLException mfe) {
-            throw new IllegalStateException("Cannot create URL for the LRA TCK suite base url " + config.tckSuiteBaseUrl(), mfe);
-        }
-    }
-
-    @After
-    public void after() {
-        lraClient.cleanUp(LOGGER, testName.getMethodName());
-    }
-
-    private void setUpTestCase() {
-        tckSuiteClient = ClientBuilder.newClient();
-    }
-
-    // enum to indicate which checks to perform on the expected and actual active LRA after running a resource method
-    private enum MethodLRACheck {
-        NONE, NOT_PRESENT, EQUALS, NOT_EQUALS
-    }
-
-    @Test
-    public void requiredWithLRA() {
-        resourceRequest(REQUIRED_PATH, true, 200, MethodLRACheck.EQUALS, false);
-    }
-
-    @Test
-    public void requiredWithoutLRA() {
-        resourceRequest(REQUIRED_PATH, false, 200, MethodLRACheck.NOT_EQUALS, false);
-    }
-
-    @Test
-    public void requiresNewWithLRA() {
-        resourceRequest(REQUIRES_NEW_PATH, true, 200, MethodLRACheck.NOT_EQUALS, false);
-    }
-
-    @Test
-    public void requiresNewWithoutLRA() {
-        resourceRequest(REQUIRES_NEW_PATH, false, 200, MethodLRACheck.NOT_EQUALS, false);
-    }
-
-    @Test
-    public void mandatoryWithLRA() {
-        resourceRequest(MANDATORY_PATH, true, 200, MethodLRACheck.EQUALS, false);
-    }
-
-    @Test
-    public void mandatoryWithoutLRA() {
-        resourceRequest(MANDATORY_PATH, false, 412, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void supportsWithLRA() {
-        resourceRequest(SUPPORTS_PATH, true, 200, MethodLRACheck.EQUALS, false);
-    }
-
-    @Test
-    public void supportsWithoutLRA() {
-        resourceRequest(SUPPORTS_PATH, false, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void notSupportedWithRA() {
-        resourceRequest(NOT_SUPPORTED_PATH, true, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void notSupportedWithoutLRA() {
-        resourceRequest(NOT_SUPPORTED_PATH, false, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void neverWithRA() {
-        resourceRequest(NEVER_PATH, true, 412, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void neverWithoutLRA() {
-        resourceRequest(NEVER_PATH, false, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    // same set of tests except that the invoked method has end = false set on the LRA annotation
-
-    @Test
-    public void requiredEndWithLRA() {
-        resourceRequest(REQUIRED_WITH_END_FALSE_PATH, true, 200, MethodLRACheck.EQUALS, true);
-    }
-
-    @Test
-    public void requiredEndWithoutLRA() {
-        resourceRequest(REQUIRED_WITH_END_FALSE_PATH, false, 200, MethodLRACheck.NOT_EQUALS, true);
-    }
-
-    @Test
-    public void requiresEndNewWithLRA() {
-        resourceRequest(REQUIRES_NEW_WITH_END_FALSE_PATH, true, 200, MethodLRACheck.NOT_EQUALS, true);
-    }
-
-    @Test
-    public void requiresEndNewWithoutLRA() {
-        resourceRequest(REQUIRES_NEW_WITH_END_FALSE_PATH, false, 200, MethodLRACheck.NOT_EQUALS, true);
-    }
-
-    @Test
-    public void mandatoryEndWithLRA() {
-        resourceRequest(MANDATORY_WITH_END_FALSE_PATH, true, 200, MethodLRACheck.EQUALS, true);
-    }
-
-    @Test
-    public void mandatoryEndWithoutLRA() {
-        resourceRequest(MANDATORY_WITH_END_FALSE_PATH, false, 412, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void supportsEndWithLRA() {
-        resourceRequest(SUPPORTS_WITH_END_FALSE_PATH, true, 200, MethodLRACheck.EQUALS, true);
-    }
-
-    @Test
-    public void supportsEndWithoutLRA() {
-        resourceRequest(SUPPORTS_WITH_END_FALSE_PATH, false, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void notSupportedEndWithRA() {
-        resourceRequest(NOT_SUPPORTED_WITH_END_FALSE_PATH, true, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void notSupportedEndWithoutLRA() {
-        resourceRequest(NOT_SUPPORTED_WITH_END_FALSE_PATH, false, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void neverWithEndRA() {
-        resourceRequest(NEVER_WITH_END_FALSE_PATH, true, 412, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    @Test
-    public void neverWithoutEndLRA() {
-        resourceRequest(NEVER_WITH_END_FALSE_PATH, false, 200, MethodLRACheck.NOT_PRESENT, false);
-    }
-
-    /**
-     * Perform a JAX-RS resource request and check the resulting status and whether or not it ran with
-     * the correct LRA context.
-     *
-     * @param path the resource path of the JAX-RS method to invoke
-     * @param startLRA indicates whether or not an active context should be present on the request
-     * @param expectedStatus the expected JAX-RS status code in the response
-     * @param lraCheckType the type of check to perform on the request context and the context specified
-     *                     by the {@link LRA.Type} annotation
-     * @param methodLRAShouldBeActive if true the LRA started by the invoked method should still
-     *                               be active after the resource invocation completes
-     */
-    private void resourceRequest(String path, boolean startLRA, int expectedStatus, MethodLRACheck lraCheckType,
-                                 boolean methodLRAShouldBeActive) {
-        Invocation.Builder target = tckSuiteTarget.path(TCK_LRA_TYPE_RESOURCE_PATH)
-                .path(path).request();
-        URI lra = startLRA ? lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS) : null;
-
-        if (lra != null) {
-            target = target.header(LRA.LRA_HTTP_HEADER, lra);
-        }
-
-        Response response = target.get();
-
-        try {
-            String methodLRA = response.readEntity(String.class);
-            String incomingLRA = lra == null ? "" : lra.toASCIIString();
-
-            assertEquals(testName.getMethodName() + ": Unexpected status", expectedStatus, response.getStatus());
-
-            if (response.getStatus() == Response.Status.PRECONDITION_FAILED.getStatusCode()) {
-                // 412 errors should abort running the target method so skip the LRA check
-                lraCheckType = MethodLRACheck.NONE;
-                methodLRAShouldBeActive = false;
-            }
-
-            switch (lraCheckType) {
-                case NOT_PRESENT:
-                    assertEquals(testName.getMethodName() + ": Resource method should not have run with an LRA: " + methodLRA,
-                            0, methodLRA.length());
-                    break;
-                case EQUALS:
-                    assertEquals(testName.getMethodName() + ": Resource method should have ran with the incoming LRA",
-                            incomingLRA, methodLRA);
-                    break;
-                case NOT_EQUALS:
-                    assertNotEquals(testName.getMethodName() + ": Resource method should not have run with the incoming LRA",
-                            incomingLRA, methodLRA);
-                    break;
-                default:
-                    break;
-            }
-
-            if (methodLRAShouldBeActive) {
-                // validate that the method ran with an LRA and that it is still active
-                assertNotEquals(testName.getMethodName() + ": Resource method should not have run with an LRA: " + methodLRA,
-                        0, methodLRA.length());
-                assertFalse(lraClient.isLRAFinished(methodLRA));
-                lraClient.closeLRA(methodLRA);
-            } else if (methodLRA.length() != 0) {
-                // otherwise it should be finished
-                assertTrue(lraClient.isLRAFinished(methodLRA));
-            }
-
-            if (lra != null) {
-                lraClient.closeLRA(lra);
-            }
-        } finally {
-            response.close();
-        }
-    }
-
-    /**
-     * The started LRA will be named based on the class name and the running test name.
-     */
-    private String lraClientId() {
-        return this.getClass().getSimpleName() + "#" + testName.getMethodName();
-    }
-
-    /**
-     * Adjusting the default timeout by the specified timeout factor
-     * which can be defined by user.
-     */
-    private long lraTimeout() {
-        return Util.adjust(LraTckConfigBean.LRA_TIMEOUT_MILLIS, config.timeoutFactor());
-    }
-}
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 ed5472c..4912343 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
@@ -22,11 +22,6 @@ package org.eclipse.microprofile.lra.tck;
 import static org.eclipse.microprofile.lra.tck.participant.api.LraController.ACCEPT_WORK;
 import static org.eclipse.microprofile.lra.tck.participant.api.LraController.LRA_CONTROLLER_PATH;
 import static org.eclipse.microprofile.lra.tck.participant.api.LraController.TRANSACTIONAL_WORK_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckResource.COMPENSATED_CNT_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckResource.COMPLETED_CNT_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckResource.JOIN_WITH_EXISTNG_LRA_PATH;
-import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckResource.JOIN_WITH_EXISTNG_LRA_PATH2;
-import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckResource.TCK_PARTICIPANT_RESOURCE_PATH;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -192,7 +187,7 @@ public class TckTests {
         WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH);
         Response response = resourcePath.request().put(Entity.text(""));
 
-        String lraId = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);
+        String lraId = checkStatusReadAndClose(Response.Status.OK, response, resourcePath);
 
         // validate that the LRA coordinator no longer knows about lraId
         assertTrue("LRA work was processed and the annotated method finished but the LRA id '" + lraId + "'"
@@ -263,7 +258,7 @@ public class TckTests {
         Response response = resourcePath
                 .request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
 
-        checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
+        checkStatusAndClose(Response.Status.OK, response, resourcePath);
 
         // validate that the LRA coordinator still knows about lraId
         assertFalse("LRA '" + lra + "' should be active as it is not closed yet.",
@@ -288,7 +283,7 @@ public class TckTests {
         WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH);
         Response response = resourcePath
                 .request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
-        checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
+        checkStatusAndClose(Response.Status.OK, response, resourcePath);
         lraClient.closeLRA(lra);
         assertTrue("LRA '" + lra + "' should be active as it is not closed yet.",
                 lraClient.isLRAFinished(lra));
@@ -301,17 +296,17 @@ public class TckTests {
         WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH);
         Response response = resourcePath.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
 
-        checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
+        checkStatusAndClose(Response.Status.OK, response, resourcePath);
 
         // perform a second request to the same method in the same LRA context to validate that multiple participants are not registered
         resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH);
         response = resourcePath.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
-        checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
+        checkStatusAndClose(Response.Status.OK, response, resourcePath);
 
         // call a method annotated with @Leave (should remove the participant from the LRA)
         resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path("leave");
         response = resourcePath.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
-        checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
+        checkStatusAndClose(Response.Status.OK, response, resourcePath);
 
         lraClient.closeLRA(lra);
 
@@ -331,7 +326,7 @@ public class TckTests {
         // check that the method started an LRA
         Object lraHeader = response.getHeaders().getFirst(LRA.LRA_HTTP_HEADER);
 
-        String lraId = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);
+        String lraId = checkStatusReadAndClose(Response.Status.OK, response, resourcePath);
 
         // the value returned via the header and body should be equal
 
@@ -397,7 +392,7 @@ public class TckTests {
         Response response = resourcePath
                 .request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
 
-        checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
+        checkStatusAndClose(Response.Status.OK, response, resourcePath);
 
         if (close) {
             lraClient.closeLRA(lra);
@@ -414,7 +409,7 @@ public class TckTests {
             Response response2 = recoveryPath
                     .request().get();
 
-            checkStatusAndCloseResponse(Response.Status.OK, response2, recoveryPath);
+            checkStatusAndClose(Response.Status.OK, response2, recoveryPath);
         }
 
         int completionCount = getCompletedCount() - beforeCompletionCount;
@@ -447,7 +442,7 @@ public class TckTests {
         Response response = resourcePath.request().header(LRA.LRA_HTTP_HEADER, lra)
                 .put(Entity.text(""));
 
-        String lraId = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);
+        String lraId = checkStatusReadAndClose(Response.Status.OK, response, resourcePath);
 
         assertEquals("While calling non-LRA method the controller returns not expected LRA id",
                 lraId, lra.toString());
@@ -467,138 +462,7 @@ public class TckTests {
                 + "The test call went to " + resourcePath.getUri(), beforeCompensatedCount + 1, compensatedCount);
     }
 
-    /**
-     * client invokes the same participant method twice in the same LRA context
-     * cancel the LRA
-     * check that the participant was asked to compensate only once
-     */
-    @Test
-    public void joinWithOneResourceSameMethodTwiceWithCancel() throws WebApplicationException {
-        joinWithOneResource("joinWithOneResourceSameMethodTwiceWithCancel",
-                false, JOIN_WITH_EXISTNG_LRA_PATH, JOIN_WITH_EXISTNG_LRA_PATH);
-    }
-
-    /**
-     * client invokes the same participant twice but using different methods in the same LRA context
-     * cancel the LRA
-     * check that the participant was asked to compensate only once
-     */
-    @Test
-    public void joinWithOneResourceDifferentMethodTwiceWithCancel() throws WebApplicationException {
-        joinWithOneResource("joinWithOneResourceDifferentMethodTwiceWithCancel",
-                false, JOIN_WITH_EXISTNG_LRA_PATH, JOIN_WITH_EXISTNG_LRA_PATH2);
-    }
-
-    /**
-     * client invokes the same participant method twice in the same LRA context
-     * close the LRA
-     * check that the participant was asked to complete only once
-     */
-    @Test
-    public void joinWithOneResourceSameMethodTwiceWithClose() throws WebApplicationException {
-        joinWithOneResource("joinWithOneResourceSameMethodTwiceWithClose",
-                true, JOIN_WITH_EXISTNG_LRA_PATH, JOIN_WITH_EXISTNG_LRA_PATH);
-    }
-
-    /**
-     * client invokes the same participant twice but using different methods in the same LRA context
-     * close the LRA
-     * check that the participant was asked to complete only once
-     */
-    @Test
-    public void joinWithOneResourceDifferentMethodTwiceWithClose() throws WebApplicationException {
-        joinWithOneResource("joinWithOneResourceDifferentMethodTwiceWithClose",
-                true, JOIN_WITH_EXISTNG_LRA_PATH, JOIN_WITH_EXISTNG_LRA_PATH2);
-    }
-
-    /**
-     * client invokes different participant in the same LRA context
-     * close the LRA
-     * check that both participants were asked to complete
-     */
-    @Test
-    public void joinWithTwoResourcesWithClose() throws WebApplicationException {
-        joinWithTwoResources(true);
-    }
-
-    /**
-     * client invokes different participants in the same LRA context
-     * cancel the LRA
-     * check that both participants were asked to compensate
-     */
-    @Test
-    public void joinWithTwoResourcesWithCancel() throws WebApplicationException {
-        joinWithTwoResources(false);
-    }
-
-    private void joinWithOneResource(String methodName, boolean close, String resouce1Method, String resouce2Method)
-            throws WebApplicationException {
-        // get the initial values for the number of completions and compensations
-        int completedCount = getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPLETED_CNT_PATH);
-        int compensatedCount = getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPENSATED_CNT_PATH);
-
-        // set up the web target for the test
-        WebTarget resource1Path = tckSuiteTarget.path(TCK_PARTICIPANT_RESOURCE_PATH).path(resouce1Method);
-        WebTarget resource2Path = tckSuiteTarget.path(TCK_PARTICIPANT_RESOURCE_PATH).path(resouce2Method);
-
-        URI lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS);
-
-        // invoke the same JAX-RS resources twicein the context of the lra which should enlist the resource only once:
-        Response response1 = resource1Path.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
-        checkStatusAndCloseResponse(Response.Status.OK, response1, resource1Path);
-        Response response2 = resource2Path.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
-        checkStatusAndCloseResponse(Response.Status.OK, response2, resource2Path);
-
-        if (close) {
-            lraClient.closeLRA(lra);
-
-            assertTrue(methodName + ": resource should have completed once with no compensations",
-                    completedCount + 1 == getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPLETED_CNT_PATH)
-                            && compensatedCount == getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPENSATED_CNT_PATH));
-        } else {
-            lraClient.cancelLRA(lra);
-
-            assertTrue(methodName + ":: resource should have compensated once with no completions",
-                    completedCount == getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPLETED_CNT_PATH)
-                            && compensatedCount + 1 == getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPENSATED_CNT_PATH));
-        }
-    }
-
-    private void joinWithTwoResources(boolean close) throws WebApplicationException {
-        // get the initial values for the number of completions and compensations
-        int completedCount1 = getActivityCount(LRA_CONTROLLER_PATH, "completedactivitycount");
-        int compensatedCount1 = getActivityCount(LRA_CONTROLLER_PATH, "compensatedactivitycount");
-        int completedCount2 = getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPLETED_CNT_PATH);
-        int compensatedCount2 = getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPENSATED_CNT_PATH);
-
-        // set up the web target for the test
-        WebTarget resource1Path = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH);
-        WebTarget resource2Path = tckSuiteTarget.path(TCK_PARTICIPANT_RESOURCE_PATH).path(JOIN_WITH_EXISTNG_LRA_PATH);
-
-        URI lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS);
-
-        // invoke two JAX-RS resources in the context of the lra which should enlist them both:
-        Response response1 = resource1Path.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
-        checkStatusAndCloseResponse(Response.Status.OK, response1, resource1Path);
-        Response response2 = resource2Path.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
-        checkStatusAndCloseResponse(Response.Status.OK, response2, resource2Path);
-
-        if (close) {
-            lraClient.closeLRA(lra);
-
-            assertTrue("joinWithTwoResourcesWithClose: both resources should have completed",
-                    getActivityCount(LRA_CONTROLLER_PATH, "completedactivitycount") == completedCount1 + 1
-                            && getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPLETED_CNT_PATH) == completedCount2 + 1);
-        } else {
-            lraClient.cancelLRA(lra);
-
-            assertTrue("joinWithTwoResourcesWithCancel: both resources should have compensated",
-                    getActivityCount(LRA_CONTROLLER_PATH, "compensatedactivitycount") == compensatedCount1 +1
-                            && getActivityCount(TCK_PARTICIPANT_RESOURCE_PATH, COMPLETED_CNT_PATH) == compensatedCount2 + 1);
-        }
-    }
-
-    private void checkStatusAndCloseResponse(Response.Status expectedStatus, Response response, WebTarget resourcePath) {
+    private void checkStatusAndClose(Response.Status expectedStatus, Response response, WebTarget resourcePath) {
         try {
             assertEquals("Not expected status at call '" + resourcePath.getUri() + "'",
                     expectedStatus.getStatusCode(), response.getStatus());
@@ -607,7 +471,7 @@ public class TckTests {
         }
     }
 
-    private String checkStatusReadAndCloseResponse(Response.Status expectedStatus, Response response, WebTarget resourcePath) {
+    private String checkStatusReadAndClose(Response.Status expectedStatus, Response response, WebTarget resourcePath) {
         try {
             assertEquals("Response status on call to '" + resourcePath.getUri() + "' failed to match.",
                     expectedStatus.getStatusCode(), response.getStatus());
@@ -626,15 +490,11 @@ public class TckTests {
     }
 
     private int getActivityCount(String activityCountTargetPath) {
-        return getActivityCount(LRA_CONTROLLER_PATH, activityCountTargetPath);
-    }
-
-    private int getActivityCount(String basePath, String activityCountTargetPath) {
-        WebTarget resourcePath = tckSuiteTarget.path(basePath)
+        WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH)
                 .path(activityCountTargetPath);
 
         Response response = resourcePath.request().get();
-        String count = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);
+        String count = checkStatusReadAndClose(Response.Status.OK, response, resourcePath);
         return Integer.parseInt(count);
     }
 
@@ -657,7 +517,7 @@ public class TckTests {
                 .header(LRA.LRA_HTTP_HEADER, lra)
                 .put(Entity.text(""));
 
-        String lraStr = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);
+        String lraStr = checkStatusReadAndClose(Response.Status.OK, response, resourcePath);
         assertNotNull("expecting a LRA string returned from " + resourcePath.getUri(), lraStr);
         String[] lraArray = lraStr.split(",");
         URI[] uris = new URI[lraArray.length];
@@ -677,6 +537,12 @@ public class TckTests {
         assertEquals("multiLevelNestedActivity: step 2 (the test call went to " + resourcePath.getUri() + ")",
                 lraId, lraArray[0]);
 
+        // check that the coordinator knows about the two nested LRAs started by the multiLevelNestedActivity method
+        // NB even though they should have completed they are held in memory pending the enclosing LRA finishing
+        IntStream.rangeClosed(1, nestedCnt).forEach(i -> assertFalse(
+                "multiLevelNestedActivity: nested LRA should be active: step 2b (path called " + resourcePath + ")",
+                lraClient.isLRAFinished(lraArray[i])));
+
         // and the mandatory lra seen by the multiLevelNestedActivity method
         assertFalse("multiLevelNestedActivity: top level LRA should be active (path called " + resourcePath.getUri() + ")",
                 lraClient.isLRAFinished(lraArray[0]));