You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2020/02/28 01:41:39 UTC

[cxf] branch 3.2.x-fixes updated: CXF-8220: The tag http.status_code is always 200 in server side tracing span, no matter what situation

This is an automated email from the ASF dual-hosted git repository.

reta pushed a commit to branch 3.2.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/3.2.x-fixes by this push:
     new 54c6839  CXF-8220: The tag http.status_code is always 200 in server side tracing span, no matter what situation
54c6839 is described below

commit 54c68396b801f51b1ef50e7ff4dafcd9361b4ef6
Author: reta <dr...@gmail.com>
AuthorDate: Wed Feb 26 21:36:48 2020 -0500

    CXF-8220: The tag http.status_code is always 200 in server side tracing span, no matter what situation
    
    (cherry picked from commit 67643a4fe883f5d6067d4ce07f48cf4de10be9f7)
---
 .../cxf/tracing/brave/AbstractBraveProvider.java   |  16 --
 .../cxf/tracing/brave/BraveStopInterceptor.java    |   2 +-
 .../cxf/tracing/htrace/AbstractHTraceProvider.java |   8 -
 .../opentracing/OpenTracingStopInterceptor.java    |   2 +-
 .../cxf/systest/jaxrs/tracing/BookStore.java       |  24 ++-
 .../tracing/NullPointerExceptionMapper.java}       |  19 +-
 .../jaxrs/tracing/brave/BraveTracingTest.java      |  96 +++++-----
 .../htrace/HTraceTracingCustomHeadersTest.java     |   7 -
 .../jaxrs/tracing/htrace/HTraceTracingTest.java    |  24 ---
 .../opentracing/OpenTracingTracingTest.java        |  32 ++++
 .../systest/jaxws/tracing/BookStoreService.java    |   1 +
 .../cxf/systest/jaxws/tracing/brave/BookStore.java |  12 ++
 .../jaxws/tracing/brave/BraveTracingTest.java      | 203 ++++++++++-----------
 .../systest/jaxws/tracing/htrace/BookStore.java    |  12 ++
 .../jaxws/tracing/htrace/HTraceTracingTest.java    |  39 ++--
 .../jaxws/tracing/opentracing/BookStore.java       |  12 ++
 .../opentracing/OpenTracingTracingTest.java        |  20 ++
 17 files changed, 283 insertions(+), 246 deletions(-)

diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveProvider.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveProvider.java
index d95db3e..d991f78 100644
--- a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveProvider.java
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveProvider.java
@@ -29,7 +29,6 @@ import brave.http.HttpServerAdapter;
 import brave.http.HttpServerHandler;
 import brave.http.HttpTracing;
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.tracing.AbstractTracingProvider;
 import org.apache.cxf.tracing.brave.internal.HttpAdapterFactory;
