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 2015/08/30 23:58:28 UTC

cxf git commit: CXF-6360: Integration with Apache HTrace. Implemented asynchronous invocation support using HTrace's continueSpan

Repository: cxf
Updated Branches:
  refs/heads/master 3261d7ddf -> a7cc783a5


CXF-6360: Integration with Apache HTrace. Implemented asynchronous invocation support using HTrace's continueSpan


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

Branch: refs/heads/master
Commit: a7cc783a5036e2900a22290738f6aa76d9fcf271
Parents: 3261d7d
Author: reta <dr...@gmail.com>
Authored: Sun Aug 30 17:58:05 2015 -0400
Committer: reta <dr...@gmail.com>
Committed: Sun Aug 30 17:58:05 2015 -0400

----------------------------------------------------------------------
 .../java/demo/jaxrs/tracing/server/Catalog.java | 21 +++++-----
 .../demo/jaxrs/tracing/server/CatalogStore.java |  4 --
 .../tracing/htrace/AbstractHTraceProvider.java  |  9 ++++-
 .../cxf/tracing/htrace/HTraceTracerContext.java | 26 +++++++++++-
 .../htrace/jaxrs/HTraceContextProvider.java     | 10 +++++
 .../org/apache/cxf/tracing/TracerContext.java   |  2 +
 .../cxf/systest/jaxrs/tracing/BookStore.java    | 42 +++++++++++++++++---
 .../jaxrs/tracing/htrace/HTraceTracingTest.java | 21 +++++++++-
 8 files changed, 112 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/Catalog.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/Catalog.java b/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/Catalog.java
index d761d1a..105c53e 100644
--- a/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/Catalog.java
+++ b/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/Catalog.java
@@ -22,7 +22,6 @@ package demo.jaxrs.tracing.server;
 
 import java.io.IOException;
 import java.util.UUID;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
@@ -48,9 +47,6 @@ import org.apache.cxf.tracing.Traceable;
 import org.apache.cxf.tracing.TracerContext;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseConfiguration;
