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/27 02:37:09 UTC

[cxf] branch master 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 master
in repository https://gitbox.apache.org/repos/asf/cxf.git


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

commit 67643a4fe883f5d6067d4ce07f48cf4de10be9f7
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
---
 .../cxf/tracing/brave/AbstractBraveProvider.java   |  16 ---
 .../cxf/tracing/brave/BraveStopInterceptor.java    |   2 +-
 .../opentracing/OpenTracingStopInterceptor.java    |   2 +-
 .../cxf/systest/jaxrs/tracing/BookStore.java       |  24 +++-
 .../tracing/NullPointerExceptionMapper.java}       |  19 +--
 .../jaxrs/tracing/brave/BraveTracingTest.java      |  97 ++++++-------
 .../opentracing/OpenTracingTracingTest.java        |  36 ++++-
 .../systest/jaxws/tracing/BookStoreService.java    |   1 +
 .../cxf/systest/jaxws/tracing/brave/BookStore.java |  12 ++
 .../jaxws/tracing/brave/BraveTracingTest.java      | 160 +++++++++------------
 .../jaxws/tracing/opentracing/BookStore.java       |  14 +-
 .../opentracing/OpenTracingTracingTest.java        |  13 ++
 12 files changed, 227 insertions(+), 169 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-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 1f6d752..f02142f 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
@@ -28,6 +28,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
 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;
@@ -131,7 +132,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 6308260..71c3335 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
@@ -47,6 +47,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.AbstractClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractTestServerBase;
 import org.apache.cxf.tracing.brave.BraveClientFeature;
@@ -107,6 +108,7 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
             sf.setAddress("http://localhost:" + PORT);
             sf.setProvider(new JacksonJsonProvider());
             sf.setProvider(new BraveFeature(brave));
+            sf.setProvider(new NullPointerExceptionMapper());
             server = sf.create();
         }
 
@@ -153,8 +155,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         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
@@ -167,8 +167,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         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
@@ -181,8 +179,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         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
@@ -193,8 +189,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         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
@@ -210,8 +204,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         assertThat(TestSpanReporter.getAllSpans().get(0).parentId(), not(nullValue()));
         assertThat(TestSpanReporter.getAllSpans().get(0).parentId(),
             equalTo(TestSpanReporter.getAllSpans().get(1).id()));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -223,8 +215,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
 
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
         assertThat(TestSpanReporter.getAllSpans().get(0).name(), equalTo("get /bookstore/books/async/notrace"));
-
-        assertThatTraceIsPresent(r, spanId);
     }
 
     @Test
@@ -249,8 +239,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         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
@@ -263,10 +251,7 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
             .range(0, 4)
             .mapToObj(index -> client.async().get())
             .map(this::get)
-            .forEach(r -> {
-                assertEquals(Status.OK.getStatusCode(), r.getStatus());
-                assertThatTraceHeadersArePresent(r, false);
-            });
+            .forEach(r -> assertEquals(Status.OK.getStatusCode(), r.getStatus()));
 
         assertThat(TestSpanReporter.getAllSpans().toString(), TestSpanReporter.getAllSpans().size(), equalTo(12));
 
@@ -292,10 +277,7 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         IntStream
             .range(0, 4)
             .mapToObj(index -> client.get())
-            .forEach(r -> {
-                assertEquals(Status.OK.getStatusCode(), r.getStatus());
-                assertThatTraceHeadersArePresent(r, false);
-            });
+            .forEach(r -> assertEquals(Status.OK.getStatusCode(), r.getStatus()));
 
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(12));
 
@@ -326,8 +308,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
             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();
         }
@@ -355,8 +335,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
             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();
         }
@@ -378,8 +356,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         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
@@ -394,7 +370,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
         assertThat(TestSpanReporter.getAllSpans().size(), equalTo(0));
-        assertThatTraceHeadersArePresent(r, false);
     }
 
     @Test
@@ -421,6 +396,51 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         }
     }
 
+    @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));
+    }
+
     private static WebClient createWebClient(final String path, final Object ... providers) {
         return WebClient
             .create("http://localhost:" + PORT + path, Arrays.asList(providers))
@@ -435,25 +455,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
             .header(PARENT_SPAN_ID_NAME, spanId.parentId());
     }
 