@@ -79,14 +78,6 @@ public abstract class AbstractBraveProvider extends AbstractTracingProvider {
                                  final Map<String, List<Object>> responseHeaders,
                                  final int responseStatus,
                                  final TraceScopeHolder<TraceScope> holder) {
-
-        // Transfer tracing headers into the response headers
-        brave
-            .tracing()
-            .propagation()
-            .keys()
-            .forEach(key -> transferRequestHeader(requestHeaders, responseHeaders, key));
-
         if (holder == null) {
             return;
         }
@@ -125,11 +116,4 @@ public abstract class AbstractBraveProvider extends AbstractTracingProvider {
     private void propagateContinuationSpan(final Span continuationScope) {
         PhaseInterceptorChain.getCurrentMessage().put(Span.class, continuationScope);
     }
-
-    private void transferRequestHeader(final Map<String, List<String>> requestHeaders,
-            final Map<String, List<Object>> responseHeaders, final String header) {
-        if (requestHeaders.containsKey(header)) {
-            responseHeaders.put(header, CastUtils.cast(requestHeaders.get(header)));
-        }
-    }
 }
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveStopInterceptor.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveStopInterceptor.java
index 44d072a..7dc4c0a 100644
--- a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveStopInterceptor.java
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveStopInterceptor.java
@@ -33,7 +33,7 @@ import org.apache.cxf.phase.Phase;
 @NoJSR250Annotations
 public class BraveStopInterceptor extends AbstractBraveInterceptor {
     public BraveStopInterceptor(final HttpTracing brave) {
-        super(Phase.PRE_MARSHAL, brave);
+        super(Phase.POST_MARSHAL, brave);
     }
 
     @Override
diff --git a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java
index df218fb..33a9300 100644
--- a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java
+++ b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java
@@ -24,7 +24,6 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.tracing.AbstractTracingProvider;
 import org.apache.htrace.core.SpanId;
@@ -69,13 +68,6 @@ public abstract class AbstractHTraceProvider extends AbstractTracingProvider {
     protected void stopTraceSpan(final Map<String, List<String>> requestHeaders,
                                  final Map<String, List<Object>> responseHeaders,
                                  final TraceScopeHolder<TraceScope> holder) {
-        final String spanIdHeader = getSpanIdHeader();
-
-        // Transfer tracing headers into the response headers
-        if (requestHeaders.containsKey(spanIdHeader)) {
-            responseHeaders.put(spanIdHeader, CastUtils.cast(requestHeaders.get(spanIdHeader)));
-        }
-
         if (holder == null) {
             return;
         }
diff --git a/integration/tracing/tracing-opentracing/src/main/java/org/apache/cxf/tracing/opentracing/OpenTracingStopInterceptor.java b/integration/tracing/tracing-opentracing/src/main/java/org/apache/cxf/tracing/opentracing/OpenTracingStopInterceptor.java
index 9ecc0c4..5aa61ae 100644
--- a/integration/tracing/tracing-opentracing/src/main/java/org/apache/cxf/tracing/opentracing/OpenTracingStopInterceptor.java
+++ b/integration/tracing/tracing-opentracing/src/main/java/org/apache/cxf/tracing/opentracing/OpenTracingStopInterceptor.java
@@ -32,7 +32,7 @@ import io.opentracing.Tracer;
 
 public class OpenTracingStopInterceptor extends AbstractOpenTracingInterceptor {
     public OpenTracingStopInterceptor(final Tracer tracer) {
-        super(Phase.PRE_MARSHAL, tracer);
+        super(Phase.POST_MARSHAL, tracer);
     }
 
     @Override
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/BookStore.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/BookStore.java
index 3b5a4a0..5597a5a 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/BookStore.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/BookStore.java
@@ -29,6 +29,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 
 import javax.ws.rs.GET;
+import javax.ws.rs.InternalServerErrorException;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -172,7 +173,28 @@ public class BookStore<T extends Closeable> {
         Thread.sleep(500);
         return books();
     }
-    
+
+    @GET
+    @Path("/books/exception")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Collection<Book> getBooksException() {
+        throw new InternalServerErrorException("Simulated failure");
+    }
+
+    @GET
+    @Path("/books/error")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getBooksError() {
+        return Response.status(503).build();
+    }
+
+    @GET
+    @Path("/books/mapper")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getNpe() {
+        throw new NullPointerException("Simulated failure");
+    }
+
     private static Collection<Book> books() {
         return Arrays.asList(
                 new Book("Apache CXF in Action", UUID.randomUUID().toString()),
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/BookStoreService.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/NullPointerExceptionMapper.java
similarity index 65%
copy from systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/BookStoreService.java
copy to systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/NullPointerExceptionMapper.java
index e2c5ab8..ef81184 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/BookStoreService.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/NullPointerExceptionMapper.java
@@ -16,16 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.cxf.systest.jaxws.tracing;
 
-import java.util.Collection;
+package org.apache.cxf.systest.jaxrs.tracing;
 
-import javax.jws.WebService;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
 
-import org.apache.cxf.systest.Book;
-
-@WebService
-public interface BookStoreService {
-    Collection< Book > getBooks();
-    int removeBooks();
+@Provider
+public class NullPointerExceptionMapper implements ExceptionMapper<NullPointerException> {
+    public Response toResponse(NullPointerException exception) {
+        return Response.status(Status.NOT_FOUND).build();
+    }
 }
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java
index cfc3534..513b956 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java
@@ -48,6 +48,7 @@ import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
 import org.apache.cxf.systest.brave.BraveTestSupport.SpanId;
 import org.apache.cxf.systest.brave.TestSpanReporter;
 import org.apache.cxf.systest.jaxrs.tracing.BookStore;
+import org.apache.cxf.systest.jaxrs.tracing.NullPointerExceptionMapper;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
 import org.apache.cxf.tracing.brave.BraveClientFeature;
@@ -76,9 +77,6 @@ import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.collection.IsMapContaining.hasEntry;
 import static org.hamcrest.collection.IsMapContaining.hasKey;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
 public class BraveTracingTest extends AbstractBusClientServerTestBase {
     public static final String PORT = allocatePort(BraveTracingTest.class);
@@ -105,6 +103,7 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
             sf.setAddress("http://localhost:" + PORT);
             sf.setProvider(new JacksonJsonProvider());
             sf.setProvider(new BraveFeature(brave));
+            sf.setProvider(new NullPointerExceptionMapper());
             sf.create();
         }
     }
@@ -156,8 +155,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
         assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("get /bookstore/books"));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -170,8 +167,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get /bookstore/book/1"));
         assertThat(TestSpanReporter.getAllSpans().get(0).tags(), hasEntry("book-id", "1"));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -184,8 +179,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReporter.getAllSpans(), hasSpan("processing books", hasItem("Processing started")));
         assertThat(TestSpanReporter.getAllSpans(), hasSpan("put /bookstore/process"));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -196,8 +189,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(3));
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
         assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
-
-        assertThatTraceHeadersArePresent(r, false);
     }
 
     @Test
@@ -213,8 +204,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
         assertThat(TestSpanReporter.getAllSpans().get(0).parentId(),
             equalTo(TestSpanReporter.getAllSpans().get(1).id()));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -226,8 +215,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
 
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get /bookstore/books/async/notrace"));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -252,8 +239,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
         assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("get /bookstore/books"));
         assertThat(TestSpanReporter.getAllSpans().get(2).name(), equalTo("get " + client.getCurrentURI()));
-
-        assertThatTraceHeadersArePresent(r, false);
     }
 
     @Test
@@ -270,7 +255,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
 
         for (final Response r: responses) {
             assertEquals(Status.OK.getStatusCode(), r.getStatus());
-            assertThatTraceHeadersArePresent(r, false);
         }
 
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(12));
@@ -301,7 +285,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
 
         for (final Response r: responses) {
             assertEquals(Status.OK.getStatusCode(), r.getStatus());
-            assertThatTraceHeadersArePresent(r, false);
         }
 
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(12));
@@ -334,8 +317,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
                 assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
                 assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("get /bookstore/books"));
                 assertThat(TestSpanReporter.getAllSpans().get(2).name(), equalTo("get " + client.getCurrentURI()));
