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 2016/12/27 00:29:29 UTC

[1/2] cxf git commit: CXF-7164: Support tracing using OpenZipkin Brave. Implemented JAX-RS support.

Repository: cxf
Updated Branches:
  refs/heads/master 2103bc595 -> c194254d6


http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsAnnotationContaining.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsAnnotationContaining.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsAnnotationContaining.java
new file mode 100644
index 0000000..54d877b
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsAnnotationContaining.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs.tracing.brave;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.core.IsCollectionContaining;
+
+import zipkin.Annotation;
+
+public class IsAnnotationContaining extends IsCollectionContaining<Annotation> {
+    public IsAnnotationContaining(final String value) {
+        super(new TypeSafeMatcher<Annotation>() {
+            @Override
+            public void describeTo(Description description) {
+                description.appendValue(value);
+            }
+
+            @Override
+            protected boolean matchesSafely(Annotation item) {
+                return value.equals(item.value);
+            }
+        });
+    }
+    
+    public static IsAnnotationContaining hasItem(final String value) {
+        return new IsAnnotationContaining(value);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsBinaryAnnotationContaining.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsBinaryAnnotationContaining.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsBinaryAnnotationContaining.java
new file mode 100644
index 0000000..c9ed3fa
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/IsBinaryAnnotationContaining.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs.tracing.brave;
+
+import java.nio.charset.StandardCharsets;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.core.IsCollectionContaining;
+
+import zipkin.BinaryAnnotation;
+
+public class IsBinaryAnnotationContaining extends IsCollectionContaining<BinaryAnnotation> {
+    public IsBinaryAnnotationContaining(final String key, final String value) {
+        super(new TypeSafeMatcher<BinaryAnnotation>() {
+            @Override
+            public void describeTo(Description description) {
+                description
+                    .appendText("the key ")
+                    .appendValue(key)
+                    .appendText(" with value ")
+                    .appendValue(value);
+            }
+
+            @Override
+            protected boolean matchesSafely(BinaryAnnotation item) {
+                return value.equals(new String(item.value, StandardCharsets.UTF_8)) && key.equals(item.key);
+            }
+        });
+    }
+    
+    public static IsBinaryAnnotationContaining hasItem(final String key, final String value) {
+        return new IsBinaryAnnotationContaining(key, value);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingCustomHeadersTest.java
----------------------------------------------------------------------
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 b7c5b32..fae555b 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
@@ -43,6 +43,7 @@ import org.apache.htrace.core.AlwaysSampler;
 import org.apache.htrace.core.HTraceConfiguration;
 import org.apache.htrace.core.SpanId;
 import org.apache.htrace.core.StandardOutSpanReceiver;
+import org.apache.htrace.core.TraceScope;
 import org.apache.htrace.core.Tracer;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -72,7 +73,7 @@ public class HTraceTracingCustomHeadersTest extends AbstractBusClientServerTestB
             
             final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
             sf.setResourceClasses(BookStore.class);
-            sf.setResourceProvider(BookStore.class, new SingletonResourceProvider(new BookStore()));
+            sf.setResourceProvider(BookStore.class, new SingletonResourceProvider(new BookStore<TraceScope>()));
             sf.setAddress("http://localhost:" + PORT);
             sf.setProvider(new JacksonJsonProvider());
             sf.setFeatures(Arrays.asList(new HTraceFeature(HTraceConfiguration.fromMap(properties), "test-tracer")));

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/htrace/HTraceTracingTest.java
----------------------------------------------------------------------
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 d4f84ba..b46b422 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
@@ -70,7 +70,7 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
             
             final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
             sf.setResourceClasses(BookStore.class);
-            sf.setResourceProvider(BookStore.class, new SingletonResourceProvider(new BookStore()));
+            sf.setResourceProvider(BookStore.class, new SingletonResourceProvider(new BookStore<TraceScope>()));
             sf.setAddress("http://localhost:" + PORT);
             sf.setProvider(new JacksonJsonProvider());
             sf.setFeatures(Arrays.asList(new HTraceFeature(HTraceConfiguration.fromMap(properties), "tracer")));


[2/2] cxf git commit: CXF-7164: Support tracing using OpenZipkin Brave. Implemented JAX-RS support.

Posted by re...@apache.org.
CXF-7164: Support tracing using OpenZipkin Brave. Implemented JAX-RS support.


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/c194254d
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/c194254d
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/c194254d

Branch: refs/heads/master
Commit: c194254d62b2d89a58fbd77c287b4bb106caa61d
Parents: 2103bc5
Author: reta <dr...@gmail.com>
Authored: Mon Dec 26 19:28:55 2016 -0500
Committer: reta <dr...@gmail.com>
Committed: Mon Dec 26 19:28:55 2016 -0500

----------------------------------------------------------------------
 .../samples/jax_rs/tracing_brave/README.txt     |  39 +++
 .../samples/jax_rs/tracing_brave/pom.xml        | 136 ++++++++
 .../java/demo/jaxrs/tracing/client/Client.java  |  48 +++
 .../java/demo/jaxrs/tracing/server/Catalog.java | 135 ++++++++
 .../tracing/server/CatalogApplication.java      |  45 +++
 .../demo/jaxrs/tracing/server/CatalogStore.java |  71 ++++
 .../java/demo/jaxrs/tracing/server/Server.java  |  52 +++
 distribution/src/main/release/samples/pom.xml   |   1 +
 integration/pom.xml                             |   1 +
 integration/tracing/tracing-brave/pom.xml       |  72 ++++
 .../brave/AbstractBraveClientProvider.java      | 104 ++++++
 .../tracing/brave/AbstractBraveProvider.java    | 136 ++++++++
 .../cxf/tracing/brave/BraveTracerContext.java   | 109 ++++++
 .../tracing/brave/ClientSpanNameProvider.java   |  39 +++
 .../tracing/brave/ServerSpanNameProvider.java   |  39 +++
 .../apache/cxf/tracing/brave/TraceScope.java    |  43 +++
 .../brave/jaxrs/BraveClientProvider.java        |  60 ++++
 .../brave/jaxrs/BraveContextProvider.java       |  50 +++
 .../cxf/tracing/brave/jaxrs/BraveFeature.java   |  52 +++
 .../cxf/tracing/brave/jaxrs/BraveProvider.java  |  80 +++++
 .../htrace/AbstractHTraceClientProvider.java    |   2 +-
 .../htrace/jaxrs/HTraceClientProvider.java      |   3 +-
 parent/pom.xml                                  |   6 +
 systests/tracing/pom.xml                        |   7 +-
 .../apache/cxf/systest/TestSpanReporter.java    |  42 +++
 .../cxf/systest/jaxrs/tracing/BookStore.java    |   9 +-
 .../jaxrs/tracing/brave/BraveTracingTest.java   | 334 +++++++++++++++++++
 .../tracing/brave/IsAnnotationContaining.java   |  45 +++
 .../brave/IsBinaryAnnotationContaining.java     |  51 +++
 .../htrace/HTraceTracingCustomHeadersTest.java  |   3 +-
 .../jaxrs/tracing/htrace/HTraceTracingTest.java |   2 +-
 31 files changed, 1806 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/jax_rs/tracing_brave/README.txt
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_brave/README.txt b/distribution/src/main/release/samples/jax_rs/tracing_brave/README.txt
new file mode 100644
index 0000000..03ec82a
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/tracing_brave/README.txt
@@ -0,0 +1,39 @@
+JAX-RS HTrace Demo 
+=================
+
+The demo shows a basic usage of HTrace distributed tracer with REST based 
+Web Services using  JAX-RS 2.0 (JSR-339). The REST server provides the 
+following services: 
+
+A RESTful catalog service is provided on URL http://localhost:9000/catalog 
+
+A HTTP GET request to URL http://localhost:9000/catalog generates following 
+traces:
+
+A HTTP POST request to URL http://localhost:9000/catalog generates following 
+traces:
+
+A HTTP GET request to URL http://localhost:9000/catalog/<id> generates following 
+traces:
+
+A HTTP DELETE request to URL http://localhost:9000/catalog/<id> generates following 
+traces:
+
+Building and running the demo using Maven
+---------------------------------------
+
+From the base directory of this sample (i.e., where this README file is
+located), the Maven pom.xml file can be used to build and run the demo. 
+
+
+Using either UNIX or Windows:
+
+  mvn install
+  mvn -Pserver  (from one command line window)
+  mvn -Pclient  (from a second command line window)
+    
+
+To remove the target dir, run mvn clean".
+
+
+

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/jax_rs/tracing_brave/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_brave/pom.xml b/distribution/src/main/release/samples/jax_rs/tracing_brave/pom.xml
new file mode 100644
index 0000000..697060c
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/tracing_brave/pom.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+ 
+  http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>jax_rs_tracing_brave</artifactId>
+    <name>JAX-RS Demo Using Distributed Tracing with OpenZipkin Brave</name>
+    <description>JAX-RS Demo Using Distributed Tracing with OpenZipkin Brave</description>
+    <parent>
+        <groupId>org.apache.cxf.samples</groupId>
+        <artifactId>cxf-samples</artifactId>
+        <version>3.2.0-SNAPSHOT</version>
+        <relativePath>../..</relativePath>
+    </parent>
+    <properties>
+        <cxf.version>${project.version}</cxf.version>
+        <httpclient.version>3.1</httpclient.version>
+    </properties>
+    <profiles>
+        <profile>
+            <id>server</id>
+            <build>
+                <defaultGoal>test</defaultGoal>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>test</phase>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                                <configuration>
+                                    <mainClass>demo.jaxrs.tracing.server.Server</mainClass>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>client</id>
+            <build>
+                <defaultGoal>test</defaultGoal>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>test</phase>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                                <configuration>
+                                    <mainClass>demo.jaxrs.tracing.client.Client</mainClass>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http</artifactId>
+            <version>3.2.0-SNAPSHOT</version>
+        </dependency>
+        <!-- This dependency is needed if you're using the Jetty container -->
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http-jetty</artifactId>
+            <version>3.2.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <version>3.2.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-client</artifactId>
+            <version>3.2.0-SNAPSHOT</version>
+        </dependency>    
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-integration-tracing-brave</artifactId>
+            <version>3.2.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-extension-providers</artifactId>
+            <version>3.2.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.json</groupId>
+            <artifactId>javax.json-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish</groupId>
+            <artifactId>javax.json</artifactId>
+        </dependency>                    
+        <dependency>
+            <groupId>commons-httpclient</groupId>
+            <artifactId>commons-httpclient</artifactId>
+        </dependency>                
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/client/Client.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/client/Client.java b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/client/Client.java
new file mode 100644
index 0000000..f746efe
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/client/Client.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package demo.jaxrs.tracing.client;
+
+import java.util.Arrays;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.tracing.brave.jaxrs.BraveClientProvider;
+
+import com.github.kristofa.brave.Brave;
+
+public final class Client {
+    private Client() {
+    }
+    
+    public static void main(final String[] args) throws Exception {
+        final Brave brave = new Brave.Builder().build();
+        final BraveClientProvider provider = new BraveClientProvider(brave);
+        
+        final Response response = WebClient
+            .create("http://localhost:9000/catalog", Arrays.asList(provider))
+            .accept(MediaType.APPLICATION_JSON)
+            .get();
+        
+        System.out.println(response.readEntity(String.class));
+        response.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Catalog.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Catalog.java b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Catalog.java
new file mode 100644
index 0000000..35110b2
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Catalog.java
@@ -0,0 +1,135 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package demo.jaxrs.tracing.server;
+
+
+import java.io.IOException;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.cxf.tracing.Traceable;
+import org.apache.cxf.tracing.TracerContext;
+
+@Path("/catalog")
+public class Catalog {
+    private final ExecutorService executor = Executors.newFixedThreadPool(2);
+    private final CatalogStore store;
+    
+    public Catalog() {
+        store = new CatalogStore();
+    }
+    
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response addBook(@Context final UriInfo uriInfo, @Context final TracerContext tracing, 
+            @FormParam("title") final String title)  {
+        try {
+            final String id = UUID.randomUUID().toString();
+        
+            executor.submit(
+                tracing.wrap("Inserting New Book", 
+                    new Traceable<Void>() {
+                        public Void call(final TracerContext context) throws Exception {
+                            store.put(id, title);
+                            return null;
+                        }
+                    }
+                )
+            ).get(10, TimeUnit.SECONDS);
+            
+            return Response
+                .created(uriInfo.getRequestUriBuilder().path(id).build())
+                .build();
+        } catch (final Exception ex) {
+            return Response
+                .serverError()
+                .entity(Json
+                     .createObjectBuilder()
+                     .add("error", ex.getMessage())
+                     .build())
+                .build();
+        }
+    }
+    
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public void getBooks(@Suspended final AsyncResponse response, 
+            @Context final TracerContext tracing) throws Exception {
+        tracing.continueSpan(new Traceable<Void>() {
+            @Override
+            public Void call(final TracerContext context) throws Exception {
+                executor.submit(tracing.wrap("Looking for books", new Traceable<Void>() {
+                    @Override
+                    public Void call(final TracerContext context) throws Exception {
+                        response.resume(store.scan());
+                        return null;
+                    }
+                }));
+                
+                return null;
+            }
+        });
+    }
+    
+    @GET
+    @Path("/{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public JsonObject getBook(@PathParam("id") final String id) throws IOException {
+        final JsonObject book = store.get(id);
+        
+        if (book == null) {
+            throw new NotFoundException("Book with does not exists: " + id);
+        }
+        
+        return book;
+    }
+    
+    @DELETE
+    @Path("/{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response delete(@PathParam("id") final String id) throws IOException {
+        if (!store.remove(id)) {
+            throw new NotFoundException("Book with does not exists: " + id);
+        }
+        
+        return Response.ok().build();
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogApplication.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogApplication.java b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogApplication.java
new file mode 100644
index 0000000..b522a41
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogApplication.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package demo.jaxrs.tracing.server;
+
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+import org.apache.cxf.jaxrs.provider.jsrjsonp.JsrJsonpProvider;
+import org.apache.cxf.tracing.brave.jaxrs.BraveFeature;
+
+@ApplicationPath("/")
+public class CatalogApplication extends Application {
+    @Override
+    public Set<Object> getSingletons() {
+        return new HashSet<Object>(
+            Arrays.asList(
+                new Catalog(),
+                new BraveFeature(),
+                new JsrJsonpProvider()
+            )
+        );
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java
new file mode 100644
index 0000000..c102dfc
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package demo.jaxrs.tracing.server;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+
+public class CatalogStore {
+    private final Map<String, String> books = new ConcurrentHashMap<>();
+    
+    public CatalogStore() {
+    }
+    
+    public boolean remove(final String key) throws IOException {
+        return (books.remove(key) != null);
+    }
+    
+    public JsonObject get(final String key) throws IOException {
+        final String title = books.get(key);
+        
+        if (title != null) {
+            return Json.createObjectBuilder()
+                .add("id", key)
+                .add("title", title)
+                .build();
+        }
+
+        return null;
+    }
+    
+    public void put(final String key, final String title) throws IOException {
+        books.put(key, title);
+    }
+    
+    public JsonArray scan() throws IOException {
+        final JsonArrayBuilder builder = Json.createArrayBuilder();
+        
+        for (final Map.Entry<String, String> entry: books.entrySet()) {
+            builder.add(Json.createObjectBuilder()
+                .add("id", entry.getKey())
+                .add("title", entry.getValue())
+            );
+        }
+        
+        return builder.build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Server.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Server.java b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Server.java
new file mode 100644
index 0000000..407300b
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/tracing_brave/src/main/java/demo/jaxrs/tracing/server/Server.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package demo.jaxrs.tracing.server;
+
+import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+public class Server {
+    protected Server() throws Exception {
+        org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server(9000);
+
+        // Register and map the dispatcher servlet
+        final ServletHolder servletHolder = new ServletHolder(new CXFNonSpringJaxrsServlet());
+        final ServletContextHandler context = new ServletContextHandler();      
+        context.setContextPath("/");
+        context.addServlet(servletHolder, "/*");
+        
+        servletHolder.setInitParameter("javax.ws.rs.Application", 
+            CatalogApplication.class.getName());
+
+        server.setHandler(context);
+        server.start();
+        server.join();
+    }
+
+    public static void main(String args[]) throws Exception {
+        new Server();
+        System.out.println("Server ready...");
+
+        Thread.sleep(5 * 6000 * 1000);
+        System.out.println("Server exiting");
+        System.exit(0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/distribution/src/main/release/samples/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/pom.xml b/distribution/src/main/release/samples/pom.xml
index 6dae5e0..4930929 100644
--- a/distribution/src/main/release/samples/pom.xml
+++ b/distribution/src/main/release/samples/pom.xml
@@ -123,6 +123,7 @@
         <module>jax_rs/sse_cdi</module>
         <module>jax_rs/sse_tomcat</module>
         <module>jax_rs/sse_spring</module>
+        <module>jax_rs/tracing_brave</module>
     </modules>
     <dependencyManagement>
         <dependencies>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/pom.xml
----------------------------------------------------------------------
diff --git a/integration/pom.xml b/integration/pom.xml
index 8d81959..6af4286 100644
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -33,6 +33,7 @@
         <module>jca</module>
         <module>cdi</module>
         <module>tracing/tracing-htrace</module>
+        <module>tracing/tracing-brave</module>
         <module>spring-boot</module>
     </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/pom.xml
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/pom.xml b/integration/tracing/tracing-brave/pom.xml
new file mode 100644
index 0000000..b1ad664
--- /dev/null
+++ b/integration/tracing/tracing-brave/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>cxf-integration-tracing-brave</artifactId>
+    <packaging>jar</packaging>
+    <name>Apache CXF Distributed Tracing using OpenZipkin Brave</name>
+    <description>Apache CXF Distributed using OpenZipkin Brave</description>
+    <url>http://cxf.apache.org</url>
+    <parent>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-parent</artifactId>
+        <version>3.2.0-SNAPSHOT</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+    
+    <properties>
+        <cxf.osgi.export>
+            org.apache.cxf.tracing
+        </cxf.osgi.export>
+    </properties>
+    
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <version>${project.version}</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-management</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-http</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveClientProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveClientProvider.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveClientProvider.java
new file mode 100644
index 0000000..e396cda
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveClientProvider.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.http.HttpClientRequest;
+import com.github.kristofa.brave.http.HttpClientRequestAdapter;
+import com.github.kristofa.brave.http.HttpClientResponseAdapter;
+import com.github.kristofa.brave.http.HttpResponse;
+import com.github.kristofa.brave.http.SpanNameProvider;
+import com.twitter.zipkin.gen.Span;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.tracing.AbstractTracingProvider;
+
+public abstract class AbstractBraveClientProvider extends AbstractTracingProvider { 
+    protected static final Logger LOG = LogUtils.getL7dLogger(AbstractBraveClientProvider.class);
+    protected static final String TRACE_SPAN = "org.apache.cxf.tracing.client.brave.span";
+        
+    private final Brave brave;
+    private final SpanNameProvider spanNameProvider;
+        
+    public AbstractBraveClientProvider(final Brave brave) {
+        this.brave = brave;
+        this.spanNameProvider = new ClientSpanNameProvider();
+    }
+
+    protected TraceScopeHolder<Span> startTraceSpan(final Map<String, List<String>> requestHeaders, 
+            URI uri, String method) {
+        final HttpClientRequest request = new HttpClientRequest() {
+            @Override
+            public URI getUri() {
+                return uri;
+            }
+            
+            @Override
+            public String getHttpMethod() {
+                return method;
+            }
+            
+            @Override
+            public void addHeader(String header, String value) {
+                requestHeaders.put(header, Collections.singletonList(value));
+            }
+        };
+        
+        brave.clientRequestInterceptor().handle(new HttpClientRequestAdapter(request, spanNameProvider));
+        final Span span = brave.clientSpanThreadBinder().getCurrentClientSpan();
+        // In case of asynchronous client invocation, the span should be detached as JAX-RS 
+        // client request / response filters are going to be executed in different threads.
+        boolean detached = false;
+        if (isAsyncInvocation() && span != null) {
+            brave.clientSpanThreadBinder().setCurrentSpan(null);
+            detached = true;
+        }
+        
+        return new TraceScopeHolder<Span>(span, detached);
+    }
+    
+    private boolean isAsyncInvocation() {
+        return !JAXRSUtils.getCurrentMessage().getExchange().isSynchronous();
+    }
+
+    protected void stopTraceSpan(final TraceScopeHolder<Span> holder, final int responseStatus) {
+        if (holder == null) {
+            return;
+        }
+        
+        final Span span = holder.getScope();
+        if (span != null) {
+            // If the client invocation was asynchronous , the trace span has been created 
+            // in another thread and should be re-attached to the current one.
+            if (holder.isDetached()) {
+                brave.clientSpanThreadBinder().setCurrentSpan(span);
+            }
+            
+            final HttpResponse response = () -> responseStatus;
+            brave.clientResponseInterceptor().handle(new HttpClientResponseAdapter(response));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveProvider.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..306923f
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/AbstractBraveProvider.java
@@ -0,0 +1,136 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.ServerSpan;
+import com.github.kristofa.brave.http.BraveHttpHeaders;
+import com.github.kristofa.brave.http.HttpResponse;
+import com.github.kristofa.brave.http.HttpServerRequest;
+import com.github.kristofa.brave.http.HttpServerRequestAdapter;
+import com.github.kristofa.brave.http.HttpServerResponseAdapter;
+import com.github.kristofa.brave.http.SpanNameProvider;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.tracing.AbstractTracingProvider;
+
+public abstract class AbstractBraveProvider extends AbstractTracingProvider { 
+    protected static final Logger LOG = LogUtils.getL7dLogger(AbstractBraveProvider.class);
+    protected static final String TRACE_SPAN = "org.apache.cxf.tracing.brave.span";
+        
+    private final Brave brave;
+    private final SpanNameProvider spanNameProvider;
+            
+    public AbstractBraveProvider(final Brave brave) {
+        this.brave = brave;
+        this.spanNameProvider = new ServerSpanNameProvider();
+    }
+
+    protected TraceScopeHolder<ServerSpan> startTraceSpan(final Map<String, List<String>> requestHeaders,
+            URI uri, String method) {
+
+        final HttpServerRequest request = new HttpServerRequest() {
+            @Override
+            public URI getUri() {
+                return uri;
+            }
+            
+            @Override
+            public String getHttpMethod() {
+                return method;
+            }
+            
+            @Override
+            public String getHttpHeaderValue(String headerName) {
+                List<String> value = requestHeaders.get(headerName);
+                
+                if (value != null && !value.isEmpty()) {
+                    return value.get(0);
+                }
+                
+                return null;
+            }
+        };
+        
+        brave.serverRequestInterceptor().handle(new HttpServerRequestAdapter(request, spanNameProvider));
+        final ServerSpan serverSpan = brave.serverSpanThreadBinder().getCurrentServerSpan();
+        
+        // If the service resource is using asynchronous processing mode, the trace
+        // scope will be closed in another thread and as such should be detached.
+        boolean detached = false;
+        if (isAsyncResponse()) {
+            brave.serverSpanThreadBinder().setCurrentSpan(null);
+            propagateContinuationSpan(serverSpan);
+            detached = true;
+        }
+        
+        return new TraceScopeHolder<ServerSpan>(serverSpan, detached);
+    }
+    
+    private void transferRequestHeader(final Map<String, List<String>> requestHeaders,
+            final Map<String, List<Object>> responseHeaders, final BraveHttpHeaders header) {
+        if (requestHeaders.containsKey(header.getName())) {
+            responseHeaders.put(header.getName(), CastUtils.cast(requestHeaders.get(header.getName())));
+        }
+    }
+
+    protected void stopTraceSpan(final Map<String, List<String>> requestHeaders,
+                                 final Map<String, List<Object>> responseHeaders,
+                                 final int responseStatus,
+                                 final TraceScopeHolder<ServerSpan> holder) {
+
+        // Transfer tracing headers into the response headers
+        transferRequestHeader(requestHeaders, responseHeaders, BraveHttpHeaders.SpanId);
+        transferRequestHeader(requestHeaders, responseHeaders, BraveHttpHeaders.Sampled);
+        transferRequestHeader(requestHeaders, responseHeaders, BraveHttpHeaders.ParentSpanId);
+        transferRequestHeader(requestHeaders, responseHeaders, BraveHttpHeaders.TraceId);
+        
+        if (holder == null) {
+            return;
+        }
+        
+        final ServerSpan span = holder.getScope();
+        if (span != null) {
+            // If the service resource is using asynchronous processing mode, the trace
+            // scope has been created in another thread and should be re-attached to the current 
+            // one.
+            if (holder.isDetached()) {
+                brave.serverSpanThreadBinder().setCurrentSpan(span);
+            } 
+            
+            final HttpResponse response = () -> responseStatus;
+            brave.serverResponseInterceptor().handle(new HttpServerResponseAdapter(response));
+        }
+    }
+    
+    private void propagateContinuationSpan(final ServerSpan continuationScope) {
+        JAXRSUtils.getCurrentMessage().put(ServerSpan.class, continuationScope);
+    }
+    
+    protected boolean isAsyncResponse() {
+        return !JAXRSUtils.getCurrentMessage().getExchange().isSynchronous();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveTracerContext.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveTracerContext.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveTracerContext.java
new file mode 100644
index 0000000..044495f
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/BraveTracerContext.java
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave;
+
+import java.util.concurrent.Callable;
+
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.ServerSpan;
+import com.github.kristofa.brave.ServerSpanThreadBinder;
+
+import org.apache.cxf.tracing.Traceable;
+import org.apache.cxf.tracing.TracerContext;
+
+import zipkin.Constants;
+
+public class BraveTracerContext implements TracerContext {
+    private final Brave brave;
+    private final ServerSpan continuationSpan;
+    private final ServerSpanThreadBinder serverSpanThreadBinder;
+    
+    public BraveTracerContext(final Brave brave) {
+        this(brave, null);
+    }
+    
+    public BraveTracerContext(final Brave brave, final ServerSpan continuationSpan) {
+        this.brave = brave;
+        this.continuationSpan = continuationSpan;
+        this.serverSpanThreadBinder = brave.serverSpanThreadBinder();
+    }
+    
+    @Override
+    @SuppressWarnings("unchecked")
+    public TraceScope startSpan(final String description) {
+        return new TraceScope(brave, 
+            brave
+                .localTracer()
+                .startNewSpan(Constants.LOCAL_COMPONENT, description));
+    }
+    
+    @Override
+    public <T> T continueSpan(final Traceable<T> traceable) throws Exception {
+        boolean attached = false;
+        if (serverSpanThreadBinder.getCurrentServerSpan() != null && continuationSpan != null) {
+            serverSpanThreadBinder.setCurrentSpan(continuationSpan);
+            attached = true;
+        }
+        
+        try {
+            return traceable.call(new BraveTracerContext(brave));
+        } finally {
+            if (continuationSpan != null && attached) {
+                serverSpanThreadBinder.setCurrentSpan(null);
+            }
+        }
+    }
+    
+    @Override
+    public <T> Callable<T> wrap(final String description, final Traceable<T> traceable) {
+        final Callable<T> callable = new Callable<T>() {
+            @Override
+            public T call() throws Exception {
+                return traceable.call(new BraveTracerContext(brave));
+            }
+        };
+        
+        return () -> {
+            try {
+                startSpan(description);
+                return callable.call();
+            } finally {
+                brave.localTracer().finishSpan();
+            }
+        };
+    }
+    
+    @Override
+    public void annotate(String key, String value) {
+        if (brave.localSpanThreadBinder().getCurrentLocalSpan() != null) {
+            brave.localTracer().submitBinaryAnnotation(key, value);
+        } else if (brave.serverSpanThreadBinder().getCurrentServerSpan() != null) {
+            brave.serverTracer().submitBinaryAnnotation(key, value);
+        }
+    }
+    
+    @Override
+    public void timeline(String message) {
+        if (brave.localSpanThreadBinder().getCurrentLocalSpan() != null) {
+            brave.localTracer().submitAnnotation(message);
+        } else if (brave.serverSpanThreadBinder().getCurrentServerSpan() != null) {
+            brave.serverTracer().submitAnnotation(message);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ClientSpanNameProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ClientSpanNameProvider.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ClientSpanNameProvider.java
new file mode 100644
index 0000000..f0927f2
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ClientSpanNameProvider.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave;
+
+import com.github.kristofa.brave.http.HttpRequest;
+import com.github.kristofa.brave.http.SpanNameProvider;
+
+import org.apache.cxf.common.util.StringUtils;
+
+public class ClientSpanNameProvider implements SpanNameProvider {
+    @Override
+    public String spanName(HttpRequest request) {
+        return buildSpanDescription(request.getUri().toString(), request.getHttpMethod());
+    }
+    
+    private String buildSpanDescription(final String path, final String method) {
+        if (StringUtils.isEmpty(method)) {
+            return path;
+        } else {
+            return method + " " + path;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ServerSpanNameProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ServerSpanNameProvider.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ServerSpanNameProvider.java
new file mode 100644
index 0000000..73a665e
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/ServerSpanNameProvider.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave;
+
+import com.github.kristofa.brave.http.HttpRequest;
+import com.github.kristofa.brave.http.SpanNameProvider;
+
+import org.apache.cxf.common.util.StringUtils;
+
+public class ServerSpanNameProvider implements SpanNameProvider {
+    @Override
+    public String spanName(HttpRequest request) {
+        return buildSpanDescription(request.getUri().getPath(), request.getHttpMethod());
+    }
+    
+    private String buildSpanDescription(final String path, final String method) {
+        if (StringUtils.isEmpty(method)) {
+            return path;
+        } else {
+            return method + " " + path;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/TraceScope.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/TraceScope.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/TraceScope.java
new file mode 100644
index 0000000..32f0f59
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/TraceScope.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave;
+
+import java.io.Closeable;
+
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.SpanId;
+import com.twitter.zipkin.gen.Span;
+
+public class TraceScope implements Closeable {
+    final Brave brave;
+    final SpanId spanId;
+    
+    TraceScope(final Brave brave, final SpanId spanId) {
+        this.brave = brave;
+        this.spanId = spanId;
+    }
+    
+    @Override
+    public void close() {
+        final Span span = brave.localSpanThreadBinder().getCurrentLocalSpan(); 
+        if (span != null && span.getTrace_id() == spanId.traceId && span.getId() == spanId.spanId) {
+            brave.localTracer().finishSpan();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveClientProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveClientProvider.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveClientProvider.java
new file mode 100644
index 0000000..1d384ec
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveClientProvider.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave.jaxrs;
+
+import java.io.IOException;
+
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.ext.Provider;
+
+import com.github.kristofa.brave.Brave;
+import com.twitter.zipkin.gen.Span;
+
+import org.apache.cxf.tracing.brave.AbstractBraveClientProvider;
+
+@Provider
+public class BraveClientProvider extends AbstractBraveClientProvider 
+        implements ClientRequestFilter, ClientResponseFilter {
+    
+    public BraveClientProvider(final Brave brave) {
+        super(brave);
+    }
+
+    @Override
+    public void filter(final ClientRequestContext requestContext) throws IOException {
+        final TraceScopeHolder<Span> holder = super.startTraceSpan(requestContext.getStringHeaders(), 
+            requestContext.getUri(), requestContext.getMethod());
+
+        if (holder != null) {
+            requestContext.setProperty(TRACE_SPAN, holder);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public void filter(final ClientRequestContext requestContext,
+            final ClientResponseContext responseContext) throws IOException {
+        final TraceScopeHolder<Span> holder = 
+            (TraceScopeHolder<Span>)requestContext.getProperty(TRACE_SPAN);
+        super.stopTraceSpan(holder, responseContext.getStatus());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveContextProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveContextProvider.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveContextProvider.java
new file mode 100644
index 0000000..d75fa9d
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveContextProvider.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave.jaxrs;
+
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.ServerSpan;
+
+import org.apache.cxf.jaxrs.ext.ContextProvider;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.tracing.TracerContext;
+import org.apache.cxf.tracing.brave.BraveTracerContext;
+
+public class BraveContextProvider implements ContextProvider< TracerContext > {
+    private final Brave brave;
+    
+    public BraveContextProvider(final Brave brave) {
+        this.brave = brave;
+    }
+
+    @Override
+    public TracerContext createContext(final Message message) {
+        // Check if there is a server span passed along with the message
+        final ServerSpan continuationSpan = message.get(ServerSpan.class);
+        
+        // If server span is already present, let us check if it is detached 
+        // (asynchronous invocation)
+        if (continuationSpan != null) {
+            return new BraveTracerContext(brave, continuationSpan);
+        }
+        
+        return new BraveTracerContext(brave);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveFeature.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveFeature.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveFeature.java
new file mode 100644
index 0000000..b6bcbc8
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveFeature.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave.jaxrs;
+
+import java.util.Arrays;
+
+import com.github.kristofa.brave.Brave;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.feature.AbstractFeature;
+import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
+
+public class BraveFeature extends AbstractFeature {
+    private final Brave brave;
+    
+    public BraveFeature() {
+        this(new Brave.Builder().build());
+    }
+
+    public BraveFeature(final Brave brave) {
+        this.brave = brave;
+    }
+
+    @Override
+    public void initialize(final Server server, final Bus bus) {
+        final ServerProviderFactory providerFactory = (ServerProviderFactory)server
+            .getEndpoint()
+            .get(ServerProviderFactory.class.getName());
+        
+        if (providerFactory != null) {
+            providerFactory.setUserProviders(Arrays.asList(new BraveProvider(brave), 
+                new BraveContextProvider(brave)));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveProvider.java b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveProvider.java
new file mode 100644
index 0000000..cfd917a
--- /dev/null
+++ b/integration/tracing/tracing-brave/src/main/java/org/apache/cxf/tracing/brave/jaxrs/BraveProvider.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.tracing.brave.jaxrs;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Provider;
+
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.ServerSpan;
+
+import org.apache.cxf.tracing.brave.AbstractBraveProvider;
+
+@Provider
+public class BraveProvider extends AbstractBraveProvider 
+    implements ContainerRequestFilter, ContainerResponseFilter {
+    @Context 
+    private ResourceInfo resourceInfo;
+    
+    public BraveProvider(final Brave brave) {
+        super(brave);
+    }
+
+    @Override
+    public void filter(final ContainerRequestContext requestContext) throws IOException {
+        final TraceScopeHolder<ServerSpan> holder = super.startTraceSpan(requestContext.getHeaders(), 
+                                                requestContext.getUriInfo().getRequestUri(),
+                                                requestContext.getMethod());
+        
+        if (holder != null) {
+            requestContext.setProperty(TRACE_SPAN, holder);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public void filter(final ContainerRequestContext requestContext,
+            final ContainerResponseContext responseContext) throws IOException {
+        super.stopTraceSpan(requestContext.getHeaders(), 
+                            responseContext.getHeaders(), 
+                            responseContext.getStatus(),
+                            (TraceScopeHolder<ServerSpan>)requestContext.getProperty(TRACE_SPAN));
+    }
+    
+    @Override
+    protected boolean isAsyncResponse() {
+        for (final Annotation[] annotations: resourceInfo.getResourceMethod().getParameterAnnotations()) {
+            for (final Annotation annotation: annotations) {
+                if (annotation.annotationType().equals(Suspended.class)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceClientProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceClientProvider.java b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceClientProvider.java
index 65aca86..5d6e2ac 100644
--- a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceClientProvider.java
+++ b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceClientProvider.java
@@ -32,7 +32,7 @@ import org.apache.htrace.core.Tracer;
 
 public abstract class AbstractHTraceClientProvider extends AbstractTracingProvider { 
     protected static final Logger LOG = LogUtils.getL7dLogger(AbstractHTraceClientProvider.class);
-    protected static final String TRACE_SPAN = "org.apache.cxf.tracing.htrace.span";
+    protected static final String TRACE_SPAN = "org.apache.cxf.tracing.client.htrace.span";
         
     private final Tracer tracer;
         

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceClientProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceClientProvider.java b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceClientProvider.java
index 0e4b5b8..0c7c238 100644
--- a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceClientProvider.java
+++ b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceClientProvider.java
@@ -33,8 +33,7 @@ import org.apache.htrace.core.Tracer;
 @Provider
 public class HTraceClientProvider extends AbstractHTraceClientProvider 
         implements ClientRequestFilter, ClientResponseFilter {
-    private static final String TRACE_SPAN = "org.apache.cxf.tracing.client.htrace.span";
-    
+
     public HTraceClientProvider(final Tracer tracer) {
         super(tracer);
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index e1c305b..038a076 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -210,6 +210,7 @@
         <cxf.jexl.version>2.1.1</cxf.jexl.version>
         <cxf.htrace.version>4.0.1-incubating</cxf.htrace.version>
         <cxf.zest.version>2.1</cxf.zest.version>
+        <cxf.brave.version>3.16.0</cxf.brave.version>
         <cxf.checkstyle.extension />
         <cxf.jaxb.context.class />
         <cxf.jaxb.context.class.property>none</cxf.jaxb.context.class.property>
@@ -1919,6 +1920,11 @@
                 <version>${cxf.htrace.version}</version>
             </dependency>
             <dependency>
+                 <groupId>io.zipkin.brave</groupId>
+                 <artifactId>brave-http</artifactId>
+                 <version>${cxf.brave.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.qi4j.library</groupId>
                 <artifactId>org.qi4j.library.circuitbreaker</artifactId>
                 <version>${cxf.zest.version}</version>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/pom.xml
----------------------------------------------------------------------
diff --git a/systests/tracing/pom.xml b/systests/tracing/pom.xml
index 945a600..6028f38 100644
--- a/systests/tracing/pom.xml
+++ b/systests/tracing/pom.xml
@@ -82,7 +82,12 @@
             <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-integration-tracing-htrace</artifactId>
             <version>${project.version}</version>
-        </dependency>                
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-integration-tracing-brave</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-testutils</artifactId>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReporter.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReporter.java b/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReporter.java
new file mode 100644
index 0000000..a5cd1f6
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReporter.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import zipkin.Span;
+import zipkin.reporter.Reporter;
+
+public class TestSpanReporter implements Reporter<Span> {
+    private static List<Span> spans = new ArrayList<>();
+
+    @Override
+    public void report(Span span) {
+        spans.add(span);
+    }
+
+    public static List<Span> getAllSpans() {
+        return spans;
+    }
+    
+    public static void clear() {
+        spans.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/BookStore.java
----------------------------------------------------------------------
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 0c7f691..d05ec48 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
@@ -18,6 +18,8 @@
  */
 package org.apache.cxf.systest.jaxrs.tracing;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.UUID;
@@ -39,18 +41,17 @@ import javax.ws.rs.core.Response;
 import org.apache.cxf.systest.Book;
 import org.apache.cxf.tracing.Traceable;
 import org.apache.cxf.tracing.TracerContext;
-import org.apache.htrace.core.TraceScope;
 
 @Path("/bookstore/")
-public class BookStore {
+public class BookStore<T extends Closeable> {
     @Context private TracerContext tracer;
     private ExecutorService executor = Executors.newSingleThreadExecutor();
         
     @GET
     @Path("/books")
     @Produces(MediaType.APPLICATION_JSON)
-    public Collection< Book > getBooks() {
-        try (TraceScope span =  tracer.startSpan("Get Books")) {
+    public Collection< Book > getBooks() throws IOException {
+        try (T span =  tracer.startSpan("Get Books")) {
             return Arrays.asList(
                 new Book("Apache CXF in Action", UUID.randomUUID().toString()),
                 new Book("Mastering Apache CXF", UUID.randomUUID().toString())

http://git-wip-us.apache.org/repos/asf/cxf/blob/c194254d/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..f1f1ab7
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java
@@ -0,0 +1,334 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs.tracing.brave;
+
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.SpanId;
+import com.github.kristofa.brave.http.BraveHttpHeaders;
+
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+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.TestSpanReporter;
+import org.apache.cxf.systest.jaxrs.tracing.BookStore;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.cxf.tracing.brave.TraceScope;
+import org.apache.cxf.tracing.brave.jaxrs.BraveClientProvider;
+import org.apache.cxf.tracing.brave.jaxrs.BraveFeature;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.cxf.systest.jaxrs.tracing.brave.IsAnnotationContaining.hasItem;
+import static org.apache.cxf.systest.jaxrs.tracing.brave.IsBinaryAnnotationContaining.hasItem;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import zipkin.Constants;
+
+public class BraveTracingTest extends AbstractBusClientServerTestBase {
+    public static final String PORT = allocatePort(BraveTracingTest.class);
+    
+    private Brave brave;
+    private BraveClientProvider braveClientProvider;
+    private Random random;
+
+    @Ignore
+    public static class Server extends AbstractBusTestServerBase {
+        protected void run() {
+            final Brave brave = new Brave.Builder().reporter(new TestSpanReporter()).build();
+            final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+            sf.setResourceClasses(BookStore.class);
+            sf.setResourceProvider(BookStore.class, new SingletonResourceProvider(new BookStore<TraceScope>()));
+            sf.setAddress("http://localhost:" + PORT);
+            sf.setProvider(new JacksonJsonProvider());
+            sf.setFeatures(Arrays.asList(new BraveFeature(brave)));
+            sf.create();
+        }
+    }
+    
+    @BeforeClass
+    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(Server.class, true));
+        createStaticBus();
+    }
+    
+    @Before
+    public void setUp() {
+        TestSpanReporter.clear();
+        
+        brave = new Brave.Builder().reporter(new TestSpanReporter()).build();
+        braveClientProvider = new BraveClientProvider(brave);
+        random = new Random();
+    }
+    
+    @Test
+    public void testThatNewSpanIsCreatedWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        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"));
+        
+        assertFalse(r.getHeaders().containsKey(BraveHttpHeaders.SpanId.getName()));
+        assertFalse(r.getHeaders().containsKey(BraveHttpHeaders.TraceId.getName()));
+        assertFalse(r.getHeaders().containsKey(BraveHttpHeaders.Sampled.getName()));
+        assertFalse(r.getHeaders().containsKey(BraveHttpHeaders.ParentSpanId.getName()));
+    }
+    
+    @Test
+    public void testThatNewInnerSpanIsCreated() {
+        final SpanId spanId = fromRandom();
+        
+        final Response r = withTrace(createWebClient("/bookstore/books"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        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
+    public void testThatCurrentSpanIsAnnotatedWithKeyValue() {
+        final SpanId spanId = fromRandom();
+        
+        final Response r = withTrace(createWebClient("/bookstore/book/1"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name, equalTo("get /bookstore/book/1"));
+        assertThat(TestSpanReporter.getAllSpans().get(0).binaryAnnotations, hasItem("book-id", "1"));
+        
+        assertThatTraceIsPresent(r, spanId);
+    }
+    
+    @Test
+    public void testThatParallelSpanIsAnnotatedWithTimeline() {
+        final SpanId spanId = fromRandom();
+        
+        final Response r = withTrace(createWebClient("/bookstore/process"), spanId).put("");
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name, equalTo("processing books"));
+        assertThat(TestSpanReporter.getAllSpans().get(0).annotations, hasItem("Processing started"));
+        assertThat(TestSpanReporter.getAllSpans().get(1).name, equalTo("put /bookstore/process"));
+        
+        assertThatTraceIsPresent(r, spanId);
+    }
+    
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvided() {
+        final Response r = createWebClient("/bookstore/books", braveClientProvider).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        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
+    public void testThatNewInnerSpanIsCreatedUsingAsyncInvocation() {
+        final SpanId spanId = fromRandom();
+        
+        final Response r = withTrace(createWebClient("/bookstore/books/async"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
+        assertThat(TestSpanReporter.getAllSpans().get(1).name, equalTo("get /bookstore/books/async"));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name, equalTo("processing books"));
+        
+        assertThatTraceIsPresent(r, spanId);
+    }
+    
+    @Test
+    public void testThatOuterSpanIsCreatedUsingAsyncInvocation() {
+        final SpanId spanId = fromRandom();
+        
+        final Response r = withTrace(createWebClient("/bookstore/books/async/notrace"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name, equalTo("get /bookstore/books/async/notrace"));
+        
+        assertThatTraceIsPresent(r, spanId);
+    }
+    
+    @Test
+    public void testThatNewSpanIsCreatedUsingAsyncInvocation() {
+        final Response r = createWebClient("/bookstore/books/async").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(2));
+        assertThat(TestSpanReporter.getAllSpans().get(1).name, equalTo("get /bookstore/books/async"));
+        assertThat(TestSpanReporter.getAllSpans().get(0).name, equalTo("processing books"));
+    }
+    
+    @Test
+    public void testThatNewSpanIsCreatedWhenNotProvidedUsingAsyncClient() throws Exception {
+        final WebClient client = createWebClient("/bookstore/books", braveClientProvider);
+        final Future<Response> f = client.async().get();
+        
+        final Response r = f.get(1, TimeUnit.SECONDS);
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(3));
+        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
+    public void testThatProvidedSpanIsNotClosedWhenActive() throws MalformedURLException {
+        final WebClient client = createWebClient("/bookstore/books", braveClientProvider);
+        
+        try {
+            brave.localTracer().startNewSpan(Constants.LOCAL_COMPONENT, "test span");
+        
+            final Response r = client.get();
+            assertEquals(Status.OK.getStatusCode(), r.getStatus());
+            
+            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("get /bookstore/books"));
+            assertThat(TestSpanReporter.getAllSpans().get(2).name, equalTo("get " + client.getCurrentURI()));
+            
+            assertThatTraceHeadersArePresent(r, true);
+        } finally {
+            brave.localTracer().finishSpan();
+        }
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(4));
+        assertThat(TestSpanReporter.getAllSpans().get(3).name, equalTo("test span"));
+    }
+    
+    @Test
+    public void testThatProvidedSpanIsNotDetachedWhenActiveUsingAsyncClient() throws Exception {
+        final WebClient client = createWebClient("/bookstore/books", braveClientProvider);
+        
+        try {
+            final SpanId spanId = brave.localTracer().startNewSpan(Constants.LOCAL_COMPONENT, "test span");
+            final Future<Response> f = client.async().get();
+        
+            final Response r = f.get(1, TimeUnit.SECONDS);
+            assertEquals(Status.OK.getStatusCode(), r.getStatus());
+            assertThat(brave.localSpanThreadBinder().getCurrentLocalSpan().getId(), equalTo(spanId.spanId));
+            
+            assertThat(TestSpanReporter.getAllSpans().size(), equalTo(3));
+            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 {
+            brave.localTracer().finishSpan();
+        }
+        
+        assertThat(TestSpanReporter.getAllSpans().size(), equalTo(4));
+        assertThat(TestSpanReporter.getAllSpans().get(3).name, equalTo("test span"));
+    }
+    
+    @Test
+    public void testThatInnerSpanIsCreatedUsingPseudoAsyncInvocation() {
+        final SpanId spanId = fromRandom();
+        
+        final Response r = withTrace(createWebClient("/bookstore/books/pseudo-async"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        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);
+    }
+    
+    protected WebClient createWebClient(final String url, final Object ... providers) {
+        return WebClient
+            .create("http://localhost:" + PORT + url, Arrays.asList(providers))
+            .accept(MediaType.APPLICATION_JSON);
+    }
+    
+    protected WebClient withTrace(final WebClient client, final SpanId spanId) {
+        return client
+            .header(BraveHttpHeaders.SpanId.getName(), spanId.spanId)
+            .header(BraveHttpHeaders.TraceId.getName(), spanId.traceId)
+            .header(BraveHttpHeaders.Sampled.getName(), spanId.sampled())
+            .header(BraveHttpHeaders.ParentSpanId.getName(), spanId.parentId);
+    }
+
+    private void assertThatTraceIsPresent(final Response r, final SpanId spanId) {
+        assertThat((String)r.getHeaders().getFirst(BraveHttpHeaders.SpanId.getName()), 
+            equalTo(Long.toString(spanId.spanId)));
+        assertThat((String)r.getHeaders().getFirst(BraveHttpHeaders.TraceId.getName()), 
+            equalTo(Long.toString(spanId.traceId)));
+        assertThat((String)r.getHeaders().getFirst(BraveHttpHeaders.Sampled.getName()), 
+            equalTo(Boolean.toString(spanId.sampled())));
+        assertThat((String)r.getHeaders().getFirst(BraveHttpHeaders.ParentSpanId.getName()), 
+            equalTo(Long.toString(spanId.parentId)));
+    }
+    
+    private void assertThatTraceHeadersArePresent(final Response r, final boolean expectParent) {
+        assertTrue(r.getHeaders().containsKey(BraveHttpHeaders.SpanId.getName()));
+        assertTrue(r.getHeaders().containsKey(BraveHttpHeaders.TraceId.getName()));
+        assertTrue(r.getHeaders().containsKey(BraveHttpHeaders.Sampled.getName()));
+        
+        if (expectParent) {
+            assertTrue(r.getHeaders().containsKey(BraveHttpHeaders.ParentSpanId.getName()));
+        } else {
+            assertFalse(r.getHeaders().containsKey(BraveHttpHeaders.ParentSpanId.getName()));
+        }
+            
+    }
+
+    private SpanId fromRandom() {
+        final SpanId spanId = SpanId
+            .builder()
+            .traceId(random.nextLong())
+            .parentId(random.nextLong())
+            .spanId(random.nextLong())
+            .sampled(true)
+            .build();
+        return spanId;
+    }
+}