-    private static void assertThatTraceIsPresent(final Response r, final SpanId spanId) {
-        assertEquals(spanId.spanId(),
-            Long.parseLong(r.getHeaders().getFirst(SPAN_ID_NAME).toString()));
-        assertEquals(spanId.traceId(),
-            Long.parseLong(r.getHeaders().getFirst(TRACE_ID_NAME).toString()));
-        assertEquals(spanId.sampled(),
-            Boolean.parseBoolean(r.getHeaders().getFirst(SAMPLED_NAME).toString()));
-        assertEquals(spanId.parentId(),
-            Long.valueOf(r.getHeaders().getFirst(PARENT_SPAN_ID_NAME).toString()));
-    }
-
-    private static 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));
-
-        assertEquals(expectParent, r.getHeaders().containsKey(PARENT_SPAN_ID_NAME));
-    }
-
     private<T> T get(final Future<T> future) {
         try {
             return future.get(1L, TimeUnit.MINUTES);
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 e14451a..38c3ca3 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
@@ -43,6 +43,7 @@ import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
 import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
 import org.apache.cxf.systest.jaxrs.tracing.BookStore;
+import org.apache.cxf.systest.jaxrs.tracing.NullPointerExceptionMapper;
 import org.apache.cxf.testutil.common.AbstractClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractTestServerBase;
 import org.apache.cxf.tracing.opentracing.OpenTracingClientFeature;
@@ -93,7 +94,7 @@ public class OpenTracingTracingTest extends AbstractClientServerTestBase {
         .withReporter(REPORTER)
         .build();
 
-    public static class BraveServer extends AbstractTestServerBase {
+    public static class OpenTracingServer extends AbstractTestServerBase {
 
         private org.apache.cxf.endpoint.Server server;
 
@@ -110,6 +111,7 @@ public class OpenTracingTracingTest extends AbstractClientServerTestBase {
             sf.setAddress("http://localhost:" + PORT);
             sf.setProvider(new JacksonJsonProvider());
             sf.setProvider(new OpenTracingFeature(tracer));
+            sf.setProvider(new NullPointerExceptionMapper());
             server = sf.create();
         }
 
@@ -123,7 +125,7 @@ public class OpenTracingTracingTest extends AbstractClientServerTestBase {
     public static void startServers() throws Exception {
         AbstractResourceInfo.clearAllMaps();
         //keep out of process due to stack traces testing failures
-        assertTrue("server did not launch correctly", launchServer(BraveServer.class, true));
+        assertTrue("server did not launch correctly", launchServer(OpenTracingServer.class, true));
     }
 
     @After
@@ -390,6 +392,36 @@ public class OpenTracingTracingTest extends AbstractClientServerTestBase {
         }
     }
 
+    @Test
+    public void testThatErrorSpanIsCreatedOnExceptionWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books/exception").get();
+        assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), r.getStatus());
+
+        assertThat(REPORTER.getSpans().toString(), REPORTER.getSpans().size(), equalTo(1));
+        assertThat(REPORTER.getSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/exception"));
+        assertThat(REPORTER.getSpans().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(REPORTER.getSpans().toString(), REPORTER.getSpans().size(), equalTo(1));
+        assertThat(REPORTER.getSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/error"));
+        assertThat(REPORTER.getSpans().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(REPORTER.getSpans().toString(), REPORTER.getSpans().size(), equalTo(1));
+        assertThat(REPORTER.getSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/mapper"));
+        assertThat(REPORTER.getSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 404));
+    }
+
     private static WebClient createWebClient(final String path, final Object ... providers) {
         return WebClient
             .create("http://localhost:" + PORT + path, 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 f092ecf..d7c3d0b 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,11 +56,10 @@ 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.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
+import static org.hamcrest.collection.IsMapContaining.hasEntry;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -141,65 +140,50 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         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 Exception {
-        final Tracing brave = Tracing.newBuilder()
-            .localServiceName("book-store")
-            .spanReporter(new TestSpanReporter())
-            .build();
-
-        final BookStoreService service = createJaxWsService(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);
+        try (Tracing brave = createTracer()) {
+            final BookStoreService service = createJaxWsService(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 Exception {
-        final Tracing brave = Tracing.newBuilder()
-            .localServiceName("book-store")
-            .spanReporter(new TestSpanReporter())
-            .build();
-
-        final BookStoreService service = createJaxWsService(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"));
-
-                final Map<String, List<String>> response = getResponseHeaders(service);
-                assertThatTraceHeadersArePresent(response, true);
-            }
-        } finally {
-            if (span != null) {
-                span.finish();
+        try (Tracing brave = createTracer()) {
+            final BookStoreService service = createJaxWsService(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"));
+                }
+            } 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
@@ -225,27 +209,36 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
 
     @Test
     public void testThatNewChildSpanIsCreatedWhenParentIsProvidedInCaseOfFault() throws Exception {
-        final Tracing brave = Tracing.newBuilder()
-            .localServiceName("book-store")
-            .spanReporter(new TestSpanReporter())
-            .build();
-
-        final BookStoreService service = createJaxWsService(new BraveClientFeature(brave));
-
-        try {
-            service.removeBooks();
-            fail("Expected SOAPFaultException to be raised");
-        } catch (final SOAPFaultException ex) {
-            /* expected exception */
+        try (Tracing brave = createTracer()) {
+            final BookStoreService service = createJaxWsService(new BraveClientFeature(brave));
+    
+            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 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() {
@@ -261,7 +254,6 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
     }
 
     private BookStoreService createJaxWsService(final Map<String, List<String>> headers, final Feature feature) {
-
         JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
         factory.getOutInterceptors().add(new LoggingOutInterceptor());
         factory.getInInterceptors().add(new LoggingInInterceptor());
@@ -283,23 +275,11 @@ public class BraveTracingTest extends AbstractClientServerTestBase {
         final Client proxy = ClientProxy.getClient(service);
         return CastUtils.cast((Map<?, ?>)proxy.getResponseContext().get(Message.PROTOCOL_HEADERS));
     }
-
-    private static 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 static 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));
-
-        assertEquals(expectParent, 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/opentracing/BookStore.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java
index af58418..5ffa70e 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;
@@ -37,12 +40,15 @@ import io.opentracing.util.GlobalTracer;
 public class BookStore implements BookStoreService {
     private final Tracer tracer;
 
+    @Resource
+    private WebServiceContext context;
+    
     public BookStore() {
         tracer = GlobalTracer.get();
     }
 
     @WebMethod
-    public Collection< Book > getBooks() {
+    public Collection<Book> getBooks() {
         final Span span = tracer.buildSpan("Get Books").start();
         try (Scope scope = tracer.activateSpan(span)) {
             return Arrays.asList(
@@ -58,4 +64,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 d96a9ce..d7dbcb7 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
@@ -51,12 +51,14 @@ import io.opentracing.Span;
 import io.opentracing.Tracer;
 import io.opentracing.noop.NoopTracerFactory;
 import io.opentracing.propagation.Format.Builtin;
+import io.opentracing.tag.Tags;
 import io.opentracing.util.GlobalTracer;
 
 import org.junit.After;
 import org.junit.BeforeClass;
 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;
@@ -210,9 +212,20 @@ public class OpenTracingTracingTest extends AbstractClientServerTestBase {
 
         assertThat(REPORTER.getSpans().size(), equalTo(2));
         assertThat(REPORTER.getSpans().get(0).getOperationName(), equalTo("POST /BookStore"));
+        assertThat(REPORTER.getSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 500));
         assertThat(REPORTER.getSpans().get(1).getOperationName(),
             equalTo("POST http://localhost:" + PORT + "/BookStore"));
     }
+    
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvidedAndCustomStatusCodeReturned() throws Exception {
+        final BookStoreService service = createJaxWsService(new OpenTracingClientFeature(tracer));
+        service.addBooks();
+        
+        assertThat(REPORTER.getSpans().size(), equalTo(1));
+        assertThat(REPORTER.getSpans().get(0).getOperationName(), equalTo("POST /BookStore"));
+        assertThat(REPORTER.getSpans().get(0).getTags(), hasItem(Tags.HTTP_STATUS.getKey(), 202));
+    }
 
     private static BookStoreService createJaxWsService() {
         return createJaxWsService(Collections.emptyMap());