-    
-                assertThatTraceHeadersArePresent(r, true);
             }
         } finally {
             span.finish();
@@ -365,8 +346,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
                 assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
                 assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("get /bookstore/books"));
                 assertThat(TestSpanReporter.getAllSpans().get(2).name(), equalTo("get " + client.getCurrentURI()));
-    
-                assertThatTraceHeadersArePresent(r, true);
             }
         } finally {
             span.finish();
@@ -389,8 +368,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("get /bookstore/books/pseudo-async"));
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("processing books"));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -405,7 +382,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(0));
-        assertThatTraceHeadersArePresent(r, false);
     }
 
     @Test
@@ -432,6 +408,51 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         }
     }
 
+    @Test
+    public void testThatErrorSpanIsCreatedOnExceptionWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books/exception").get();
+        assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), r.getStatus());
+
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get /bookstore/books/exception"));
+        assertThat(TestSpanReporter.getAllSpans().get(0).tags(), hasEntry("http.status_code", "500"));
+
+        assertFalse(r.getHeaders().containsKey(SPAN_ID_NAME));
+        assertFalse(r.getHeaders().containsKey(TRACE_ID_NAME));
+        assertFalse(r.getHeaders().containsKey(SAMPLED_NAME));
+        assertFalse(r.getHeaders().containsKey(PARENT_SPAN_ID_NAME));
+    }
+    
+    @Test
+    public void testThatErrorSpanIsCreatedOnErrorWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books/error").get();
+        assertEquals(Status.SERVICE_UNAVAILABLE.getStatusCode(), r.getStatus());
+
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get /bookstore/books/error"));
+        assertThat(TestSpanReporter.getAllSpans().get(0).tags(), hasEntry("http.status_code", "503"));
+
+        assertFalse(r.getHeaders().containsKey(SPAN_ID_NAME));
+        assertFalse(r.getHeaders().containsKey(TRACE_ID_NAME));
+        assertFalse(r.getHeaders().containsKey(SAMPLED_NAME));
+        assertFalse(r.getHeaders().containsKey(PARENT_SPAN_ID_NAME));
+    }
+
+    @Test
+    public void testThatErrorSpanIsCreatedOnMappedExceptionWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books/mapper").get();
+        assertEquals(Status.NOT_FOUND.getStatusCode(), r.getStatus());
+
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get /bookstore/books/mapper"));
+        assertThat(TestSpanReporter.getAllSpans().get(0).tags(), hasEntry("http.status_code", "404"));
+
+        assertFalse(r.getHeaders().containsKey(SPAN_ID_NAME));
+        assertFalse(r.getHeaders().containsKey(TRACE_ID_NAME));
+        assertFalse(r.getHeaders().containsKey(SAMPLED_NAME));
+        assertFalse(r.getHeaders().containsKey(PARENT_SPAN_ID_NAME));
+    }
+
     protected WebClient createWebClient(final String url, final Object ... providers) {
         return WebClient
             .create("http://localhost:" + PORT + url, Arrays.asList(providers))
@@ -446,29 +467,6 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
             .header(PARENT_SPAN_ID_NAME, spanId.parentId());
     }
 