-import org.apache.hadoop.hbase.trace.SpanReceiverHost;
-
-import demo.jaxrs.tracing.conf.TracingConfiguration;
 
 @Path("/catalog")
 public class Catalog {
@@ -61,7 +57,6 @@ public class Catalog {
         final Configuration configuration = HBaseConfiguration.create();
         configuration.set("hbase.zookeeper.quorum", "hbase");
         configuration.set("hbase.zookeeper.property.clientPort", "2181");
-        configuration.set(SpanReceiverHost.SPAN_RECEIVERS_CONF_KEY, TracingConfiguration.SPAN_RECEIVER.getName());
         store = new CatalogStore(configuration, "catalog");
     }
     
@@ -99,11 +94,19 @@ public class Catalog {
     
     @GET
     @Produces(MediaType.APPLICATION_JSON)
-    public void getBooks(@Suspended final AsyncResponse response) throws IOException {
-        executor.submit(new Callable<Void>() {
+    public void getBooks(@Suspended final AsyncResponse response, 
+            @Context final TracerContext tracing) throws Exception {
+        tracing.continueSpan(new Traceable<Void>() {
             @Override
-            public Void call() throws Exception {
-                response.resume(store.scan());
+            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;
             }
         });

http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java b/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java
index 060cbbb..6a37e13 100644
--- a/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java
+++ b/distribution/src/main/release/samples/jax_rs/tracing_htrace/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java
@@ -39,18 +39,14 @@ import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.client.Table;
-import org.apache.hadoop.hbase.trace.SpanReceiverHost;
 import org.apache.hadoop.hbase.util.Bytes;
 
 public class CatalogStore {
-    @SuppressWarnings("unused")
-    private final SpanReceiverHost spanReceiverHost;
     private final Connection connection;
     private final String tableName;
     
     public CatalogStore(final Configuration configuration, final String tableName) throws IOException {
         this.connection = ConnectionFactory.createConnection(configuration);
-        this.spanReceiverHost = SpanReceiverHost.getInstance(configuration);
         this.tableName = tableName;
     }
     

http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java
index 8f397a7..380d97b 100644
--- a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java
+++ b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/AbstractHTraceProvider.java
@@ -28,6 +28,7 @@ import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.tracing.AbstractTracingProvider;
 import org.apache.htrace.Sampler;
+import org.apache.htrace.Span;
 import org.apache.htrace.Trace;
 import org.apache.htrace.TraceInfo;
 import org.apache.htrace.TraceScope;
@@ -69,12 +70,12 @@ public abstract class AbstractHTraceProvider extends AbstractTracingProvider {
         // If the service resource is using asynchronous processing mode, the trace
         // scope will be closed in another thread and as such should be detached.
         if (isAsyncResponse()) {
-            traceScope.detach();
+            propagateContinuationSpan(traceScope.detach());
         }
         
         return traceScope;
     }
-    
+
     protected void stopTraceSpan(final Map<String, List<String>> requestHeaders,
                                  final Map<String, List<Object>> responseHeaders,
                                  final TraceScope span) {
@@ -100,6 +101,10 @@ public abstract class AbstractHTraceProvider extends AbstractTracingProvider {
         }
     }
     
+    private void propagateContinuationSpan(final Span continuationSpan) {
+        JAXRSUtils.getCurrentMessage().put(Span.class, continuationSpan);
+    }
+    
     protected boolean isAsyncResponse() {
         return !JAXRSUtils.getCurrentMessage().getExchange().isSynchronous();
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/HTraceTracerContext.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/HTraceTracerContext.java b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/HTraceTracerContext.java
index 2e92435..9b97741 100644
--- a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/HTraceTracerContext.java
+++ b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/HTraceTracerContext.java
@@ -24,15 +24,22 @@ import java.util.concurrent.Callable;
 import org.apache.cxf.tracing.Traceable;
 import org.apache.cxf.tracing.TracerContext;
 import org.apache.htrace.Sampler;
+import org.apache.htrace.Span;
 import org.apache.htrace.Trace;
 import org.apache.htrace.TraceScope;
 import org.apache.htrace.wrappers.TraceCallable;
 
 public class HTraceTracerContext implements TracerContext {
     private final Sampler< ? > sampler;
-    
+    private final Span continuationSpan;
+
     public HTraceTracerContext(final Sampler< ? > sampler) {
+        this(sampler, null);
+    }
+
+    public HTraceTracerContext(final Sampler< ? > sampler, final Span continuationSpan) {
         this.sampler = sampler;
+        this.continuationSpan = continuationSpan;
     }
         
     @Override
@@ -42,6 +49,23 @@ public class HTraceTracerContext implements TracerContext {
     }
     
     @Override
+    public <T> T continueSpan(final Traceable<T> traceable) throws Exception {
+        TraceScope continueSpan = null;
+        
+        if (!Trace.isTracing() && continuationSpan != null) {
+            continueSpan = Trace.continueSpan(continuationSpan);
+        }
+        
+        try {
+            return traceable.call(new HTraceTracerContext(sampler));
+        } finally {
+            if (continueSpan != null) {
+                continueSpan.close();
+            }
+        }
+    }
+    
+    @Override
     public <T> Callable<T> wrap(final String desription, final Traceable<T> traceable) {
         final Callable<T> callable = new Callable<T>() {
             @Override

http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceContextProvider.java
----------------------------------------------------------------------
diff --git a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceContextProvider.java b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceContextProvider.java
index 453f0d4..b2f122e 100644
--- a/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceContextProvider.java
+++ b/integration/tracing/tracing-htrace/src/main/java/org/apache/cxf/tracing/htrace/jaxrs/HTraceContextProvider.java
@@ -25,6 +25,7 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.tracing.TracerContext;
 import org.apache.cxf.tracing.htrace.HTraceTracerContext;
 import org.apache.htrace.Sampler;
+import org.apache.htrace.Span;
 import org.apache.htrace.impl.NeverSampler;
 
 @Provider
@@ -37,6 +38,15 @@ public class HTraceContextProvider implements ContextProvider< TracerContext > {
 
     @Override
     public TracerContext createContext(final Message message) {
+        // Check if there is a trace scope passed along with the message
+        final Span continuationSpan = message.get(Span.class);
+        
+        // If trace scope is already present, let us check if it is detached 
+        // (asynchronous invocation)
+        if (continuationSpan != null) {
+            return new HTraceTracerContext(sampler, continuationSpan);
+        }
+        
         return new HTraceTracerContext(sampler);
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/rt/management/src/main/java/org/apache/cxf/tracing/TracerContext.java
----------------------------------------------------------------------
diff --git a/rt/management/src/main/java/org/apache/cxf/tracing/TracerContext.java b/rt/management/src/main/java/org/apache/cxf/tracing/TracerContext.java
index 9ab9f58..325527c 100644
--- a/rt/management/src/main/java/org/apache/cxf/tracing/TracerContext.java
+++ b/rt/management/src/main/java/org/apache/cxf/tracing/TracerContext.java
@@ -21,6 +21,8 @@ package org.apache.cxf.tracing;
 import java.util.concurrent.Callable;
 
 public interface TracerContext {
+    <T> T continueSpan(final Traceable<T> traceable) throws Exception;
+    
     <T> T startSpan(final String desription);
     <T> Callable<T> wrap(final String desription, final Traceable<T> traceable);
     

http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/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 186b364..c88d4ba 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
@@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxrs.tracing;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.UUID;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -59,13 +60,44 @@ public class BookStore {
     @GET
     @Path("/books/async")
     @Produces(MediaType.APPLICATION_JSON)
-    public void getBooksAsync(@Suspended final AsyncResponse response) {
+    public void getBooksAsync(@Suspended final AsyncResponse response) throws Exception {
+        tracer.continueSpan(new Traceable<Void>() {
+            @Override
+            public Void call(final TracerContext context) throws Exception {
+                executor.submit(
+                    tracer.wrap("Processing books", new Traceable<Void>() {
+                        @Override
+                        public Void call(final TracerContext context) throws Exception {
+                            // Simulate some running job 
+                            Thread.sleep(200);
+                            
+                            response.resume(
+                                Arrays.asList(
+                                    new Book("Apache CXF in Action", UUID.randomUUID().toString()),
+                                    new Book("Mastering Apache CXF", UUID.randomUUID().toString())
+                                )
+                            );
+                            
+                            return null;
+                        }
+                    }
+                ));
+                
+                return null;
+            }
+        });
+    }
+    
+    @GET
+    @Path("/books/async/notrace")
+    @Produces(MediaType.APPLICATION_JSON)
+    public void getBooksAsyncNoTrace(@Suspended final AsyncResponse response) throws Exception {
         executor.submit(
-            tracer.wrap("Processing books", new Traceable<Void>() {
+            new Callable<Void>() {
                 @Override
-                public Void call(final TracerContext context) throws Exception {
+                public Void call() throws Exception {
                     // Simulate some running job 
-                    Thread.sleep(100);
+                    Thread.sleep(200);
                     
                     response.resume(
                         Arrays.asList(
@@ -76,7 +108,7 @@ public class BookStore {
                     
                     return null;
                 }
-            })
+            }
         );
     }
     

http://git-wip-us.apache.org/repos/asf/cxf/blob/a7cc783a/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 35938a4..75efad5 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
@@ -168,8 +168,24 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
             .get();
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
         
-        assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("bookstore/books/async"));
+        assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("Processing books"));
+        
+        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_TRACE_ID), equalTo("10"));
+        assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo("20"));
+    }
+    
+    @Test
+    public void testThatOuterSpanIsCreatedUsingAsyncInvocation() {
+        final Response r = createWebClient("/bookstore/books/async/notrace")
+            .header(TracerHeaders.DEFAULT_HEADER_TRACE_ID, 10L)
+            .header(TracerHeaders.DEFAULT_HEADER_SPAN_ID, 20L)
+            .get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("bookstore/books/async/notrace"));
         
         assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_TRACE_ID), equalTo("10"));
         assertThat((String)r.getHeaders().getFirst(TracerHeaders.DEFAULT_HEADER_SPAN_ID), equalTo("20"));
@@ -180,8 +196,9 @@ public class HTraceTracingTest extends AbstractBusClientServerTestBase {
         final Response r = createWebClient("/bookstore/books/async").get();
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
         
-        assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(1));
+        assertThat(TestSpanReceiver.getAllSpans().size(), equalTo(2));
         assertThat(TestSpanReceiver.getAllSpans().get(0).getDescription(), equalTo("bookstore/books/async"));
+        assertThat(TestSpanReceiver.getAllSpans().get(1).getDescription(), equalTo("Processing books"));
     }
     
     protected WebClient createWebClient(final String url, final Object ... providers) {