Repository: eclipse/microprofile-lra
Pull request #132 (2019-04-07 21:32:43)

issue122 context propagation tests
#122 

This PR adds the TCK tests for the new context propagation semantics introduced in issue #122 


Patch:
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 4dc3740..de67007 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
@@ -53,7 +53,7 @@ import java.time.temporal.ChronoUnit;
  * <p>
  * Newly created LRAs are uniquely identified and the id is referred to as the
  * LRA context. The context is passed around using a JAX-RS request/response header
- * called {@value #LRA_HTTP_HEADER}.
+ * called {@value #LRA_HTTP_CONTEXT_HEADER}.
  * The implementation (of the LRA specification) is expected to manage this context
  * and the application developer is expected to declaratively control the creation,
  * propagation and destruction of LRAs using the {@link LRA} annotation. When a JAX-RS bean
@@ -78,7 +78,7 @@ import java.time.temporal.ChronoUnit;
  * <p>
  * 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
+ * annotation with value {@value #LRA_HTTP_CONTEXT_HEADER}. This may be useful, for example, for
  * associating business work with an LRA.
  * </p>
  */
@@ -91,7 +91,7 @@ public @interface LRA {
      * via an HTTP header field with the following name. The value contains
      * the LRA id associated with the HTTP request/response
      */
-    String LRA_HTTP_HEADER = "Long-Running-Action";
+    String LRA_HTTP_CONTEXT_HEADER = "Long-Running-Action";
 
     /**
      * the name of the HTTP header field that contains a recovery URI corresponding
@@ -129,7 +129,7 @@ public @interface LRA {
      * <p>
      * When an LRA is present its identifer <b>MUST</b> be made available to
      * the business logic in the JAX-RS request and response header
-     * {@value #LRA_HTTP_HEADER}.
+     * {@value #LRA_HTTP_CONTEXT_HEADER}.
      *
      * @return whether a bean method is to be executed within a transaction context.
      */
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 932d030..f10acde 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
@@ -46,7 +46,7 @@ import java.lang.annotation.Target;
  * 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
+ * the `LRA_HTTP_CONTEXT_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>
  *
diff --git a/pom.xml b/pom.xml
index abcd1e9..d398dda 100644
--- a/pom.xml
+++ b/pom.xml
@@ -207,6 +207,9 @@
                                 <module name="EmptyBlock">
                                     <property name="option" value="text" />
                                 </module>
+                                <module name="WhitespaceAround">
+                                  <property name="tokens" value="LITERAL_ELSE"/>
+                                </module>
                                 <module name="NeedBraces" />
                                 <module name="EmptyStatement" />
                                 <module name="EqualsHashCode" />
diff --git a/spec/src/main/asciidoc/microprofile-lra-spec.adoc b/spec/src/main/asciidoc/microprofile-lra-spec.adoc
index f271b47..5dfe927 100644
--- a/spec/src/main/asciidoc/microprofile-lra-spec.adoc
+++ b/spec/src/main/asciidoc/microprofile-lra-spec.adoc
@@ -312,7 +312,7 @@ 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>>.
+the Java constant `LRA_HTTP_CONTEXT_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
@@ -465,7 +465,7 @@ the LRA to be finished. If it is closed or cancelled depends on the Response sta
 
 When an LRA is present its identifier MUST be made available to
 the business logic via request and response headers as described earlier
-(using a header name specified in the Java constant `LRA_HTTP_HEADER`).
+(using a header name specified in the Java constant `LRA_HTTP_CONTEXT_HEADER`).
 
 The following is a simple example of how to start an LRA and how to receive
 a notification when the LRA is later cancelled (`@Compensate` is invoked)
@@ -479,7 +479,7 @@ public class SimpleLRAParticipant
 {
     @Path("/cdi")
     @LRA(LRA.Type.REQUIRES_NEW)
-    public void doInTransaction(@HeaderParam(LRA_HTTP_HEADER) String lraId)
+    public void doInTransaction(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId)
     {
         /*
          * Perform business actions in the context of the LRA identified by the
@@ -493,7 +493,7 @@ public class SimpleLRAParticipant
     @PUT
     @Path("/complete")
     @Complete
-    public Response completeWork(@HeaderParam(LRA_HTTP_HEADER) String lraId,
+    public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
                                  String userData)
     {
         /*
@@ -509,7 +509,7 @@ public class SimpleLRAParticipant
     @PUT
     @Path("/compensate")
     @Compensate
-    public Response compensateWork(@HeaderParam(LRA_HTTP_HEADER) String lraId,
+    public Response compensateWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
                                    String userData)
     {
         /*
@@ -526,7 +526,7 @@ public class SimpleLRAParticipant
     @DELETE
     @Path("/forget")
     @Forget
-    public Response forgetWork(@HeaderParam(LRA_HTTP_HEADER) String lraId)
+    public Response forgetWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId)
     {
         // clean up any resources that were used in the context of lraId
     }
@@ -582,7 +582,7 @@ For example:
   @PUT
   @Path("/compensate")
   @Compensate
-  public Response compensateWork(@HeaderParam(LRA.LRA_HTTP_HEADER) String lraId)
+  public Response compensateWork(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) String lraId)
   {
     // compensate for whatever activity the business logic has associated with lraId
     return Response.ok(ParticipantStatus.Compensated.name()).build();
@@ -671,7 +671,7 @@ section for when this feature could be useful.
     @Produces(MediaType.APPLICATION_JSON)
     @LRA(LRA.Type.SUPPORTS)
     @NestedLRA
-    public Booking bookFlight(@HeaderParam(LRA_HTTP_HEADER) String lraId,
+    public Booking bookFlight(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
                               @QueryParam("flightNumber") String flightNumber) {
         return service.book(lraId, flightNumber);
     }
@@ -694,7 +694,7 @@ example, to indicate that an LRA should automatically cancel after 100 milliseco
   @Produces(MediaType.APPLICATION_JSON)
   @LRA(value = LRA.Type.REQUIRED, timeLimit = 100, timeUnit = ChronoUnit.MILLIS)
   public Response theClockIsTicking(
-      @HeaderParam(LRA.LRA_HTTP_HEADER) String lraId) {...}
+      @HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) String lraId) {...}
 ----
 
 Furthermore, the ability to compensate or complete may be transient capabilities of a
@@ -711,7 +711,7 @@ indicate that its' ability to compensate is limited to 100 milliseconds could be
     @PUT
     @Path("/compensate")
     @Compensate(timeLimit = 100, timeUnit = ChronoUnit.MILLIS)
-    public Response completeWork(@HeaderParam(LRA_HTTP_HEADER) String lraId,
+    public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
                                  String userData) { ... }
 ----
 
@@ -738,7 +738,7 @@ An example of this annotation is shown next:
     @PUT
     @Path("/leave")
     @Leave
-    public Response leaveWork(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response leaveWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
       // clean up since this participant is no longer associated with the LRA
     }
 ----
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..82e81c4 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
@@ -126,7 +126,7 @@ public class LRAClientOps {
         Invocation.Builder builder = resourcePath.request();
 
         if (lra != null) {
-            builder.header(LRA.LRA_HTTP_HEADER, lra);
+            builder.header(LRA.LRA_HTTP_CONTEXT_HEADER, lra);
         }
 
         return builder.put(Entity.text(""));
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/ContextTckResource.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/ContextTckResource.java
new file mode 100644
index 0000000..9cacbe3
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/ContextTckResource.java
@@ -0,0 +1,378 @@
+/*
+ *******************************************************************************
+ * 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.Compensate;
+import org.eclipse.microprofile.lra.annotation.Complete;
+import org.eclipse.microprofile.lra.annotation.Forget;
+import org.eclipse.microprofile.lra.annotation.ParticipantStatus;
+import org.eclipse.microprofile.lra.annotation.Status;
+import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
+import org.eclipse.microprofile.lra.annotation.ws.rs.Leave;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
+import static org.eclipse.microprofile.lra.tck.participant.api.NonParticipatingTckResource.SUPPORTS_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.NonParticipatingTckResource.TCK_NON_PARTICIPANT_RESOURCE_PATH;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+@ApplicationScoped
+@Path(ContextTckResource.TCK_CONTEXT_RESOURCE_PATH)
+public class ContextTckResource {
+    public static final String TCK_CONTEXT_RESOURCE_PATH = "context-tck-resource";
+
+    public static final String NEW_LRA_PATH = "/new-lra";
+    public static final String REQUIRED_LRA_PATH = "/required-lra";
+    // resource path for testing that context on outbound and inbound calls made from an
+    // method annotated with @LRA are spec compliant
+    public static final String CONTEXT_CHECK_LRA_PATH = "/context-check-lra";
+    public static final String LEAVE_PATH = "/leave";
+    // resource path for reading and writing the participant status
+    public static final String STATUS_PATH = "/status";
+    // resource path for reading stats relating to a participant in the context of a single LRA
+    public static final String METRIC_PATH = "/count";
+    // resource path for clearing state
+    public static final String RESET_PATH = "/reset";
+
+    // headers for tests to indicate how the participant should respond to callbacks
+    // from the LRA implementation (complete, compensate, forget and status)
+    public static final String LRA_TCK_FAULT_TYPE_HEADER = "Lra-Tck-Fault-Type";
+    public static final String LRA_TCK_FAULT_CODE_HEADER = "Lra-Tck-Fault-Status";
+
+    // a header for tests to indicate which LRA stats are being queried/reset
+    public static final String LRA_TCK_HTTP_CONTEXT_HEADER = "Lra-Tck-Context";
+
+    private static final String REQUIRES_NEW_LRA_PATH = "/requires-new-lra";
+
+    /**
+     * A class to hold all of the metrics gathered in the context of a single LRA.
+     * We need stats per LRA since a misbehaving test may leave an LRA in need of
+     * recovery which means that the compensate/complete call will continue to be
+     * called when subsequent tests run - ie it is not possible to fully tear down
+     * a failing test.
+     */
+    private static class LRAMetric {
+        String lraId;
+        Map<String, AtomicInteger> metrics = Stream.of(
+                new AbstractMap.SimpleEntry<>(Complete.class.getName(), new AtomicInteger(0)),
+                new AbstractMap.SimpleEntry<>(Compensate.class.getName(), new AtomicInteger(0)),
+                new AbstractMap.SimpleEntry<>(Status.class.getName(), new AtomicInteger(0)),
+                new AbstractMap.SimpleEntry<>(Forget.class.getName(), new AtomicInteger(0)))
+                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+        LRAMetric(String lraId) {
+            this.lraId = lraId;
+        }
+
+        void increment(String metric) {
+            if (metrics.containsKey(metric)) {
+                metrics.get(metric).incrementAndGet();
+            }
+        }
+
+        int get(String metric) {
+            if (metrics.containsKey(metric)) {
+                return metrics.get(metric).get();
+            }
+
+            return -1;
+        }
+
+        void clear() {
+            metrics.forEach((k, v) -> v.set(0));
+        }
+    }
+
+    // maintain metrics on a per LRA basis
+    private Map<String, LRAMetric> metrics = new HashMap<>();
+
+    private void incrementMetric(String name, String lraId) {
+        metrics.putIfAbsent(lraId, new LRAMetric(lraId));
+        metrics.get(lraId).increment(name);
+    }
+
+    /**
+     * An enum which controls the behaviour of participant when the
+     * LRA spec implementation invokes the compensation, completion,
+     * forget and status callbacks. It is used for testing the
+     * implementation is spec compliant.
+     */
+    public enum EndPhase {
+        ACCEPTED, // a participant reports that the complete/compensate is in progress
+        FAILED, // a particant reports that is is unable to complete/compensate
+        SUCCESS // clear the any injected behaviour
+    }
+
+    private EndPhase endPhase = EndPhase.SUCCESS;
+    // control which status to return from participant callbacks
+    private Response.Status endPhaseStatus = Response.Status.OK;
+    private ParticipantStatus status = ParticipantStatus.Active;
+
+    // update the injected behaviour
+    private void setEndPhase(String faultType, int faultCode) {
+        if (faultType == null) {
+            endPhase = EndPhase.SUCCESS;
+            endPhaseStatus = Response.Status.OK;
+        } else {
+            endPhase = EndPhase.valueOf(faultType);
+            endPhaseStatus = Response.Status.fromStatusCode(faultCode);
+        }
+    }
+
+    // reset any state in preparation for the next test
+    @PUT
+    @Path(RESET_PATH)
+    public Response reset(@HeaderParam(LRA_TCK_HTTP_CONTEXT_HEADER) String lraId) {
+        status = ParticipantStatus.Active;
+        endPhase = EndPhase.SUCCESS;
+        endPhaseStatus = Response.Status.OK;
+
+        metrics.clear();
+
+        return Response.ok().build();
+    }
+
+    // start a new LRA which remains active after the method returns
+    @LRA(value = LRA.Type.REQUIRES_NEW, end = false)
+    @PUT
+    @Path(NEW_LRA_PATH)
+    public Response newLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
+                           @HeaderParam(LRA_TCK_FAULT_TYPE_HEADER) String tckFaultType,
+                           @HeaderParam(LRA_TCK_FAULT_CODE_HEADER) int tckFaultCode) {
+        // check for a requests to inject particular behaviour
+        setEndPhase(tckFaultType, tckFaultCode);
+
+        return Response.ok().entity(lraId).build();
+    }
+
+    // end an existing LRA or start and end a new one
+    @LRA(value = LRA.Type.REQUIRED)
+    @PUT
+    @Path(REQUIRED_LRA_PATH)
+    public Response requiredLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
+                                @HeaderParam(LRA_TCK_FAULT_TYPE_HEADER) String tckFaultType,
+                                @HeaderParam(LRA_TCK_FAULT_CODE_HEADER) int tckFaultCode) {
+        setEndPhase(tckFaultType, tckFaultCode);
+
+        return Response.ok().entity(lraId).build();
+    }
+
+    @LRA(value = LRA.Type.REQUIRES_NEW)
+    @PUT
+    @Path(REQUIRES_NEW_LRA_PATH)
+    public Response requiresNew(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
+        return Response.ok().entity(lraId).build();
+    }
+
+    // test that outgoing calls do not affect the calling context
+    @LRA(value = LRA.Type.REQUIRED)
+    @PUT
+    @Path(CONTEXT_CHECK_LRA_PATH)
+    public Response contextCheck(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
+        String remote;
+        String active = getActiveLRA();
+        assertEquals("contextCheck1: incoming and active LRAs are different", lraId, active);
+
+        // invoke a remote service which runs in its own context. Do not set the context header
+        remote = restPutInvocation(null, REQUIRES_NEW_LRA_PATH, "");
+        assertNotEquals("contextCheck2: the remote service should not have ran with the active context", remote, active);
+
+
+        assertEquals("contextCheck2: after calling a remote service the active LRAs are different", active, getActiveLRA());
+
+        // invoke a remote service which runs in its own context. Do set the context header
+        remote = restPutInvocation(active, REQUIRES_NEW_LRA_PATH, "");
+        assertNotEquals("contextCheck3: the remote service should not have ran with the active context", remote, active);
+        assertEquals("contextCheck3: after calling a remote service the active LRAs are different", active, getActiveLRA());
+
+        // invoke a remote service which runs in the callers context, ie do set the context header
+        remote = restPutInvocation(active, TCK_NON_PARTICIPANT_RESOURCE_PATH, SUPPORTS_PATH, "");
+        assertEquals("contextCheck4: the remote service should have ran with the active context", remote, active);
+        assertEquals("contextCheck4: after calling a remote service the active LRAs is different", active, getActiveLRA());
+
+        return Response.ok().entity(lraId).build();
+    }
+
+    /**
+     * Query the current value of a metric in the context of an LRA
+     * @param lraId the LRA that owns the metric
+     * @param metric the name of the metric
+     * @return the current value of the metric
+     */
+    @GET
+    @Path(METRIC_PATH + "/{metric}")
+    public Response count(@HeaderParam(LRA_TCK_HTTP_CONTEXT_HEADER) String lraId,
+                          @PathParam("metric") String metric) {
+        if (metrics.containsKey(lraId)) {
+            return Response.ok(metrics.get(lraId).get(metric)).build();
+        } else {
+            return Response.ok(-1).build();
+        }
+    }
+
+    @Leave
+    @PUT
+    @Path(LEAVE_PATH)
+    public Response leave(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
+        return Response.ok().entity(lraId).build();
+    }
+
+    @PUT
+    @Path("/compensate")
+    @Compensate
+    public Response compensateWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId)
+            throws NotFoundException {
+        incrementMetric(Compensate.class.getName(), lraId);
+
+        return getEndPhaseResponse(false);
+    }
+
+    @PUT
+    @Path("/complete")
+    @Complete
+    public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId)
+            throws NotFoundException {
+        incrementMetric(Complete.class.getName(), lraId);
+
+        return getEndPhaseResponse(true);
+    }
+
+    @Status
+    @GET
+    @Path(STATUS_PATH)
+    public Response status(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
+        incrementMetric(Status.class.getName(), lraId);
+
+        return Response.status(endPhaseStatus).entity(status.name()).build();
+    }
+
+    @Forget
+    @DELETE
+    @Path("/forget")
+    public Response forget(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
+        incrementMetric(Forget.class.getName(), lraId);
+
+        return Response.status(endPhaseStatus).entity(status.name()).build();
+    }
+
+    // clear any injected participant behaviour
+    @PUT
+    @Path(STATUS_PATH)
+    public Response clearStatus(@HeaderParam(LRA_TCK_HTTP_CONTEXT_HEADER) String lraId,
+                           @HeaderParam(LRA_TCK_FAULT_TYPE_HEADER) String tckFaultType) {
+        switch (status) {
+            case Compensating:
+                status = ParticipantStatus.Compensated;
+                break;
+            case Completing:
+                status = ParticipantStatus.Completed;
+                break;
+            default:
+                break; // do nothing
+        }
+
+        endPhase = EndPhase.SUCCESS;
+        endPhaseStatus = Response.Status.OK;
+
+        return Response.ok().entity(status.name()).build();
+    }
+
+    // modify participant responses based on injected behavour specified by the test
+    private Response getEndPhaseResponse(boolean completing) {
+        switch (endPhase) {
+            case ACCEPTED:
+                status = completing ? ParticipantStatus.Completing : ParticipantStatus.Compensating;
+                return Response.status(Response.Status.ACCEPTED).entity(status.name()).build();
+            case FAILED:
+                status = completing ? ParticipantStatus.FailedToComplete : ParticipantStatus.FailedToCompensate;
+                return Response.status(endPhaseStatus).entity(status.name()).build();
+            case SUCCESS: /* FALLTHRU */
+            default:
+                status = completing ? ParticipantStatus.Completed : ParticipantStatus.Compensated;
+                return Response.status(Response.Status.OK).entity(status.name()).build();
+        }
+    }
+
+    /*
+     * helper methods for testing how outgoing/incoming JAX-RS calls affect the notion of the current context
+     */
+
+    @Context
+    private UriInfo context;
+
+    private String getActiveLRA() {
+        return restPutInvocation(null, TCK_NON_PARTICIPANT_RESOURCE_PATH, SUPPORTS_PATH, "");
+    }
+
+    private String restPutInvocation(String lraURI, String path, String bodyText) {
+        return restPutInvocation(lraURI, TCK_CONTEXT_RESOURCE_PATH, path, bodyText);
+    }
+
+    private String restPutInvocation(String lraURI, String resource, String path, String bodyText) {
+        String id = null;
+        Invocation.Builder builder = ClientBuilder.newClient()
+                .target(context.getBaseUri())
+                .path(resource)
+                .path(path)
+                .request();
+        if (lraURI != null) {
+            builder.header(LRA_HTTP_CONTEXT_HEADER, lraURI);
+        }
+
+        Response response = builder.put(Entity.text(bodyText));
+
+        if (response.hasEntity()) {
+            id = response.readEntity(String.class);
+        }
+
+        try {
+            if (response.getStatus() != Response.Status.OK.getStatusCode()) {
+                throw new WebApplicationException("Error on REST PUT for LRA '" + lraURI
+                        + "' at path '" + path + "' and body '" + bodyText + "'", response);
+            }
+        } finally {
+            response.close();
+        }
+
+        return id;
+    }
+}
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
index 230279d..37a023b 100644
--- 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
@@ -27,7 +27,7 @@ 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;
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
 
 @ApplicationScoped
 @Path(LRATypeTckResource.TCK_LRA_TYPE_RESOURCE_PATH)
@@ -52,37 +52,37 @@ public class LRATypeTckResource {
     @GET
     @Path(REQUIRED_PATH)
     @LRA(value = LRA.Type.REQUIRED)
-    public Response requiredLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response requiredLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response requiresNewLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response mandatoryLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response supportsLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response notSupportedLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response neverLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return Response.ok(lraId).build();
     }
 
@@ -90,37 +90,37 @@ public class LRATypeTckResource {
     @GET
     @Path(REQUIRED_WITH_END_FALSE_PATH)
     @LRA(value = LRA.Type.REQUIRED, end = false)
-    public Response requiredEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response requiredEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response requiresNewEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response mandatoryEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response supportsEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response notSupportedEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_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) {
+    public Response neverEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_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..90284ac 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
@@ -19,7 +19,7 @@
  *******************************************************************************/
 package org.eclipse.microprofile.lra.tck.participant.api;
 
-import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_HEADER;
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
 
 import java.net.MalformedURLException;
 import java.net.URI;
@@ -174,7 +174,7 @@ public class LraCancelOnController {
     @PUT
     @Path("/complete")
     @Complete
-    public Response completeWork(@HeaderParam(LRA_HTTP_HEADER) String lraId)
+    public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId)
         throws NotFoundException {
         if(lraId == null) {
             throw new NullPointerException("lraId can't be null as it should be invoked with the context");
@@ -189,7 +189,7 @@ public class LraCancelOnController {
     @PUT
     @Path("/compensate")
     @Compensate
-    public Response compensateWork(@HeaderParam(LRA_HTTP_HEADER) String lraId, String userData)
+    public Response compensateWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, String userData)
         throws NotFoundException {
         if(lraId == null) {
             throw new NullPointerException("lraId can't be null as it should be invoked with the context");
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java
index 2e9e93f..0f3d56b 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/LraController.java
@@ -66,7 +66,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.stream.IntStream;
 
-import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_HEADER;
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
 import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER;
 
 @ApplicationScoped
@@ -104,7 +104,7 @@ public class LraController {
     @Produces(MediaType.APPLICATION_JSON)
     @Status
     @LRA(value = LRA.Type.NOT_SUPPORTED)
-    public Response status(@HeaderParam(LRA_HTTP_HEADER) String lraId) throws NotFoundException {
+    public Response status(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) throws NotFoundException {
         Activity activity = activityStore.getActivityAndAssertExistence(lraId, context);
 
         if (activity.getStatus() == null) {
@@ -126,7 +126,7 @@ public class LraController {
     @Path("/leave")
     @Produces(MediaType.APPLICATION_JSON)
     @Leave
-    public Response leaveWork(@HeaderParam(LRA_HTTP_HEADER) String lraId)
+    public Response leaveWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId)
         throws NotFoundException {
 
         if (lraId != null) {
@@ -144,7 +144,7 @@ public class LraController {
     @Path("/complete")
     @Produces(MediaType.APPLICATION_JSON)
     @Complete
-    public Response completeWork(@HeaderParam(LRA_HTTP_HEADER) String lraId, String userData)
+    public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, String userData)
         throws NotFoundException {
         COMPLETED_COUNT.incrementAndGet();
 
@@ -173,7 +173,7 @@ public class LraController {
     @Path("/compensate")
     @Produces(MediaType.APPLICATION_JSON)
     @Compensate(timeLimit = 0, timeUnit = ChronoUnit.SECONDS)
-    public Response compensateWork(@HeaderParam(LRA_HTTP_HEADER) String lraId, String userData)
+    public Response compensateWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, String userData)
         throws NotFoundException {
 
         assertHeaderPresent(lraId); // the TCK expects the coordinator to invoke @Compensate methods
@@ -203,7 +203,7 @@ public class LraController {
     @Path("/forget")
     @Produces(MediaType.APPLICATION_JSON)
     @Forget
-    public Response forgetWork(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response forgetWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         COMPLETED_COUNT.incrementAndGet();
 
         assertHeaderPresent(lraId); // the TCK expects the coordinator to invoke @Forget methods
@@ -228,7 +228,7 @@ public class LraController {
     @LRA(value = LRA.Type.REQUIRED, end = false)
     public Response acceptWork(
             @HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId,
-            @HeaderParam(LRA_HTTP_HEADER) String lraId) {
+            @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
 
         assertHeaderPresent(lraId);
 
@@ -241,7 +241,7 @@ public class LraController {
     @PUT
     @Path("/supports")
     @LRA(value = LRA.Type.SUPPORTS, end = false)
-    public Response supportsLRACall(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response supportsLRACall(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         assertHeaderPresent(lraId);
 
         storeActivity(lraId, null);
@@ -252,7 +252,7 @@ public class LraController {
     @PUT
     @Path("/startViaApi")
     @LRA(LRA.Type.NOT_SUPPORTED)
-    public Response subActivity(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response subActivity(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         assertNotHeaderPresent(lraId);
 
         Client client = null;
@@ -288,7 +288,7 @@ public class LraController {
     @Path(TRANSACTIONAL_WORK_PATH)
     @LRA(value = LRA.Type.REQUIRED, end = false)
     public Response activityWithLRA(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId,
-                                    @HeaderParam(LRA_HTTP_HEADER) String lraId) {
+                                    @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         assertHeaderPresent(lraId);
 
         Activity activity = storeActivity(lraId, recoveryId);
@@ -307,7 +307,7 @@ public class LraController {
                 .path(LRA_CONTROLLER_PATH)
                 .path(path)
                 .request()
-                .header(LRA_HTTP_HEADER, lraURI)
+                .header(LRA_HTTP_CONTEXT_HEADER, lraURI)
                 .put(Entity.text(bodyText));
 
         if (response.hasEntity()) {
@@ -331,7 +331,7 @@ public class LraController {
     @Produces(MediaType.TEXT_PLAIN)
     @LRA(value = LRA.Type.MANDATORY, end = false)
     public Response activityWithMandatoryLRA(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId,
-                                             @HeaderParam(LRA_HTTP_HEADER) String lraId) {
+                                             @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return activityWithLRA(recoveryId, lraId);
     }
 
@@ -340,7 +340,7 @@ public class LraController {
     @LRA(value = LRA.Type.MANDATORY, end = true)
     @NestedLRA
     public Response nestedActivity(@HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId,
-                                   @HeaderParam(LRA_HTTP_HEADER) String nestedLRAId) {
+                                   @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String nestedLRAId) {
         assertHeaderPresent(nestedLRAId);
 
         storeActivity(nestedLRAId, recoveryId);
@@ -353,7 +353,7 @@ public class LraController {
     @LRA(value = LRA.Type.MANDATORY, end = false)
     public Response multiLevelNestedActivity(
             @HeaderParam(LRA_HTTP_RECOVERY_HEADER) String recoveryId,
-            @HeaderParam(LRA_HTTP_HEADER) String nestedLRAId,
+            @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String nestedLRAId,
             @QueryParam("nestedCnt") @DefaultValue("1") Integer nestedCnt) {
         assertHeaderPresent(nestedLRAId);
 
@@ -414,7 +414,7 @@ public class LraController {
     @Path("/timeLimit")
     @Produces(MediaType.APPLICATION_JSON)
     @LRA(value = LRA.Type.REQUIRED, timeLimit = 100, timeUnit = ChronoUnit.MILLIS)
-    public Response timeLimit(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response timeLimit(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         assertHeaderPresent(lraId);
 
         activityStore.add(new Activity(lraId));
@@ -515,14 +515,14 @@ public class LraController {
     private void assertHeaderPresent(String lraId) {
         if (lraId == null) {
             throw new InvalidLRAIdException(null,
-                    String.format("%s: missing '%s' header", context.getPath(), LRA_HTTP_HEADER));
+                    String.format("%s: missing '%s' header", context.getPath(), LRA_HTTP_CONTEXT_HEADER));
         }
     }
 
     private void assertNotHeaderPresent(String lraId) {
         if (lraId != null) {
             throw new InvalidLRAIdException(null,
-                    String.format("%s: unexpected '%s' header", context.getPath(), LRA_HTTP_HEADER));
+                    String.format("%s: unexpected '%s' header", context.getPath(), LRA_HTTP_CONTEXT_HEADER));
         }
     }
 }
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NoLRAController.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NoLRAController.java
index b690f41..07420f4 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NoLRAController.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NoLRAController.java
@@ -32,7 +32,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
-import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_HEADER;
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
 import static org.eclipse.microprofile.lra.tck.participant.api.LraController.LRA_CONTROLLER_PATH;
 
 @ApplicationScoped
@@ -46,7 +46,7 @@ public class NoLRAController {
 
     @PUT
     @Path(NON_TRANSACTIONAL_WORK_PATH)
-    public Response work2(@HeaderParam(LRA_HTTP_HEADER) String lraId) throws NotFoundException {
+    public Response work2(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) throws NotFoundException {
 
         if (lraId != null) {
             return Response.status(Response.Status.PRECONDITION_FAILED).entity("Unexpected LRA context").build();
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NonParticipatingTckResource.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NonParticipatingTckResource.java
index b0f0b49..4b9f03a 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NonParticipatingTckResource.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/participant/api/NonParticipatingTckResource.java
@@ -39,7 +39,7 @@ import javax.ws.rs.core.UriInfo;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Logger;
 
-import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_HEADER;
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
 
 @ApplicationScoped
 @Path(NonParticipatingTckResource.TCK_NON_PARTICIPANT_RESOURCE_PATH)
@@ -54,6 +54,8 @@ public class NonParticipatingTckResource {
     public static final String START_BUT_DONT_END_NESTED_PATH = "/start-nested-and-dont-end";
     public static final String NEVER_PATH = "/never";
     public static final String END_PATH = "/end";
+    public static final String SUPPORTS_PATH = "/supports";
+
 
     public static final String OK_TEXT = "OK";
 
@@ -75,7 +77,14 @@ public class NonParticipatingTckResource {
     @PUT
     @Path(NonParticipatingTckResource.NEVER_PATH)
     @LRA(value = LRA.Type.NEVER)
-    public Response neverRunWithLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response neverRunWithLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
+        return Response.ok(lraId).build();
+    }
+
+    @PUT
+    @Path(SUPPORTS_PATH)
+    @LRA(value = LRA.Type.SUPPORTS)
+    public Response supports(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return Response.ok(lraId).build();
     }
 
@@ -83,7 +92,7 @@ public class NonParticipatingTckResource {
     @Path(NonParticipatingTckResource.START_AND_END_PATH)
     @LRA(value = LRA.Type.REQUIRES_NEW,
             cancelOnFamily = Response.Status.Family.SERVER_ERROR) // default is to end the LRA
-    public Response startAndEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId,
+    public Response startAndEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
                                    @DefaultValue("200") @QueryParam(STATUS_CODE_QUERY_NAME) int coerceStatus) {
         return Response.status(coerceStatus).entity(checkLRANotNull(lraId)).build();
     }
@@ -92,7 +101,7 @@ public class NonParticipatingTckResource {
     @Path(NonParticipatingTckResource.START_BUT_DONT_END_PATH)
     @LRA(value = LRA.Type.REQUIRES_NEW, end = false,
             cancelOnFamily = Response.Status.Family.SERVER_ERROR)
-    public Response startDontEndLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId,
+    public Response startDontEndLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
                                     @DefaultValue("200") @QueryParam(STATUS_CODE_QUERY_NAME) int coerceStatus) {
         return Response.status(coerceStatus).entity(checkLRANotNull(lraId)).build();
     }
@@ -101,7 +110,7 @@ public class NonParticipatingTckResource {
     @Path(NonParticipatingTckResource.END_PATH)
     @LRA(value = LRA.Type.MANDATORY,
             cancelOnFamily = Response.Status.Family.SERVER_ERROR) // default is to end the LRA
-    public Response endLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId,
+    public Response endLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId,
                            @DefaultValue("200") @QueryParam(STATUS_CODE_QUERY_NAME) int coerceStatus) {
         return Response.status(coerceStatus).entity(checkLRANotNull(lraId)).build();
     }
@@ -111,7 +120,7 @@ public class NonParticipatingTckResource {
     @LRA(value = LRA.Type.MANDATORY,
             cancelOnFamily = Response.Status.Family.SERVER_ERROR) // default is to end the LRA
     @NestedLRA
-    public Response startAndEndNestedLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response startAndEndNestedLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return Response.ok(lraId).build();
     }
 
@@ -120,7 +129,7 @@ public class NonParticipatingTckResource {
     @LRA(value = LRA.Type.MANDATORY, end = false,
             cancelOnFamily = Response.Status.Family.SERVER_ERROR)
     @NestedLRA
-    public Response startAndDontEndNestedLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response startAndDontEndNestedLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return Response.ok(lraId).build();
     }
 
@@ -128,7 +137,7 @@ public class NonParticipatingTckResource {
     @Path(NonParticipatingTckResource.START_LRA_VIA_REMOTE_INVOCATIOM)
     @LRA(value = LRA.Type.SUPPORTS, end = false,
             cancelOnFamily = Response.Status.Family.SERVER_ERROR)
-    public Response notSupportedButCallServiceWhichStartsButDoesntEndAnLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response notSupportedButCallServiceWhichStartsButDoesntEndAnLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return Response.ok(invokeRestEndpoint(lraId, TCK_NON_PARTICIPANT_RESOURCE_PATH, START_BUT_DONT_END_PATH,
                 200)).build();
     }
@@ -147,7 +156,7 @@ public class NonParticipatingTckResource {
     private String checkLRANotNull(String lraId) {
         if (lraId == null) {
             throw new InvalidLRAIdException(null,
-                    String.format("%s: missing '%s' header", context.getPath(), LRA_HTTP_HEADER));
+                    String.format("%s: missing '%s' header", context.getPath(), LRA_HTTP_CONTEXT_HEADER));
         }
 
         return lraId;
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..d511f7f 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
@@ -36,7 +36,7 @@ import javax.ws.rs.core.Response;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Logger;
 
-import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_HEADER;
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
 
 @ApplicationScoped
 @Path(ParticipatingTckResource.TCK_PARTICIPANT_RESOURCE_PATH)
@@ -57,7 +57,7 @@ public class ParticipatingTckResource {
     @PUT
     @Path("/compensate")
     @Compensate
-    public Response compensateWork(@HeaderParam(LRA_HTTP_HEADER) String lraId, String userData)
+    public Response compensateWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, String userData)
             throws NotFoundException {
         if(lraId == null) {
             throw new NullPointerException("lraId can't be null as it should be invoked with the context");
@@ -73,7 +73,7 @@ public class ParticipatingTckResource {
     @PUT
     @Path("/complete")
     @Complete
-    public Response completeWork(@HeaderParam(LRA_HTTP_HEADER) String lraId, String userData)
+    public Response completeWork(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId, String userData)
             throws NotFoundException {
         if(lraId == null) {
             throw new NullPointerException("lraId can't be null as it should be invoked with the context");
@@ -115,21 +115,21 @@ public class ParticipatingTckResource {
     @PUT
     @Path(ParticipatingTckResource.JOIN_WITH_EXISTNG_LRA_PATH)
     @LRA(value = LRA.Type.MANDATORY, end = false)
-    public Response joinWithExistingLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response joinWithExistingLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         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) {
+    public Response joinWithExistingLRA2(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return Response.ok().build();
     }
 
     @PUT
     @Path(ParticipatingTckResource.JOIN_WITH_NEW_LRA_PATH)
     @LRA(value = LRA.Type.REQUIRES_NEW, end = false)
-    public Response joinWithNewLRA(@HeaderParam(LRA_HTTP_HEADER) String lraId) {
+    public Response joinWithNewLRA(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
         return Response.ok().build();
     }
 }


Test patch:
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckContextTests.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckContextTests.java
new file mode 100644
index 0000000..7c07aad
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckContextTests.java
@@ -0,0 +1,202 @@
+/*
+ *******************************************************************************
+ * 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.Complete;
+import org.eclipse.microprofile.lra.annotation.Forget;
+import org.eclipse.microprofile.lra.annotation.ParticipantStatus;
+import org.eclipse.microprofile.lra.annotation.Status;
+import org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
+import static org.eclipse.microprofile.lra.tck.TckContextTests.HttpMethod.GET;
+import static org.eclipse.microprofile.lra.tck.TckContextTests.HttpMethod.PUT;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.CONTEXT_CHECK_LRA_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.LEAVE_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.LRA_TCK_FAULT_CODE_HEADER;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.LRA_TCK_FAULT_TYPE_HEADER;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.LRA_TCK_HTTP_CONTEXT_HEADER;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.METRIC_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.NEW_LRA_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.REQUIRED_LRA_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.RESET_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.STATUS_PATH;
+import static org.eclipse.microprofile.lra.tck.participant.api.ContextTckResource.TCK_CONTEXT_RESOURCE_PATH;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * test that Compensate, Complete, Status, Forget and Leave annotations work without an LRA annotation
+ * test that resource methods that make outgoing requests do not modify the current context when they return
+ */
+@RunWith(Arquillian.class)
+public class TckContextTests extends TckTestBase {
+
+    enum HttpMethod {GET, PUT, POST}
+
+    @Deployment(name = "TckContextTests")
+    public static WebArchive deploy() {
+        return TckTestBase.deploy(TckContextTests.class.getSimpleName().toLowerCase());
+    }
+
+    @Before
+    public void before() {
+        super.before();
+        invoke(RESET_PATH, HttpMethod.PUT, null, 200, null, 200);
+    }
+
+    @Test
+    public void testBasicContextPropagation() {
+        String lra = invoke(NEW_LRA_PATH, PUT, null, 200, ContextTckResource.EndPhase.SUCCESS, 200);
+        invoke(REQUIRED_LRA_PATH, PUT, lra, 200, ContextTckResource.EndPhase.SUCCESS, 200);
+
+        // verify that the resource was asked to complete
+        String completions = invoke(METRIC_PATH + "/" + Complete.class.getName(), GET, lra);
+
+        assertEquals(testName.getMethodName() + ": Resource was not asked to complete",
+                Integer.toString(1), completions);
+    }
+
+    @Test
+    public void testStatus() {
+        // call a resource that begins and ends an LRA and coerces the resource to return ACCEPTED when asked to complete
+        String lra = invoke(REQUIRED_LRA_PATH, PUT, null, 200, ContextTckResource.EndPhase.ACCEPTED, 202);
+
+        // verfiy that the resource was asked to complete and is in the state Completing
+        String status = invoke(STATUS_PATH, HttpMethod.GET, lra, 202, ContextTckResource.EndPhase.SUCCESS, 200);
+        assertEquals(testName.getMethodName() + ": participant is not completing", ParticipantStatus.Completing.name(), status);
+
+        // clear the EndPhase override data so that the next status request returns completed or compensated
+        invoke(STATUS_PATH, PUT, lra, 200, ContextTckResource.EndPhase.SUCCESS, 200);
+
+        // trigger a replay of the end phase
+        replayEndPhase(TCK_CONTEXT_RESOURCE_PATH);
+
+        // and verify that the resoure was asked to complete
+        status = invoke(STATUS_PATH, HttpMethod.GET, lra, 200, ContextTckResource.EndPhase.SUCCESS, 200);
+        assertEquals(testName.getMethodName() + ": participant is not completed", ParticipantStatus.Completed.name(), status);
+    }
+
+    @Test
+    public void testLeave() {
+        // call a resource that begins but does not end an LRA
+        String lra = invoke(NEW_LRA_PATH, PUT, null, 200, ContextTckResource.EndPhase.SUCCESS, 200);
+        // verfiy that the resource is active
+        String status = invoke(STATUS_PATH, HttpMethod.GET, lra, 200, ContextTckResource.EndPhase.SUCCESS, 200);
+
+        assertEquals(testName.getMethodName() + ": participant is not active", ParticipantStatus.Active.name(), status);
+
+        // ask the resource to leave the active LRA
+        invoke(LEAVE_PATH, PUT, lra);
+
+        // end the LRA via a different resource since using the same one will re-enlist it
+        lraClient.closeLRA(lra);
+
+        // verify that the resource was not asked to complete
+        String completions = invoke(METRIC_PATH + "/" + Complete.class.getName(), GET, lra);
+
+
+        assertEquals(testName.getMethodName() + ": Resource left but was still asked to complete",
+                "0", completions);
+    }
+
+    @Test
+    public void testForget() {
+        String count;
+        // call a resource that begins and ends an LRA and coerces the resource to return FAILED when asked to complete
+        String lra = invoke(REQUIRED_LRA_PATH, PUT, null, 200, ContextTckResource.EndPhase.FAILED, 500);
+
+        // trigger a replay attempt
+        replayEndPhase(TCK_CONTEXT_RESOURCE_PATH);
+
+        // the implementation should have called status which will have returned 500
+        count = invoke(METRIC_PATH + "/" + Status.class.getName(), GET, lra);
+        assertEquals(testName.getMethodName() + " resource status should have been called", "1", count);
+
+        // the implementation should not call forget until it knows the particpant status
+        count = invoke(METRIC_PATH + "/" + Forget.class.getName(), GET, lra);
+        assertEquals(testName.getMethodName() + " resource forget should not have been called", "0", count);
+
+        // clear the fault
+        invoke(STATUS_PATH, PUT, lra, 200, ContextTckResource.EndPhase.FAILED, 200);
+
+        // trigger a replay of the end phase
+        replayEndPhase(TCK_CONTEXT_RESOURCE_PATH);
+
+        // the implementation should have called status again which will have returned 200
+        count = invoke(METRIC_PATH + "/" + Status.class.getName(), GET, lra);
+        assertEquals(testName.getMethodName() + " resource status should have been called again", "2", count);
+        // the implementation should call forget since it knows the particpant status
+        count = invoke(METRIC_PATH + "/" + Forget.class.getName(), GET, lra);
+        assertEquals(testName.getMethodName() + " resource forget should have been called", "1", count);
+    }
+
+    // invoke a method in an LRA context which performs various outgoing calls checking that the notion of active context
+    // conforms with what is written in the specification
+    @Test
+    public void testContextAfterRemoteCalls() {
+        invoke(CONTEXT_CHECK_LRA_PATH, PUT, null);
+    }
+
+    private String invoke(String where, HttpMethod method, String lraContext) {
+        return invoke(where, method, lraContext, 200, ContextTckResource.EndPhase.SUCCESS, 200);
+    }
+
+    private String invoke(String where, HttpMethod method, String lraContext, int expectStatus,
+                          ContextTckResource.EndPhase finishWith, int finishStatus) {
+        WebTarget resourcePath = tckSuiteTarget.path(TCK_CONTEXT_RESOURCE_PATH).path(where);
+        Invocation.Builder builder = resourcePath.request()
+                .header(LRA_TCK_FAULT_TYPE_HEADER, finishWith)
+                .header(LRA_TCK_FAULT_CODE_HEADER, finishStatus);
+        Response response;
+
+        if (where.startsWith(METRIC_PATH) || (where.startsWith(STATUS_PATH) && method == PUT)) {
+            builder.header(LRA_TCK_HTTP_CONTEXT_HEADER, lraContext);
+        } else {
+            builder.header(LRA_HTTP_CONTEXT_HEADER, lraContext);
+        }
+
+        switch (method) {
+            case GET:
+                response =  builder.get();
+                break;
+            case PUT:
+                response =  builder.put(Entity.text(""));
+                break;
+            case POST:
+                response =  builder.post(Entity.text(""));
+                break;
+            default:
+                throw new IllegalArgumentException("HTTP method not supported: " + method);
+        }
+
+        return checkStatusReadAndCloseResponse(Response.Status.fromStatusCode(expectStatus), response, resourcePath);
+    }
+}
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
index 03b5f8f..87f4253 100644
--- a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckLRATypeTests.java
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckLRATypeTests.java
@@ -287,7 +287,7 @@ public class TckLRATypeTests {
         URI lra = startLRA ? lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS) : null;
 
         if (lra != null) {
-            target = target.header(LRA.LRA_HTTP_HEADER, lra);
+            target = target.header(LRA.LRA_HTTP_CONTEXT_HEADER, lra);
         }
 
         Response response = target.get();
diff --git a/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTestBase.java b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTestBase.java
new file mode 100644
index 0000000..6dfd721
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/lra/tck/TckTestBase.java
@@ -0,0 +1,156 @@
+/*
+ *******************************************************************************
+ * 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.tck.participant.api.Util;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+
+import javax.inject.Inject;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+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.util.logging.Logger;
+
+import static org.junit.Assert.assertEquals;
+
+public class TckTestBase {
+    private static final Logger LOGGER = Logger.getLogger(TckTestBase.class.getName());
+
+    @Rule public TestName testName = new TestName();
+
+    @Inject
+    private LraTckConfigBean config;
+
+    LRAClientOps lraClient;
+
+    private static URL recoveryCoordinatorBaseUrl;
+    private static Client tckSuiteClient;
+    private static Client recoveryCoordinatorClient;
+
+    WebTarget tckSuiteTarget;
+    private WebTarget recoveryTarget;
+
+    static WebArchive deploy(String archiveName) {
+        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();
+        }
+        if(recoveryCoordinatorClient != null) {
+            recoveryCoordinatorClient.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);
+        }
+        recoveryTarget = recoveryCoordinatorClient.target(URI.create(recoveryCoordinatorBaseUrl.toExternalForm()));
+    }
+
+    /**
+     * Checking if coordinator is running, set ups the client to contact the recovery manager and the TCK suite itself.
+     */
+    private void setUpTestCase() {
+        if(recoveryCoordinatorBaseUrl != null) {
+            // we've already set up the recovery urls and REST clients for the tests
+            return;
+        }
+
+        try {
+            // see https://github.com/eclipse/microprofile-lra/issues/116
+            recoveryCoordinatorBaseUrl = new URL(String.format("http://%s:%d/%s",
+                    config.recoveryHostName(), config.recoveryPort(), config.recoveryPath()));
+
+            tckSuiteClient = ClientBuilder.newClient();
+            recoveryCoordinatorClient = ClientBuilder.newClient();
+        } catch (MalformedURLException e) {
+            throw new RuntimeException("Cannot properly setup the TCK tests (coordinator endpoint, testsuite endpoints...)", e);
+        }
+    }
+
+    private void checkStatusAndCloseResponse(Response.Status expectedStatus, Response response, WebTarget resourcePath) {
+        try {
+            assertEquals("Not expected status at call '" + resourcePath.getUri() + "'",
+                    expectedStatus.getStatusCode(), response.getStatus());
+        } finally {
+            response.close();
+        }
+    }
+
+    String checkStatusReadAndCloseResponse(Response.Status expectedStatus, Response response, WebTarget resourcePath) {
+        try {
+            assertEquals("Response status on call to '" + resourcePath.getUri() + "' failed to match.",
+                    expectedStatus.getStatusCode(), response.getStatus());
+            return response.readEntity(String.class);
+        } finally {
+            response.close();
+        }
+    }
+
+    /**
+     * The started LRA will be named based on the class name and the running test name.
+     */
+    protected String lraClientId() {
+        return this.getClass().getSimpleName() + "#" + testName.getMethodName();
+    }
+
+    /**
+     * Adjusting the default timeout by the specified timeout factor
+     * which can be defined by user.
+     */
+    protected long lraTimeout() {
+        return Util.adjust(LraTckConfigBean.LRA_TIMEOUT_MILLIS, config.timeoutFactor());
+    }
+
+
+    void replayEndPhase(String resource) {
+        // trigger a recovery scan which trigger a replay attempt on any participants
+        // that have responded to complete/compensate requests with Response.Status.ACCEPTED
+        WebTarget recoveryPath = recoveryTarget.path("recovery");
+        Response response2 = recoveryPath
+                .request().get();
+
+        checkStatusAndCloseResponse(Response.Status.OK, response2, recoveryPath);
+    }
+}
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..92fc8ef 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
@@ -19,6 +19,7 @@
  *******************************************************************************/
 package org.eclipse.microprofile.lra.tck;
 
+import static org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER;
 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;
@@ -30,6 +31,7 @@ import static org.eclipse.microprofile.lra.tck.participant.api.ParticipatingTckR
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -49,7 +51,6 @@ import javax.ws.rs.client.Entity;
 import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.Response;
 
-import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
 import org.eclipse.microprofile.lra.client.GenericLRAException;
 import org.eclipse.microprofile.lra.tck.participant.api.LraController;
 import org.eclipse.microprofile.lra.tck.participant.api.NoLRAController;
@@ -209,13 +210,13 @@ public class TckTests {
         try {
             response = resourcePath
                     .request()
-                    .header(LRA.LRA_HTTP_HEADER, lra)
+                    .header(LRA_HTTP_CONTEXT_HEADER, lra)
                     .put(Entity.text(""));
     
             assertEquals("Response status to ' " + resourcePath.getUri() + "' does not match.",
                     Response.Status.OK.getStatusCode(), response.getStatus());
     
-            Object parentId = response.getHeaders().getFirst(LRA.LRA_HTTP_HEADER);
+            Object parentId = response.getHeaders().getFirst(LRA_HTTP_CONTEXT_HEADER);
     
             assertNotNull("Expecting to get parent LRA id as response from " + resourcePath.getUri(), parentId);
             assertEquals("The nested activity should return the parent LRA id. The call to " + resourcePath.getUri(),
@@ -261,7 +262,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(""));
+                .request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
 
         checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
 
@@ -287,7 +288,7 @@ public class TckTests {
         URI lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS);
         WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH);
         Response response = resourcePath
-                .request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
+                .request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
         checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
         lraClient.closeLRA(lra);
         assertTrue("LRA '" + lra + "' should be active as it is not closed yet.",
@@ -299,18 +300,18 @@ public class TckTests {
         int beforeCompletedCount = getCompletedCount();
         URI lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS);
         WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path(TRANSACTIONAL_WORK_PATH);
-        Response response = resourcePath.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
+        Response response = resourcePath.request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
 
         checkStatusAndCloseResponse(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(""));
+        response = resourcePath.request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
         checkStatusAndCloseResponse(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(""));
+        response = resourcePath.request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
         checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
 
         lraClient.closeLRA(lra);
@@ -328,21 +329,18 @@ public class TckTests {
         // call a method annotated with NOT_SUPPORTED but one which programatically starts an LRA and returns it via a header
         WebTarget resourcePath = tckSuiteTarget.path(LRA_CONTROLLER_PATH).path("startViaApi");
         Response response = resourcePath.request().put(Entity.text(""));
-        // check that the method started an LRA
-        Object lraHeader = response.getHeaders().getFirst(LRA.LRA_HTTP_HEADER);
-
+        Object lraHeader = response.getHeaders().getFirst(LRA_HTTP_CONTEXT_HEADER);
         String lraId = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);
 
-        // the value returned via the header and body should be equal
-
-        assertNotNull("JAX-RS response to PUT request should have returned the header " + LRA.LRA_HTTP_HEADER
+        // LRAs started within the invoked remote method should not be available to the caller via the context header
+        assertNull("JAX-RS response to PUT request should not have returned the header " + LRA_HTTP_CONTEXT_HEADER
                 + ". The test call went to " + resourcePath.getUri(), lraHeader);
+
+        // check that the remote method returned an active LRA (ie check it's not null and then close it)
         assertNotNull("JAX-RS response to PUT request should have returned content of LRA id. The test call went to "
                 + resourcePath.getUri(), lraId);
-        assertEquals("The dependent LRA has to belong to the same LRA id. The test call went to " + resourcePath.getUri(),
-                lraId, lraHeader.toString());
 
-        lraClient.closeLRA(URI.create(lraHeader.toString()));
+        lraClient.closeLRA(URI.create(lraId));
     }
 
     @Test
@@ -395,7 +393,7 @@ public class TckTests {
         WebTarget resourcePath = tckSuiteTarget.path(path).path(path2);
 
         Response response = resourcePath
-                .request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
+                .request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
 
         checkStatusAndCloseResponse(Response.Status.OK, response, resourcePath);
 
@@ -444,7 +442,7 @@ public class TckTests {
         int beforeCompensatedCount = getCompensatedCount();
         URI lra = lraClient.startLRA(null, lraClientId(), lraTimeout(), ChronoUnit.MILLIS);
 
-        Response response = resourcePath.request().header(LRA.LRA_HTTP_HEADER, lra)
+        Response response = resourcePath.request().header(LRA_HTTP_CONTEXT_HEADER, lra)
                 .put(Entity.text(""));
 
         String lraId = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);
@@ -544,9 +542,9 @@ public class TckTests {
         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(""));
+        Response response1 = resource1Path.request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
         checkStatusAndCloseResponse(Response.Status.OK, response1, resource1Path);
-        Response response2 = resource2Path.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
+        Response response2 = resource2Path.request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
         checkStatusAndCloseResponse(Response.Status.OK, response2, resource2Path);
 
         if (close) {
@@ -578,9 +576,9 @@ public class TckTests {
         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(""));
+        Response response1 = resource1Path.request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
         checkStatusAndCloseResponse(Response.Status.OK, response1, resource1Path);
-        Response response2 = resource2Path.request().header(LRA.LRA_HTTP_HEADER, lra).put(Entity.text(""));
+        Response response2 = resource2Path.request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
         checkStatusAndCloseResponse(Response.Status.OK, response2, resource2Path);
 
         if (close) {
@@ -654,7 +652,7 @@ public class TckTests {
         Response response = resourcePath
                 .queryParam("nestedCnt", nestedCnt)
                 .request()
-                .header(LRA.LRA_HTTP_HEADER, lra)
+                .header(LRA_HTTP_CONTEXT_HEADER, lra)
                 .put(Entity.text(""));
 
         String lraStr = checkStatusReadAndCloseResponse(Response.Status.OK, response, resourcePath);