-    private void assertThatTraceIsPresent(final Response r, final SpanId spanId) {
-        assertThat((String)r.getHeaders().getFirst(SPAN_ID_NAME),
-            equalTo(Long.toString(spanId.spanId())));
-        assertThat((String)r.getHeaders().getFirst(TRACE_ID_NAME),
-            equalTo(Long.toString(spanId.traceId())));
-        assertThat((String)r.getHeaders().getFirst(SAMPLED_NAME),
-            equalTo(Boolean.toString(spanId.sampled())));
-        assertThat((String)r.getHeaders().getFirst(PARENT_SPAN_ID_NAME),
-            equalTo(Long.toString(spanId.parentId())));
-    }
-
-    private void assertThatTraceHeadersArePresent(final Response r, final boolean expectParent) {
-        assertTrue(r.getHeaders().containsKey(SPAN_ID_NAME));
-        assertTrue(r.getHeaders().containsKey(TRACE_ID_NAME));
-        assertTrue(r.getHeaders().containsKey(SAMPLED_NAME));
-
-        if (expectParent) {
-            assertTrue(r.getHeaders().containsKey(PARENT_SPAN_ID_NAME));
-        } else {
-            assertFalse(r.getHeaders().containsKey(PARENT_SPAN_ID_NAME));
-        }
-    }
-    
     private<T> T get(final Future<T> future) {
         try {
             return future.get(1, TimeUnit.HOURS);
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingCustomHeadersTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingCustomHeadersTest.java
index ab29b4d..efa9b22 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingCustomHeadersTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingCustomHeadersTest.java
@@ -51,9 +51,6 @@ import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.notNullValue;
-
 public class HTraceTracingCustomHeadersTest extends AbstractBusClientServerTestBase {
     public static final String PORT = allocatePort(HTraceTracingCustomHeadersTest.class);
 
@@ -112,16 +109,12 @@ public class HTraceTracingCustomHeadersTest extends AbstractBusClientServerTestB
             .header(CUSTOM_HEADER_SPAN_ID, spanId.toString())
             .get();
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
-
-        assertThat((String)r.getHeaders().getFirst(CUSTOM_HEADER_SPAN_ID), equalTo(spanId.toString()));
     }
 
     @Test
     public void testThatNewChildSpanIsCreated() {
         final Response r = createWebClient("/bookstore/books", htraceClientProvider).get();
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
-
-        assertThat((String)r.getHeaders().getFirst(CUSTOM_HEADER_SPAN_ID), notNullValue());
     }
 
     protected WebClient createWebClient(final String url, final Object ... providers) {
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingTest.java
index a466b96..6d5bf35 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingTest.java
@@ -118,8 +118,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("GET bookstore/books"));
-
-        assertFalse(r.getHeaders().containsKey(TracerHeaders.DEFAULT_HEADER_SPAN_ID));
     }
 
     @Test
@@ -134,8 +132,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("GET bookstore/books"));
-
-        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo(spanId.toString()));
     }
 
     @Test
@@ -150,8 +146,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(1));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("GET bookstore/book/1"));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getKVAnnotations().size(), equalTo(1));
-
-        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo(spanId.toString()));
     }
 
     @Test
@@ -166,8 +160,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans(), hasSpan("Processing books", hasItem("Processing started")));
         assertThat(TestSpanReceiver.getAllSpans(), hasSpan("PUT bookstore/process", empty()));
-
-        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo(spanId.toString()));
     }
 
     @Test
@@ -178,8 +170,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(3));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getParents().length, equalTo(1));
-
-        assertTrue(r.getHeaders().containsKey(TracerHeaders.DEFAULT_HEADER_SPAN_ID));
     }
 
     @Test
@@ -194,8 +184,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("GET bookstore/books/async"));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Processing books"));
-
-        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo(spanId.toString()));
     }
 
     @Test
@@ -210,8 +198,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(1));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(),
             equalTo("GET bookstore/books/async/notrace"));
-
-        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo(spanId.toString()));
     }
 
     @Test
@@ -236,8 +222,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("GET bookstore/books"));
         assertThat(TestSpanReceiver.getAllSpans().get(2).getDescription(), equalTo("GET " + client.getCurrentURI()));
-
-        assertTrue(r.getHeaders().containsKey(TracerHeaders.DEFAULT_HEADER_SPAN_ID));
     }
 
     @Test
@@ -250,8 +234,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
             assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
             assertThat(TestSpanReceiver.getAllSpans().get(0).getParents().length, equalTo(1));
             assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("GET bookstore/books"));
-
-            assertTrue(r.getHeaders().containsKey(TracerHeaders.DEFAULT_HEADER_SPAN_ID));
         }
 
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(3));
@@ -271,8 +253,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
             assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
             assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
             assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("GET bookstore/books"));
-
-            assertTrue(r.getHeaders().containsKey(TracerHeaders.DEFAULT_HEADER_SPAN_ID));
         }
 
         assertThat(TestSpanReceiver.getAllSpans().get(2).getDescription(), equalTo("test span"));
@@ -290,8 +270,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("GET bookstore/books/pseudo-async"));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Processing books"));
-
-        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo(spanId.toString()));
     }
 
     @Test
@@ -308,7 +286,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
 
         for (final Response r: responses) {
             assertEquals(Status.OK.getStatusCode(), r.getStatus());
-            assertTrue(r.getHeaders().containsKey(TracerHeaders.DEFAULT_HEADER_SPAN_ID));
         }
 
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(12));
@@ -339,7 +316,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
 
         for (final Response r: responses) {
             assertEquals(Status.OK.getStatusCode(), r.getStatus());
-            assertTrue(r.getHeaders().containsKey(TracerHeaders.DEFAULT_HEADER_SPAN_ID));
         }
 
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(12));
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java
index 3c0dd4f..ec1714a 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java
@@ -48,6 +48,7 @@ import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
 import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
 import org.apache.cxf.systest.jaeger.TestSender;
 import org.apache.cxf.systest.jaxrs.tracing.BookStore;
+import org.apache.cxf.systest.jaxrs.tracing.NullPointerExceptionMapper;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
 import org.apache.cxf.tracing.opentracing.OpenTracingClientFeature;
