cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [1/2] cxf git commit: CXF-7439: Support OpenTracing Tracer API
Date Thu, 07 Sep 2017 11:48:24 GMT
Repository: cxf
Updated Branches:
  refs/heads/master e47f445ba -> 4080fbafc


http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index f314a62..16d723b 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -223,6 +223,8 @@
         <cxf.brave.version>4.6.0</cxf.brave.version>
         <cxf.brave.zipkin.version>1.31.1</cxf.brave.zipkin.version>
         <cxf.brave.reporter.version>1.0.2</cxf.brave.reporter.version>
+        <cxf.opentracing.version>0.30.0</cxf.opentracing.version>
+        <cxf.jaeger.version>0.20.6</cxf.jaeger.version>
         <cxf.findbugs.version>3.0.2</cxf.findbugs.version>
         <cxf.checkstyle.extension />
         <cxf.jaxb.context.class />
@@ -2002,6 +2004,21 @@
                  <version>${cxf.brave.version}</version>
             </dependency>
             <dependency>
+                <groupId>io.opentracing</groupId>
+                <artifactId>opentracing-api</artifactId>
+                <version>${cxf.opentracing.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.opentracing</groupId>
+                <artifactId>opentracing-util</artifactId>
+                <version>${cxf.opentracing.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.uber.jaeger</groupId>
+                <artifactId>jaeger-core</artifactId>
+                <version>${cxf.jaeger.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/4080fbaf/rt/management/src/main/java/org/apache/cxf/tracing/AbstractTracingProvider.java
----------------------------------------------------------------------
diff --git a/rt/management/src/main/java/org/apache/cxf/tracing/AbstractTracingProvider.java b/rt/management/src/main/java/org/apache/cxf/tracing/AbstractTracingProvider.java
index d2eafef..f15bf51 100644
--- a/rt/management/src/main/java/org/apache/cxf/tracing/AbstractTracingProvider.java
+++ b/rt/management/src/main/java/org/apache/cxf/tracing/AbstractTracingProvider.java
@@ -19,6 +19,8 @@
 package org.apache.cxf.tracing;
 
 import java.io.Serializable;
+import java.net.URI;
+import java.net.URISyntaxException;
 
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.message.Message;
@@ -74,4 +76,46 @@ public abstract class AbstractTracingProvider {
         }
         return method + " " + path;
     }
+    
+    private static String safeGet(Message message, String key) {
+        if (!message.containsKey(key)) {
+            return null;
+        }
+        Object value = message.get(key);
+        return (value instanceof String) ? value.toString() : null;
+    }
+    
+    private static String getUriAsString(Message message) {
+        String uri = safeGet(message, Message.REQUEST_URL);
+        
+        if (uri == null) {
+            String address = safeGet(message, Message.ENDPOINT_ADDRESS);
+            uri = safeGet(message, Message.REQUEST_URI);
+            if (uri != null && uri.startsWith("/")) {
+                if (address != null && !address.startsWith(uri)) {
+                    if (address.endsWith("/") && address.length() > 1) {
+                        address = address.substring(0, address.length());
+                    }
+                    uri = address + uri;
+                }
+            } else {
+                uri = address;
+            }
+        }
+        String query = safeGet(message, Message.QUERY_STRING);
+        if (query != null) {
+            return uri + "?" + query;
+        }
+        
+        return uri;
+    }
+
+    protected static URI getUri(Message message) {
+        try {
+            String uriSt = getUriAsString(message);
+            return uriSt != null ? new URI(uriSt) : new URI("");
+        } catch (URISyntaxException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/pom.xml
----------------------------------------------------------------------
diff --git a/systests/tracing/pom.xml b/systests/tracing/pom.xml
index 073389d..9d6689f 100644
--- a/systests/tracing/pom.xml
+++ b/systests/tracing/pom.xml
@@ -91,6 +91,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-integration-tracing-opentracing</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-testutils</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
@@ -126,6 +131,21 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>com.uber.jaeger</groupId>
+            <artifactId>jaeger-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReceiver.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReceiver.java b/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReceiver.java
deleted file mode 100644
index 00ec636..0000000
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReceiver.java
+++ /dev/null
@@ -1,60 +0,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.
- */
-package org.apache.cxf.systest;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.htrace.core.HTraceConfiguration;
-import org.apache.htrace.core.Span;
-import org.apache.htrace.core.SpanReceiver;
-
-/**
- * Test HTrace Span receiver
- */
-public class TestSpanReceiver extends SpanReceiver {
-    private static List<Span> spans = new ArrayList<>();
-
-    public TestSpanReceiver(final HTraceConfiguration conf) {
-    }
-
-    public Collection<Span> getSpans() {
-        return spans;
-    }
-
-    @Override
-    public void close() throws IOException {
-    }
-
-    @Override
-    public void receiveSpan(Span span) {
-        spans.add(span);
-    }
-
-    public static void clear() {
-        spans.clear();
-    }
-
-    public static List<Span> getAllSpans() {
-        return spans;
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/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
deleted file mode 100644
index d60b633..0000000
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/TestSpanReporter.java
+++ /dev/null
@@ -1,42 +0,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.
- */
-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/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/brave/TestSpanReporter.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/brave/TestSpanReporter.java b/systests/tracing/src/test/java/org/apache/cxf/systest/brave/TestSpanReporter.java
new file mode 100644
index 0000000..d6e426b
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/brave/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.brave;
+
+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/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/htrace/TestSpanReceiver.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/htrace/TestSpanReceiver.java b/systests/tracing/src/test/java/org/apache/cxf/systest/htrace/TestSpanReceiver.java
new file mode 100644
index 0000000..fdc1158
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/htrace/TestSpanReceiver.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.systest.htrace;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.htrace.core.HTraceConfiguration;
+import org.apache.htrace.core.Span;
+import org.apache.htrace.core.SpanReceiver;
+
+/**
+ * Test HTrace Span receiver
+ */
+public class TestSpanReceiver extends SpanReceiver {
+    private static List<Span> spans = new ArrayList<>();
+
+    public TestSpanReceiver(final HTraceConfiguration conf) {
+    }
+
+    public Collection<Span> getSpans() {
+        return spans;
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+
+    @Override
+    public void receiveSpan(Span span) {
+        spans.add(span);
+    }
+
+    public static void clear() {
+        spans.clear();
+    }
+
+    public static List<Span> getAllSpans() {
+        return spans;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaeger/TestSender.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaeger/TestSender.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaeger/TestSender.java
new file mode 100644
index 0000000..77b13c6
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaeger/TestSender.java
@@ -0,0 +1,54 @@
+/**
+ * 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.jaeger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.uber.jaeger.Span;
+import com.uber.jaeger.exceptions.SenderException;
+import com.uber.jaeger.senders.Sender;
+
+public class TestSender implements Sender {
+    private static List<Span> spans = new ArrayList<>();
+    
+    @Override
+    public int append(Span span) throws SenderException {
+        spans.add(span);
+        return 0;
+    }
+
+    @Override
+    public int flush() throws SenderException {
+        return 0;
+    }
+
+    @Override
+    public int close() throws SenderException {
+        return 0;
+    }
+
+    public static List<Span> getAllSpans() {
+        return spans;
+    }
+
+    public static void clear() {
+        spans.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/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
index 170ff13..90cdbe1 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/brave/BraveTracingTest.java
@@ -39,8 +39,8 @@ 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.brave.BraveTestSupport.SpanId;
+import org.apache.cxf.systest.brave.TestSpanReporter;
 import org.apache.cxf.systest.jaxrs.tracing.BookStore;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/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 2bf22a6..c9df040 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
@@ -40,7 +40,7 @@ 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.TestSpanReceiver;
+import org.apache.cxf.systest.htrace.TestSpanReceiver;
 import org.apache.cxf.systest.jaxrs.tracing.BookStore;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/HasSpan.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/HasSpan.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/HasSpan.java
new file mode 100644
index 0000000..fecdd70
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/HasSpan.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 org.apache.cxf.systest.jaxrs.tracing.opentracing;
+
+import com.uber.jaeger.LogData;
+import com.uber.jaeger.Span;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.core.IsCollectionContaining;
+
+public class HasSpan extends IsCollectionContaining<Span> {
+    public HasSpan(final String name) {
+        this(name, null);
+    }
+
+    public HasSpan(final String name, final Matcher<Iterable<? super LogData>> matcher) {
+        super(new TypeSafeMatcher<Span>() {
+            @Override
+            public void describeTo(Description description) {
+                description
+                    .appendText("span with name ")
+                    .appendValue(name)
+                    .appendText(" ");
+
+                if (matcher != null) {
+                    description.appendText(" and ");
+                    matcher.describeTo(description);
+                }
+            }
+
+            @Override
+            protected boolean matchesSafely(Span item) {
+                if (!name.equals(item.getOperationName())) {
+                    return false;
+                }
+
+                if (matcher != null) {
+                    return matcher.matches(item.getLogs());
+                }
+
+                return true;
+            }
+        });
+    }
+
+    public static HasSpan hasSpan(final String name) {
+        return new HasSpan(name);
+    }
+
+    public static HasSpan hasSpan(final String name, final Matcher<Iterable<? super LogData>> matcher) {
+        return new HasSpan(name, matcher);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsLogContaining.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsLogContaining.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsLogContaining.java
new file mode 100644
index 0000000..b125eae
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsLogContaining.java
@@ -0,0 +1,47 @@
+/**
+ * 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.opentracing;
+
+import com.uber.jaeger.LogData;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.core.IsCollectionContaining;
+
+public class IsLogContaining extends IsCollectionContaining<LogData> {
+    public IsLogContaining(final String value) {
+        super(new TypeSafeMatcher<LogData>() {
+            @Override
+            public void describeTo(Description description) {
+                description
+                    .appendText("annotation with name ")
+                    .appendValue(value);
+            }
+
+            @Override
+            protected boolean matchesSafely(LogData item) {
+                return value.equals(item.getMessage());
+            }
+        });
+    }
+
+    public static IsLogContaining hasItem(final String value) {
+        return new IsLogContaining(value);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsTagContaining.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsTagContaining.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsTagContaining.java
new file mode 100644
index 0000000..b9ac95a
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/IsTagContaining.java
@@ -0,0 +1,33 @@
+/**
+ * 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.opentracing;
+
+import org.hamcrest.collection.IsMapContaining;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+
+public class IsTagContaining extends IsMapContaining<String, Object> {
+    public IsTagContaining(final String key, final String value) {
+        super(equalTo(key), equalTo(value));
+    }
+
+    public static IsTagContaining hasItem(final String key, final String value) {
+        return new IsTagContaining(key, value);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java
new file mode 100644
index 0000000..adaa08d
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/OpenTracingTracingTest.java
@@ -0,0 +1,376 @@
+/**
+ * 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.opentracing;
+
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+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.uber.jaeger.Configuration;
+import com.uber.jaeger.SpanContext;
+import com.uber.jaeger.samplers.ConstSampler;
+
+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.jaeger.TestSender;
+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.opentracing.jaxrs.OpenTracingClientProvider;
+import org.apache.cxf.tracing.opentracing.jaxrs.OpenTracingFeature;
+import org.awaitility.Duration;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.cxf.systest.jaxrs.tracing.opentracing.HasSpan.hasSpan;
+import static org.apache.cxf.systest.jaxrs.tracing.opentracing.IsLogContaining.hasItem;
+import static org.apache.cxf.systest.jaxrs.tracing.opentracing.IsTagContaining.hasItem;
+import static org.awaitility.Awaitility.await;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.empty;
+
+import io.opentracing.ActiveSpan;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format.Builtin;
+import io.opentracing.propagation.TextMap;
+
+public class OpenTracingTracingTest extends AbstractBusClientServerTestBase {
+    public static final String PORT = allocatePort(OpenTracingTracingTest.class);
+
+    private Tracer tracer;
+    private OpenTracingClientProvider openTracingClientProvider;
+    private Random random;
+    
+    @Ignore
+    public static class Server extends AbstractBusTestServerBase {
+        protected void run() {
+            final Tracer tracer = new Configuration("tracer-test-server", 
+                    new Configuration.SamplerConfiguration(ConstSampler.TYPE, 1),
+                    new Configuration.ReporterConfiguration(new TestSender())
+                ).getTracer();
+
+            final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+            sf.setResourceClasses(BookStore.class);
+            sf.setResourceProvider(BookStore.class, new SingletonResourceProvider(new BookStore<ActiveSpan>()));
+            sf.setAddress("http://localhost:" + PORT);
+            sf.setProvider(new JacksonJsonProvider());
+            sf.setProvider(new OpenTracingFeature(tracer));
+            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() {
+        TestSender.clear();
+
+        tracer = new Configuration("tracer-test-client", 
+                new Configuration.SamplerConfiguration(ConstSampler.TYPE, 1),
+                new Configuration.ReporterConfiguration(new TestSender())
+            ).getTracer();
+
+        openTracingClientProvider = new OpenTracingClientProvider(tracer);
+        random = new Random();
+    }
+
+    @Test
+    public void testThatNewSpanIsCreatedWhenNotProvided() {
+        final Response r = createWebClient("/bookstore/books").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("GET /bookstore/books"));
+    }
+
+    @Test
+    public void testThatNewInnerSpanIsCreated() {
+        final SpanContext spanId = fromRandom();
+
+        final Response r = withTrace(createWebClient("/bookstore/books"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("GET /bookstore/books"));
+    }
+
+    @Test
+    public void testThatCurrentSpanIsAnnotatedWithKeyValue() {
+        final SpanContext spanId = fromRandom();
+
+        final Response r = withTrace(createWebClient("/bookstore/book/1"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(1));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("GET /bookstore/book/1"));
+        assertThat(TestSender.getAllSpans().get(0).getTags(), hasItem("book-id", "1"));
+    }
+
+    @Test
+    public void testThatParallelSpanIsAnnotatedWithTimeline() {
+        final SpanContext spanId = fromRandom();
+
+        final Response r = withTrace(createWebClient("/bookstore/process"), spanId).put("");
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans(), hasSpan("Processing books", hasItem("Processing started")));
+        assertThat(TestSender.getAllSpans(), hasSpan("PUT /bookstore/process"));
+    }
+
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvided() {
+        final Response r = createWebClient("/bookstore/books", openTracingClientProvider).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(3));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+        assertThat(TestSender.getAllSpans().get(0).getReferences(), not(empty()));
+    }
+
+    @Test
+    public void testThatNewInnerSpanIsCreatedUsingAsyncInvocation() {
+        final SpanContext spanId = fromRandom();
+
+        final Response r = withTrace(createWebClient("/bookstore/books/async"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/async"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("Processing books"));
+        assertThat(TestSender.getAllSpans().get(0).getReferences(), not(empty()));
+        assertThat(TestSender.getAllSpans().get(0).getReferences().get(0).getSpanContext().getSpanId(), 
+            equalTo(spanId.getSpanId()));
+    }
+
+    @Test
+    public void testThatOuterSpanIsCreatedUsingAsyncInvocation() {
+        final SpanContext spanId = fromRandom();
+
+        final Response r = withTrace(createWebClient("/bookstore/books/async/notrace"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(1));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/async/notrace"));
+    }
+
+    @Test
+    public void testThatNewSpanIsCreatedUsingAsyncInvocation() {
+        final Response r = createWebClient("/bookstore/books/async").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("GET /bookstore/books/async"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("Processing books"));
+    }
+
+    @Test
+    public void testThatNewSpanIsCreatedWhenNotProvidedUsingAsyncClient() throws Exception {
+        final WebClient client = createWebClient("/bookstore/books", openTracingClientProvider);
+        final Future<Response> f = client.async().get();
+
+        final Response r = f.get(1, TimeUnit.SECONDS);
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(3));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("GET /bookstore/books"));
+        assertThat(TestSender.getAllSpans().get(2).getOperationName(), equalTo("GET " + client.getCurrentURI()));
+    }
+
+    @Test
+    public void testThatNewSpansAreCreatedWhenNotProvidedUsingMultipleAsyncClients() throws Exception {
+        final WebClient client = createWebClient("/bookstore/books", openTracingClientProvider);
+        
+        // The intention is to make a calls one after another, not in parallel, to ensure the
+        // thread have trace contexts cleared out.
+        final Collection<Response> responses = IntStream
+            .range(0, 4)
+            .mapToObj(index -> client.async().get())
+            .map(this::get)
+            .collect(Collectors.toList());
+
+        for (final Response r: responses) {
+            assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        }
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(12));
+        
+        IntStream
+            .range(0, 4)
+            .map(index -> index * 3)
+            .forEach(index -> {
+                assertThat(TestSender.getAllSpans().get(index).getOperationName(), 
+                    equalTo("Get Books"));
+                assertThat(TestSender.getAllSpans().get(index + 1).getOperationName(), 
+                    equalTo("GET /bookstore/books"));
+                assertThat(TestSender.getAllSpans().get(index + 2).getOperationName(), 
+                    equalTo("GET " + client.getCurrentURI()));
+            });
+    }
+    
+    @Test
+    public void testThatNewSpansAreCreatedWhenNotProvidedUsingMultipleClients() throws Exception {
+        final WebClient client = createWebClient("/bookstore/books", openTracingClientProvider);
+        
+        // The intention is to make a calls one after another, not in parallel, to ensure the
+        // thread have trace contexts cleared out.
+        final Collection<Response> responses = IntStream
+            .range(0, 4)
+            .mapToObj(index -> client.get())
+            .collect(Collectors.toList());
+
+        for (final Response r: responses) {
+            assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        }
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(12));
+        
+        IntStream
+            .range(0, 4)
+            .map(index -> index * 3)
+            .forEach(index -> {
+                assertThat(TestSender.getAllSpans().get(index).getOperationName(), 
+                    equalTo("Get Books"));
+                assertThat(TestSender.getAllSpans().get(index + 1).getOperationName(), 
+                    equalTo("GET /bookstore/books"));
+                assertThat(TestSender.getAllSpans().get(index + 2).getOperationName(), 
+                    equalTo("GET " + client.getCurrentURI()));
+            });
+    }
+
+    @Test
+    public void testThatProvidedSpanIsNotClosedWhenActive() throws MalformedURLException {
+        final WebClient client = createWebClient("/bookstore/books", openTracingClientProvider);
+
+        try (ActiveSpan span = tracer.buildSpan("test span").startActive()) {
+            final Response r = client.get();
+            assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+            assertThat(TestSender.getAllSpans().size(), equalTo(2));
+            assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+            assertThat(TestSender.getAllSpans().get(0).getReferences(), not(empty()));
+            assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("GET /bookstore/books"));
+        }
+
+        // Await till flush happens, usually every second
+        await().atMost(Duration.ONE_SECOND).until(()-> TestSender.getAllSpans().size() == 3);
+        
+        assertThat(TestSender.getAllSpans().size(), equalTo(3));
+        assertThat(TestSender.getAllSpans().get(2).getOperationName(), equalTo("test span"));
+    }
+
+    @Test
+    public void testThatProvidedSpanIsNotDetachedWhenActiveUsingAsyncClient() throws Exception {
+        final WebClient client = createWebClient("/bookstore/books", openTracingClientProvider);
+
+        try (ActiveSpan span = tracer.buildSpan("test span").startActive()) {
+            final Future<Response> f = client.async().get();
+
+            final Response r = f.get(1, TimeUnit.HOURS);
+            assertEquals(Status.OK.getStatusCode(), r.getStatus());
+            assertThat(tracer.activeSpan().context(), equalTo(span.context()));
+
+            assertThat(TestSender.getAllSpans().size(), equalTo(2));
+            assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+            assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("GET /bookstore/books"));
+        }
+
+        // Await till flush happens, usually every second
+        await().atMost(Duration.ONE_SECOND).until(()-> TestSender.getAllSpans().size() == 3);
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(3));
+        assertThat(TestSender.getAllSpans().get(2).getOperationName(), equalTo("test span"));
+    }
+
+    @Test
+    public void testThatInnerSpanIsCreatedUsingPseudoAsyncInvocation() {
+        final SpanContext spanId = fromRandom();
+
+        final Response r = withTrace(createWebClient("/bookstore/books/pseudo-async"), spanId).get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("GET /bookstore/books/pseudo-async"));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Processing books"));
+    }
+
+    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 SpanContext spanContext) {
+        tracer.inject(spanContext, Builtin.HTTP_HEADERS, new TextMap() {
+            
+            @Override
+            public void put(String key, String value) {
+                client.header(key, value);
+            }
+            
+            @Override
+            public Iterator<Entry<String, String>> iterator() {
+                return null;
+            }
+        });
+        
+        return client;
+    }
+
+    private<T> T get(final Future<T> future) {
+        try {
+            return future.get(1, TimeUnit.HOURS);
+        } catch (InterruptedException | TimeoutException | ExecutionException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private SpanContext fromRandom() {
+        return new SpanContext(random.nextLong(), /* traceId */ random.nextLong() /* spanId */, 
+            random.nextLong() /* parentId */, (byte)1 /* sampled */);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java
index df4b65a..e43b3c8 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BookStore.java
@@ -26,7 +26,7 @@ import javax.jws.WebMethod;
 import javax.jws.WebService;
 
 import org.apache.cxf.systest.Book;
-import org.apache.cxf.systest.TestSpanReporter;
+import org.apache.cxf.systest.brave.TestSpanReporter;
 import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
 
 import brave.Span;

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java
index 27f6de6..13eeca9 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/brave/BraveTracingTest.java
@@ -35,8 +35,8 @@ import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.systest.TestSpanReporter;
 import org.apache.cxf.systest.brave.BraveTestSupport.SpanId;
+import org.apache.cxf.systest.brave.TestSpanReporter;
 import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java
index 5776ac4..c0c7fd4 100644
--- a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/htrace/HTraceTracingTest.java
@@ -33,7 +33,7 @@ import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.Phase;
-import org.apache.cxf.systest.TestSpanReceiver;
+import org.apache.cxf.systest.htrace.TestSpanReceiver;
 import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java
new file mode 100644
index 0000000..3310dae
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/BookStore.java
@@ -0,0 +1,57 @@
+/**
+ * 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.jaxws.tracing.opentracing;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.UUID;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+
+import org.apache.cxf.systest.Book;
+import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
+
+import io.opentracing.ActiveSpan;
+import io.opentracing.Tracer;
+import io.opentracing.util.GlobalTracer;
+
+@WebService(endpointInterface = "org.apache.cxf.systest.jaxws.tracing.BookStoreService", serviceName = "BookStore")
+public class BookStore implements BookStoreService {
+    private final Tracer tracer;
+
+    public BookStore() {
+        tracer = GlobalTracer.get();
+    }
+
+    @WebMethod
+    public Collection< Book > getBooks() {
+        try (ActiveSpan span = tracer.buildSpan("Get Books").startActive()) {
+            return Arrays.asList(
+                    new Book("Apache CXF in Action", UUID.randomUUID().toString()),
+                    new Book("Mastering Apache CXF", UUID.randomUUID().toString())
+                );
+        }
+    }
+
+    @WebMethod
+    public int removeBooks() {
+        throw new RuntimeException("Unable to remove books");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4080fbaf/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java
----------------------------------------------------------------------
diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java
new file mode 100644
index 0000000..e1413a3
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/OpenTracingTracingTest.java
@@ -0,0 +1,254 @@
+/**
+ * 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.jaxws.tracing.opentracing;
+
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.xml.ws.soap.SOAPFaultException;
+
+import com.uber.jaeger.Configuration;
+import com.uber.jaeger.SpanContext;
+import com.uber.jaeger.samplers.ConstSampler;
+
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.ext.logging.LoggingInInterceptor;
+import org.apache.cxf.ext.logging.LoggingOutInterceptor;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.systest.jaeger.TestSender;
+import org.apache.cxf.systest.jaxws.tracing.BookStoreService;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.cxf.tracing.opentracing.OpenTracingClientFeature;
+import org.apache.cxf.tracing.opentracing.OpenTracingFeature;
+import org.apache.cxf.tracing.opentracing.internal.TextMapInjectAdapter;
+import org.awaitility.Duration;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.awaitility.Awaitility.await;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.Matchers.empty;
+
+import io.opentracing.ActiveSpan;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format.Builtin;
+import io.opentracing.util.GlobalTracer;
+
+public class OpenTracingTracingTest extends AbstractBusClientServerTestBase {
+    public static final String PORT = allocatePort(OpenTracingTracingTest.class);
+
+    private Tracer tracer;
+    private Random random;
+    
+    @Ignore
+    public static class Server extends AbstractBusTestServerBase {
+        protected void run() {
+            final Tracer tracer = new Configuration("book-store", 
+                    new Configuration.SamplerConfiguration(ConstSampler.TYPE, 1),
+                    new Configuration.ReporterConfiguration(new TestSender())
+                ).getTracer();
+            GlobalTracer.register(tracer);
+            
+            final JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
+            sf.setServiceClass(BookStore.class);
+            sf.setAddress("http://localhost:" + PORT);
+            sf.getFeatures().add(new OpenTracingFeature(tracer));
+            sf.create();
+        }
+    }
+
+    private interface Configurator {
+        void configure(JaxWsProxyFactoryBean factory);
+    }
+
+    @BeforeClass
+    public static void startServers() throws Exception {
+        //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() {
+        random = new Random();
+        
+        tracer = new Configuration("tracer", 
+                new Configuration.SamplerConfiguration(ConstSampler.TYPE, 1),
+                new Configuration.ReporterConfiguration(new TestSender())
+            ).getTracer();
+
+        TestSender.clear();
+    }
+
+    @Test
+    public void testThatNewSpanIsCreatedWhenNotProvided() throws MalformedURLException {
+        final BookStoreService service = createJaxWsService();
+        assertThat(service.getBooks().size(), equalTo(2));
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("POST /BookStore"));
+    }
+
+    @Test
+    public void testThatNewInnerSpanIsCreated() throws MalformedURLException {
+        final SpanContext spanId = fromRandom();
+
+        final Map<String, List<String>> headers = new HashMap<>();
+        tracer.inject(spanId, Builtin.HTTP_HEADERS, new TextMapInjectAdapter(headers));
+
+        final BookStoreService service = createJaxWsService(headers);
+        assertThat(service.getBooks().size(), equalTo(2));
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("POST /BookStore"));
+    }
+
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvided() throws MalformedURLException {
+        final BookStoreService service = createJaxWsService(new Configurator() {
+            @Override
+            public void configure(final JaxWsProxyFactoryBean factory) {
+                factory.getFeatures().add(new OpenTracingClientFeature(tracer));
+            }
+        });
+        assertThat(service.getBooks().size(), equalTo(2));
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(3));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+        assertThat(TestSender.getAllSpans().get(0).getReferences(), not(empty()));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("POST /BookStore"));
+        assertThat(TestSender.getAllSpans().get(2).getOperationName(),
+            equalTo("POST http://localhost:" + PORT + "/BookStore"));
+    }
+
+    @Test
+    public void testThatProvidedSpanIsNotClosedWhenActive() throws MalformedURLException {
+        final BookStoreService service = createJaxWsService(new Configurator() {
+            @Override
+            public void configure(final JaxWsProxyFactoryBean factory) {
+                factory.getFeatures().add(new OpenTracingClientFeature(tracer));
+            }
+        });
+
+        try (ActiveSpan scope = tracer.buildSpan("test span").startActive()) {
+            assertThat(service.getBooks().size(), equalTo(2));
+            assertThat(tracer.activeSpan(), not(nullValue()));
+
+            assertThat(TestSender.getAllSpans().size(), equalTo(2));
+            assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("Get Books"));
+            assertThat(TestSender.getAllSpans().get(0).getReferences(), not(empty()));
+            assertThat(TestSender.getAllSpans().get(1).getOperationName(), equalTo("POST /BookStore"));
+        }
+
+        // Await till flush happens, usually every second
+        await().atMost(Duration.ONE_SECOND).until(()-> TestSender.getAllSpans().size() == 3);
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(3));
+        assertThat(TestSender.getAllSpans().get(2).getOperationName(), equalTo("test span"));
+    }
+
+    @Test
+    public void testThatNewSpanIsCreatedInCaseOfFault() throws MalformedURLException {
+        final BookStoreService service = createJaxWsService();
+
+        try {
+            service.removeBooks();
+            fail("Expected SOAPFaultException to be raised");
+        } catch (final SOAPFaultException ex) {
+            /* expected exception */
+        }
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(1));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("POST /BookStore"));
+    }
+
+    @Test
+    public void testThatNewChildSpanIsCreatedWhenParentIsProvidedInCaseOfFault() throws MalformedURLException {
+        final BookStoreService service = createJaxWsService(new Configurator() {
+            @Override
+            public void configure(final JaxWsProxyFactoryBean factory) {
+                factory.getFeatures().add(new OpenTracingClientFeature(tracer));
+                factory.getOutInterceptors().add(new LoggingOutInterceptor());
+                factory.getInInterceptors().add(new LoggingInInterceptor());
+            }
+        });
+
+        try {
+            service.removeBooks();
+            fail("Expected SOAPFaultException to be raised");
+        } catch (final SOAPFaultException ex) {
+            /* expected exception */
+        }
+
+        assertThat(TestSender.getAllSpans().size(), equalTo(2));
+        assertThat(TestSender.getAllSpans().get(0).getOperationName(), equalTo("POST /BookStore"));
+        assertThat(TestSender.getAllSpans().get(1).getOperationName(),
+            equalTo("POST http://localhost:" + PORT + "/BookStore"));
+    }
+
+    private BookStoreService createJaxWsService() throws MalformedURLException {
+        return createJaxWsService(new HashMap<String, List<String>>());
+    }
+
+    private BookStoreService createJaxWsService(final Map<String, List<String>> headers) throws MalformedURLException {
+        return createJaxWsService(headers, null);
+    }
+
+    private BookStoreService createJaxWsService(final Configurator configurator) throws MalformedURLException {
+        return createJaxWsService(new HashMap<String, List<String>>(), configurator);
+    }
+
+    private BookStoreService createJaxWsService(final Map<String, List<String>> headers,
+            final Configurator configurator) throws MalformedURLException {
+
+        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
+        factory.getOutInterceptors().add(new LoggingOutInterceptor());
+        factory.getInInterceptors().add(new LoggingInInterceptor());
+        factory.setServiceClass(BookStoreService.class);
+        factory.setAddress("http://localhost:" + PORT + "/BookStore");
+
+        if (configurator != null) {
+            configurator.configure(factory);
+        }
+
+        final BookStoreService service = (BookStoreService) factory.create();
+        final Client proxy = ClientProxy.getClient(service);
+        proxy.getRequestContext().put(Message.PROTOCOL_HEADERS, headers);
+
+        return service;
+    }
+
+    private SpanContext fromRandom() {
+        return new SpanContext(random.nextLong(), /* traceId */ random.nextLong() /* spanId */, 
+            random.nextLong() /* parentId */, (byte)1 /* sampled */);
+    }
+}


Mime
View raw message