@@ -101,6 +102,7 @@ public class OpenTracingTracingTest extends AbstractBusClientServerTestBase {
             sf.setAddress("http://localhost:" + PORT);
             sf.setProvider(new JacksonJsonProvider());
             sf.setProvider(new OpenTracingFeature(tracer));
+            sf.setProvider(new NullPointerExceptionMapper());
             sf.create();
         }
     }
@@ -381,7 +383,37 @@ public class OpenTracingTracingTest extends AbstractBusClientServerTestBase {
             assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("GET /bookstore/books/long"));
         }
     }
+
+    @Test
+    public void testThatErrorSpanIsCreatedOnExceptionWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books/exception").get();
+        assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().toString(), TestSender.getAllSpans().size(), equalTo(1));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/exception"));
+        assertThat(TestSender.getAllSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 500));
+    }
     
+    @Test
+    public void testThatErrorSpanIsCreatedOnErrorWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books/error").get();
+        assertEquals(Status.SERVICE_UNAVAILABLE.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().toString(), TestSender.getAllSpans().size(), equalTo(1));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/error"));
+        assertThat(TestSender.getAllSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 503));
+    }
+
+    @Test
+    public void testThatErrorSpanIsCreatedOnMappedExceptionWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books/mapper").get();
+        assertEquals(Status.NOT_FOUND.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().toString(), TestSender.getAllSpans().size(), equalTo(1));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/mapper"));
+        assertThat(TestSender.getAllSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 404));
+    }
+
     protected WebClient createWebClient(final String url, final Object ... providers) {
         return WebClient
             .create("http://localhost:" + PORT + url, Arrays.asList(providers))
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/BookStoreService.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/BookStoreService.java
index e2c5ab8..c6a58cf 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/BookStoreService.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/BookStoreService.java
@@ -28,4 +28,5 @@ import org.apache.cxf.systest.Book;
 public interface BookStoreService {
     Collection< Book > getBooks();
     int removeBooks();
+    void addBooks();
 }
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java
index d239a6a..2a1d254 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java
@@ -22,8 +22,11 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.UUID;
 
+import javax.annotation.Resource;
 import javax.jws.WebMethod;
 import javax.jws.WebService;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
 
 import brave.Span;
 import brave.Tracer.SpanInScope;
@@ -36,6 +39,9 @@ import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
 public class BookStore implements BookStoreService {
     private final Tracing brave;
 
+    @Resource
+    private WebServiceContext context;
+
     public BookStore() {
         brave = Tracing.newBuilder()
             .localServiceName("book-store")
@@ -60,4 +66,10 @@ public class BookStore implements BookStoreService {
     public int removeBooks() {
         throw new RuntimeException("Unable to remove books");
     }
+    
+    @WebMethod
+    public void addBooks() {
+        final MessageContext ctx = context.getMessageContext();
+        ctx.put(MessageContext.HTTP_RESPONSE_CODE, 305);
+    }
 }
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java
index b2fad83..931368b 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java
@@ -56,10 +56,9 @@ import static org.apache.cxf.systest.brave.BraveTestSupport.SAMPLED_NAME;
 import static org.apache.cxf.systest.brave.BraveTestSupport.SPAN_ID_NAME;
 import static org.apache.cxf.systest.brave.BraveTestSupport.TRACE_ID_NAME;
 import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.hasItem;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
-
+import static org.hamcrest.collection.IsMapContaining.hasEntry;
 
 public class BraveTracingTest extends AbstractBusClientServerTestBase {
     public static final String PORT = allocatePort(BraveTracingTest.class);
@@ -134,75 +133,60 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
         assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("post /bookstore"));
-
-        final Map<String, List<String>> response = getResponseHeaders(service);
-        assertThatTraceIsPresent(response, spanId);
     }
 
     @Test
-    public void testThatNewChildSpanIsCreatedWhenParentIsProvided() throws MalformedURLException {
-        final Tracing brave = Tracing.newBuilder()
-            .localServiceName("book-store")
-            .spanReporter(new TestSpanReporter())
-            .build();
-
-        final BookStoreService service = createJaxWsService(new Configurator() {
-            @Override
-            public void configure(final JaxWsProxyFactoryBean factory) {
-                factory.getFeatures().add(new BraveClientFeature(brave));
-            }
-        });
-        assertThat(service.getBooks().size(), equalTo(2));
-
-        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(3));
-        assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
-        assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
-        assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("post /bookstore"));
-        assertThat(TestSpanReporter.getAllSpans().get(2).name(),
-            equalTo("post http://localhost:" + PORT + "/bookstore"));
-
-        final Map<String, List<String>> response = getResponseHeaders(service);
-        assertThatTraceHeadersArePresent(response, false);
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvided() throws Exception {
+        try (Tracing brave = createTracer()) {
+            final BookStoreService service = createJaxWsService(new Configurator() {
+                @Override
+                public void configure(final JaxWsProxyFactoryBean factory) {
+                    factory.getFeatures().add(new BraveClientFeature(brave));
+                }
+            });
+            assertThat(service.getBooks().size(), equalTo(2));
+    
+            assertThat(TestSpanReporter.getAllSpans().size(), equalTo(3));
+            assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
+            assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
+            assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("post /bookstore"));
+            assertThat(TestSpanReporter.getAllSpans().get(2).name(),
+                equalTo("post http://localhost:" + PORT + "/bookstore"));
+        }
     }
 
     @Test
-    public void testThatProvidedSpanIsNotClosedWhenActive() throws MalformedURLException {
-        final Tracing brave = Tracing.newBuilder()
-            .localServiceName("book-store")
-            .spanReporter(new TestSpanReporter())
-            .build();
-
-        final BookStoreService service = createJaxWsService(new Configurator() {
-            @Override
-            public void configure(final JaxWsProxyFactoryBean factory) {
-                factory.getFeatures().add(new BraveClientFeature(brave));
-            }
-        });
-
-        final Span span = brave.tracer().nextSpan().name("test span").start();
-        try {
-            try (SpanInScope scope = brave.tracer().withSpanInScope(span)) {
-                assertThat(service.getBooks().size(), equalTo(2));
-                assertThat(brave.tracer().currentSpan(), not(nullValue()));
-    
-                assertThat(TestSpanReporter.getAllSpans().size(), equalTo(3));
-                assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
-                assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
-                assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("post /bookstore"));
-                assertThat(TestSpanReporter.getAllSpans().get(2).name(),
-                    equalTo("post http://localhost:" + PORT + "/bookstore"));
+    public void testThatProvidedSpanIsNotClosedWhenActive() throws Exception {
+        try (Tracing brave = createTracer()) {
+            final BookStoreService service = createJaxWsService(new Configurator() {
+                @Override
+                public void configure(final JaxWsProxyFactoryBean factory) {
+                    factory.getFeatures().add(new BraveClientFeature(brave));
+                }
+            });
+            
+            final Span span = brave.tracer().nextSpan().name("test span").start();
+            try {
+                try (SpanInScope scope = brave.tracer().withSpanInScope(span)) {
+                    assertThat(service.getBooks().size(), equalTo(2));
+                    assertThat(brave.tracer().currentSpan(), not(nullValue()));
     
-                final Map<String, List<String>> response = getResponseHeaders(service);
-                assertThatTraceHeadersArePresent(response, true);
-            }
-        } finally {
-            if (span != null) {
-                span.finish();
+                    assertThat(TestSpanReporter.getAllSpans().size(), equalTo(3));
+                    assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get books"));
+                    assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
+                    assertThat(TestSpanReporter.getAllSpans().get(1).name(), equalTo("post /bookstore"));
+                    assertThat(TestSpanReporter.getAllSpans().get(2).name(),
+                        equalTo("post http://localhost:" + PORT + "/bookstore"));
+                }
+            } finally {
+                if (span != null) {
+                    span.finish();
+                }
             }
+    
+            assertThat(TestSpanReporter.getAllSpans().size(), equalTo(4));
+            assertThat(TestSpanReporter.getAllSpans().get(3).name(), equalTo("test span"));
         }
-
-        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(4));
-        assertThat(TestSpanReporter.getAllSpans().get(3).name(), equalTo("test span"));
     }
 
     @Test
@@ -227,35 +211,48 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
     }
 
     @Test
-    public void testThatNewChildSpanIsCreatedWhenParentIsProvidedInCaseOfFault() throws MalformedURLException {
-        final Tracing brave = Tracing.newBuilder()
-            .localServiceName("book-store")
-            .spanReporter(new TestSpanReporter())
-            .build();
-
-        final BookStoreService service = createJaxWsService(new Configurator() {
-            @Override
-            public void configure(final JaxWsProxyFactoryBean factory) {
-                factory.getFeatures().add(new BraveClientFeature(brave));
-                factory.getOutInterceptors().add(new LoggingOutInterceptor());
-                factory.getInInterceptors().add(new LoggingInInterceptor());
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvidedInCaseOfFault() throws Exception {
+        try (Tracing brave = createTracer()) {
+            final BookStoreService service = createJaxWsService(new Configurator() {
+                @Override
+                public void configure(final JaxWsProxyFactoryBean factory) {
+                    factory.getFeatures().add(new BraveClientFeature(brave));
+                }
+            });
+    
+            try {
+                service.removeBooks();
+                fail("Expected SOAPFaultException to be raised");
+            } catch (final SOAPFaultException ex) {
+                /* expected exception */
             }
-        });
-
-        try {
-            service.removeBooks();
-            fail("Expected SOAPFaultException to be raised");
-        } catch (final SOAPFaultException ex) {
-            /* expected exception */
+    
+            assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
+            assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("post /bookstore"));
+            assertThat(TestSpanReporter.getAllSpans().get(1).name(),
+                equalTo("post http://localhost:" + PORT + "/bookstore"));
+        }
+    }
+    
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvidedAndCustomStatusCodeReturned() throws Exception {
+        try (Tracing brave = createTracer()) {
+            final BookStoreService service = createJaxWsService(new Configurator() {
+                @Override
+                public void configure(final JaxWsProxyFactoryBean factory) {
+                    factory.getFeatures().add(new BraveClientFeature(brave));
+                }
+            });
+            
+            service.addBooks();
+    
+            assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
+            assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("post /bookstore"));
+            assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), nullValue());
+            assertThat(TestSpanReporter.getAllSpans().get(0).tags(), hasEntry("http.status_code", "305"));
+            assertThat(TestSpanReporter.getAllSpans().get(1).name(),
+                    equalTo("post http://localhost:" + PORT + "/bookstore"));
         }
-
-        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
-        assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("post /bookstore"));
-        assertThat(TestSpanReporter.getAllSpans().get(1).name(),
-            equalTo("post http://localhost:" + PORT + "/bookstore"));
-
-        final Map<String, List<String>> response = getResponseHeaders(service);
-        assertThatTraceHeadersArePresent(response, false);
     }
 
     private BookStoreService createJaxWsService() throws MalformedURLException {
@@ -294,27 +291,11 @@ public class BraveTracingTest extends AbstractBusClientServerTestBase {
         final Client proxy = ClientProxy.getClient(service);
         return CastUtils.cast((Map<?, ?>)proxy.getResponseContext().get(Message.PROTOCOL_HEADERS));
     }
-
-    private void assertThatTraceIsPresent(Map<String, List<String>> headers, SpanId spanId) {
-        assertThat(headers.get(SPAN_ID_NAME),
-            hasItem(Long.toString(spanId.spanId())));
-        assertThat(headers.get(TRACE_ID_NAME),
-            hasItem(Long.toString(spanId.traceId())));
-        assertThat(headers.get(SAMPLED_NAME),
-            hasItem(Boolean.toString(spanId.sampled())));
-        assertThat(headers.get(PARENT_SPAN_ID_NAME),
-            hasItem(Long.toString(spanId.parentId())));
-    }
-
-    private void assertThatTraceHeadersArePresent(Map<String, List<String>> headers, boolean expectParent) {
-        assertTrue(headers.containsKey(SPAN_ID_NAME));
-        assertTrue(headers.containsKey(TRACE_ID_NAME));
-        assertTrue(headers.containsKey(SAMPLED_NAME));
-
-        if (expectParent) {
-            assertTrue(headers.containsKey(PARENT_SPAN_ID_NAME));
-        } else {
-            assertFalse(headers.containsKey(PARENT_SPAN_ID_NAME));
-        }
+    
+    private static Tracing createTracer() {
+        return Tracing.newBuilder()
+            .localServiceName("book-store")
+            .spanReporter(new TestSpanReporter())
+            .build();
     }
 }
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/BookStore.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/BookStore.java
index 638836c..15a8fd4 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/BookStore.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/BookStore.java
@@ -22,8 +22,11 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.UUID;
 
+import javax.annotation.Resource;
 import javax.jws.WebMethod;
 import javax.jws.WebService;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
 
 import org.apache.cxf.systest.Book;
 import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
@@ -32,6 +35,9 @@ import org.apache.htrace.core.Tracer;
 
 @WebService(endpointInterface = "org.apache.cxf.systest.jaxws.tracing.BookStoreService", serviceName = "BookStore")
 public class BookStore implements BookStoreService {
+    @Resource
+    private WebServiceContext context;
+
     @WebMethod
     public Collection< Book > getBooks() {
         try (TraceScope span = Tracer.curThreadTracer().newScope("Get Books")) {
@@ -46,4 +52,10 @@ public class BookStore implements BookStoreService {
     public int removeBooks() {
         throw new RuntimeException("Unable to remove books");
     }
+    
+    @WebMethod
+    public void addBooks() {
+        final MessageContext ctx = context.getMessageContext();
+        ctx.put(MessageContext.HTTP_RESPONSE_CODE, 305);
+    }
 }
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java
index 3cfeb8a..cc29504 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java
@@ -28,7 +28,6 @@ import org.apache.cxf.endpoint.Client;
 import org.apache.cxf.ext.logging.LoggingInInterceptor;
 import org.apache.cxf.ext.logging.LoggingOutInterceptor;
 import org.apache.cxf.frontend.ClientProxy;
-import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 import org.apache.cxf.message.Message;
@@ -54,7 +53,6 @@ import org.junit.Ignore;
 import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.hasItems;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 
@@ -69,7 +67,7 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
             sf.setServiceClass(BookStore.class);
             sf.setAddress("http://localhost:" + PORT);
             sf.getInInterceptors().add(new HTraceStartInterceptor(Phase.PRE_INVOKE, tracer));
-            sf.getOutInterceptors().add(new HTraceStopInterceptor(Phase.PRE_MARSHAL));
+            sf.getOutInterceptors().add(new HTraceStopInterceptor(Phase.POST_MARSHAL));
             sf.create();
         }
     }
@@ -98,9 +96,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("POST /BookStore"));
-
-        final Map<String, List<String>> response = getResponseHeaders(service);
-        assertThat(response.get(TracerHeaders.DEFAULT_HEADER_SPAN_ID), nullValue());
     }
 
     @Test
@@ -115,9 +110,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("Get Books"));
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("POST /BookStore"));
-
-        final Map<String, List<String>> response = getResponseHeaders(service);
-        assertThat(response.get(TracerHeaders.DEFAULT_HEADER_SPAN_ID), hasItems(spanId.toString()));
     }
 
     @Test
@@ -139,9 +131,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("POST /BookStore"));
         assertThat(TestSpanReceiver.getAllSpans().get(2).getDescription(),
             equalTo("POST http://localhost:" + PORT + "/BookStore"));
-
-        final Map<String, List<String>> response = getResponseHeaders(service);
-        assertThat(response.get(TracerHeaders.DEFAULT_HEADER_SPAN_ID), not(nullValue()));
     }
 
     @Test
@@ -168,9 +157,26 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
 
         assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(3));
         assertThat(TestSpanReceiver.getAllSpans().get(2).getDescription(), equalTo("test span"));
+    }
 
-        final Map<String, List<String>> response = getResponseHeaders(service);
-        assertThat(response.get(TracerHeaders.DEFAULT_HEADER_SPAN_ID), not(nullValue()));
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvidedAndCustomStatusCodeReturned() throws Exception {
+        final Tracer tracer = createTracer();
+
+        final BookStoreService service = createJaxWsService(new Configurator() {
+            @Override
+            public void configure(final JaxWsProxyFactoryBean factory) {
+                factory.getOutInterceptors().add(new HTraceClientStartInterceptor(tracer));
+                factory.getInInterceptors().add(new HTraceClientStopInterceptor());
+            }
+        });
+        service.addBooks();
+
+        assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
+        assertThat(TestSpanReceiver.getAllSpans().get(0).getParents().length, equalTo(1));
+        assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("POST /BookStore"));
+        assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(),
+            equalTo("POST http://localhost:" + PORT + "/BookStore"));
     }
 
 
@@ -206,11 +212,6 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         return service;
     }
 
-    private Map<String, List<String>> getResponseHeaders(final BookStoreService service) {
-        final Client proxy = ClientProxy.getClient(service);
-        return CastUtils.cast((Map<?, ?>)proxy.getResponseContext().get(Message.PROTOCOL_HEADERS));
-    }
-
     private static Tracer createTracer() {
         final Map<String, String> properties = new HashMap<>();
         properties.put(Tracer.SPAN_RECEIVER_CLASSES_KEY, TestSpanReceiver.class.getName());
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java
index 3310dae..ae653a0 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java
@@ -22,8 +22,11 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.UUID;
 
+import javax.annotation.Resource;
 import javax.jws.WebMethod;
 import javax.jws.WebService;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
 
 import org.apache.cxf.systest.Book;
 import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
@@ -36,6 +39,9 @@ import io.opentracing.util.GlobalTracer;
 public class BookStore implements BookStoreService {
     private final Tracer tracer;
 
+    @Resource
+    private WebServiceContext context;
+    
     public BookStore() {
         tracer = GlobalTracer.get();
     }
@@ -54,4 +60,10 @@ public class BookStore implements BookStoreService {
     public int removeBooks() {
         throw new RuntimeException("Unable to remove books");
     }
+    
+    @WebMethod
+    public void addBooks() {
+        final MessageContext ctx = context.getMessageContext();
+        ctx.put(MessageContext.HTTP_RESPONSE_CODE, 202);
+    }
 }
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java
index 1c6f20a..95bb76a 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java
@@ -49,6 +49,7 @@ import org.awaitility.Duration;
 import io.opentracing.ActiveSpan;
 import io.opentracing.Tracer;
 import io.opentracing.propagation.Format.Builtin;
+import io.opentracing.tag.Tags;
 import io.opentracing.util.GlobalTracer;
 
 import org.junit.Before;
@@ -56,6 +57,7 @@ import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import static org.apache.cxf.systest.jaxrs.tracing.opentracing.IsTagContaining.hasItem;
 import static org.awaitility.Awaitility.await;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.not;
@@ -217,9 +219,27 @@ public class OpenTracingTracingTest extends AbstractBusClientServerTestBase {
 
         assertThat(TestSender.getAllSpans().size(), equalTo(2));
         assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("POST /BookStore"));
+        assertThat(TestSender.getAllSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 500));
         assertThat(TestSender.getAllSpans().get(1).getOperationName(),
             equalTo("POST http://localhost:" + PORT + "/BookStore"));
     }
+    
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvidedAndCustomStatusCodeReturned() throws Exception {
+        final BookStoreService service = createJaxWsService(new Configurator() {
+            @Override
+            public void configure(final JaxWsProxyFactoryBean factory) {
+                factory.getFeatures().add(new OpenTracingClientFeature(tracer));
+                factory.getOutInterceptors().add(new LoggingOutInterceptor());
+                factory.getInInterceptors().add(new LoggingInInterceptor());
+            }
+        });
+        service.addBooks();
+        
+        assertThat(TestSender.getAllSpans().size(), equalTo(1));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("POST /BookStore"));
+        assertThat(TestSender.getAllSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 202));
+    }
 
     private BookStoreService createJaxWsService() throws MalformedURLException {
         return createJaxWsService(new HashMap<String, List<String>>());