startig to fill opentracing repo - not yet functional at all
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..49ca981
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.idea
+*.iml
+target
+
diff --git a/geronimo-microprofile-opentracing-spec/pom.xml b/geronimo-microprofile-opentracing-spec/pom.xml
new file mode 100644
index 0000000..d73cc96
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/pom.xml
@@ -0,0 +1,34 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>geronimo-opentracing</artifactId>
+ <groupId>org.apache.geronimo</groupId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>geronimo-microprofile-opentracing-spec</artifactId>
+ <name>Geronimo OpenTracing :: Spec</name>
+
+ <properties>
+ <geronimo.jpms.name>org.eclipse.microprofile.opentracing</geronimo.jpms.name>
+ </properties>
+</project>
diff --git a/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrar.java b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrar.java
new file mode 100644
index 0000000..5526e08
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrar.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.eclipse.microprofile.opentracing;
+
+import java.util.ServiceLoader;
+import java.util.concurrent.ExecutorService;
+import javax.ws.rs.client.ClientBuilder;
+
+/**
+ * Allows a user to activate tracing on a client builder.
+ */
+public final class ClientTracingRegistrar {
+ /**
+ * @param cb the client builder to active tracing on.
+ * @return the same client builder with tracing activated.
+ */
+ public static ClientBuilder configure(final ClientBuilder cb) {
+ return ServiceLoader.load(ClientTracingRegistrarProvider.class).iterator().next().configure(cb);
+ }
+
+ /**
+ * @param cb the client builder to active tracing on.
+ * @param executorService the executor service the client will use.
+ * @return the same client builder with tracing activated.
+ */
+ public static ClientBuilder configure(final ClientBuilder cb, final ExecutorService executorService) {
+ return ServiceLoader.load(ClientTracingRegistrarProvider.class).iterator().next().configure(cb, executorService);
+ }
+
+ private ClientTracingRegistrar() {
+ // no-op
+ }
+}
diff --git a/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrarProvider.java b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrarProvider.java
new file mode 100644
index 0000000..1909364
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrarProvider.java
@@ -0,0 +1,31 @@
+/*
+ * 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.eclipse.microprofile.opentracing;
+
+import java.util.concurrent.ExecutorService;
+
+import javax.ws.rs.client.ClientBuilder;
+
+/**
+ * Standard java SPI which is used by {@link ClientTracingRegistrar}.
+ */
+public interface ClientTracingRegistrarProvider {
+
+ ClientBuilder configure(ClientBuilder builder);
+
+ ClientBuilder configure(ClientBuilder builder, ExecutorService executorService);
+}
diff --git a/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/Traced.java b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/Traced.java
new file mode 100644
index 0000000..0ddc5fa
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/Traced.java
@@ -0,0 +1,56 @@
+/*
+ * 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.eclipse.microprofile.opentracing;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.enterprise.util.Nonbinding;
+import javax.interceptor.InterceptorBinding;
+
+@InterceptorBinding
+@Retention(RUNTIME)
+@Target({ TYPE, METHOD })
+public @interface Traced {
+
+ /**
+ * This method only modifies the default behavior when set to false.
+ * Depending if Traced has been set on the class it behaves differently:
+ *
+ * <ul>
+ * <li>If <code>@Traced</code> exists on the class then setting this flag to false
+ * on a method will disable the span creation for the endpoint</li>
+ * <li>If the class doesn't have the <code>@Traced</code> marker then the parent is ignored.</li>
+ * </ul>
+ *
+ * @return should the method be traced or not.
+ */
+ @Nonbinding
+ boolean value() default true;
+
+ /**
+ * Allows to customize the span name.
+ *
+ * @return the span name for the "current" endpoint.
+ */
+ @Nonbinding
+ String operationName() default "";
+}
diff --git a/geronimo-opentracing-impl/pom.xml b/geronimo-opentracing-impl/pom.xml
new file mode 100644
index 0000000..cfdba21
--- /dev/null
+++ b/geronimo-opentracing-impl/pom.xml
@@ -0,0 +1,125 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>geronimo-opentracing</artifactId>
+ <groupId>org.apache.geronimo</groupId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>geronimo-opentracing-impl</artifactId>
+ <name>Geronimo OpenTracing :: Impl</name>
+
+ <properties>
+ <geronimo.jpms.name>org.apache.geronimo.opentracing</geronimo.jpms.name>
+
+ <tck.version>1.1-SNAPSHOT</tck.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.geronimo</groupId>
+ <artifactId>geronimo-microprofile-opentracing-spec</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo</groupId>
+ <artifactId>geronimo-opentracing-spec</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.openwebbeans</groupId>
+ <artifactId>openwebbeans-impl</artifactId>
+ <version>2.0.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.testng</groupId>
+ <artifactId>arquillian-testng-container</artifactId>
+ <version>1.1.13.Final</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>6.8.21</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.meecrowave</groupId>
+ <artifactId>meecrowave-arquillian</artifactId>
+ <version>1.2.1</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.microprofile.opentracing</groupId>
+ <artifactId>microprofile-opentracing-tck</artifactId>
+ <version>${tck.version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.microprofile.opentracing</groupId>
+ <artifactId>microprofile-opentracing-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.opentracing</groupId>
+ <artifactId>opentracing-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-client</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jackson-provider</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.21.0</version>
+ <configuration>
+ <suiteXmlFiles>
+ <suiteXmlFile>${project.basedir}/src/test/resources/tck.xml</suiteXmlFile>
+ </suiteXmlFiles>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/FinishedSpan.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/FinishedSpan.java
new file mode 100644
index 0000000..6349ee7
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/FinishedSpan.java
@@ -0,0 +1,31 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import io.opentracing.Span;
+
+public class FinishedSpan {
+ private final Span span;
+
+ FinishedSpan(final Span span) {
+ this.span = span;
+ }
+
+ public Span getSpan() {
+ return span;
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/GeronimoTracer.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/GeronimoTracer.java
new file mode 100644
index 0000000..19f0090
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/GeronimoTracer.java
@@ -0,0 +1,113 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import static java.util.Optional.ofNullable;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+import javax.ws.rs.core.MultivaluedMap;
+
+import io.opentracing.Scope;
+import io.opentracing.ScopeManager;
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format;
+import io.opentracing.propagation.TextMap;
+
+@ApplicationScoped
+public class GeronimoTracer implements Tracer {
+
+ @Inject
+ private ScopeManager scopeManager;
+
+ @Inject
+ private IdGenerator idGenerator;
+
+ @Inject
+ private Event<FinishedSpan> finishedSpanEvent;
+
+ @Override
+ public ScopeManager scopeManager() {
+ return scopeManager;
+ }
+
+ @Override
+ public Span activeSpan() {
+ return ofNullable(scopeManager.active()).map(Scope::span).orElse(null);
+ }
+
+ @Override
+ public SpanBuilder buildSpan(final String operationName) {
+ return new SpanBuilderImpl(this, span -> finishedSpanEvent.fire(new FinishedSpan(span)), operationName, idGenerator);
+ }
+
+ @Override
+ public <C> void inject(final SpanContext spanContext, final Format<C> format, final C carrier) {
+ if (!TextMap.class.isInstance(carrier)) {
+ throw new IllegalArgumentException("Only TextMap are supported");
+ }
+ final TextMap textMap = TextMap.class.cast(carrier);
+ final SpanContextImpl context = SpanContextImpl.class.cast(spanContext);
+ textMap.put("traceid", String.valueOf(context.getTraceId()));
+ textMap.put("spanid", String.valueOf(context.getSpanId()));
+ context.getBaggageItems().forEach((k, v) -> textMap.put("baggage-" + k, v));
+ }
+
+ @Override
+ public <C> SpanContext extract(final Format<C> format, final C carrier) {
+ if (HeaderTextMap.class.isInstance(carrier)) {
+ final MultivaluedMap<String, ?> map = HeaderTextMap.class.cast(carrier).getMap();
+ final String traceid = (String) map.getFirst("traceid");
+ final String spanid = (String) map.getFirst("spanid");
+ if (traceid != null && spanid != null) {
+ return new SpanContextImpl(traceid, spanid, map.keySet().stream().filter(it -> it.startsWith("baggage-"))
+ .collect(toMap(identity(), k -> String.valueOf(map.getFirst(k)))));
+ }
+ return null;
+ }
+ if (!TextMap.class.isInstance(carrier)) {
+ throw new IllegalArgumentException("Only TextMap are supported");
+ }
+ final Iterator<Map.Entry<String, String>> textMap = TextMap.class.cast(carrier).iterator();
+ String traceId = null;
+ String spanId = null;
+ final Map<String, String> baggages = new HashMap<>();
+ while (textMap.hasNext()) {
+ final Map.Entry<String, String> next = textMap.next();
+ if (next.getKey().startsWith("baggage-")) {
+ baggages.put(next.getKey(), next.getValue());
+ } else if ("spanid".equals(next.getKey())) {
+ spanId = next.getValue();
+ } else if ("traceid".equals(next.getKey())) {
+ traceId = next.getValue();
+ }
+ }
+ if (traceId != null && spanId != null) {
+ return new SpanContextImpl(traceId, spanId, baggages);
+ }
+ return null;
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/HeaderTextMap.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/HeaderTextMap.java
new file mode 100644
index 0000000..82b1706
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/HeaderTextMap.java
@@ -0,0 +1,76 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import io.opentracing.propagation.TextMap;
+
+public class HeaderTextMap<T> implements TextMap {
+
+ private final MultivaluedMap<String, T> headers;
+
+ public HeaderTextMap(final MultivaluedMap<String, T> headers) {
+ this.headers = headers;
+ }
+
+ public MultivaluedMap<String, ?> getMap() {
+ return headers;
+ }
+
+ @Override
+ public Iterator<Map.Entry<String, String>> iterator() {
+ final Iterator<String> iterator = headers.keySet().iterator();
+ return new Iterator<Map.Entry<String, String>>() {
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public Map.Entry<String, String> next() {
+ final String next = iterator.next();
+ return new Map.Entry<String, String>() {
+
+ @Override
+ public String getKey() {
+ return next;
+ }
+
+ @Override
+ public String getValue() {
+ return String.valueOf(headers.getFirst(next));
+ }
+
+ @Override
+ public String setValue(final String value) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public void put(final String key, final String value) {
+ this.headers.putSingle(key, (T) value);
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/IdGenerator.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/IdGenerator.java
new file mode 100644
index 0000000..9a048c0
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/IdGenerator.java
@@ -0,0 +1,29 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import java.util.UUID;
+
+import javax.enterprise.context.ApplicationScoped;
+
+@ApplicationScoped
+public class IdGenerator {
+
+ public Object next() {
+ return UUID.randomUUID().toString();
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ReferenceImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ReferenceImpl.java
new file mode 100644
index 0000000..b97ee0f
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ReferenceImpl.java
@@ -0,0 +1,37 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+public class ReferenceImpl {
+
+ private final String type;
+
+ private final SpanContextImpl value;
+
+ public ReferenceImpl(final String type, final SpanContextImpl value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public SpanContextImpl getValue() {
+ return value;
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeImpl.java
new file mode 100644
index 0000000..8d5851e
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import io.opentracing.Scope;
+import io.opentracing.Span;
+
+public class ScopeImpl implements Scope {
+
+ private final Span span;
+
+ private final boolean finishOnClose;
+
+ private final Runnable onClose;
+
+ public ScopeImpl(final Runnable onClose, final Span span, final boolean finishSpanOnClose) {
+ this.onClose = onClose;
+ this.span = span;
+ this.finishOnClose = finishSpanOnClose;
+ }
+
+ @Override
+ public void close() {
+ try {
+ if (finishOnClose) {
+ span.finish();
+ }
+ } finally {
+ if (onClose != null) {
+ onClose.run();
+ }
+ }
+ }
+
+ @Override
+ public Span span() {
+ return span;
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeManagerImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeManagerImpl.java
new file mode 100644
index 0000000..5f5c36f
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeManagerImpl.java
@@ -0,0 +1,49 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import io.opentracing.Scope;
+import io.opentracing.ScopeManager;
+import io.opentracing.Span;
+
+@ApplicationScoped
+public class ScopeManagerImpl implements ScopeManager {
+
+ private final ThreadLocal<Scope> current = new ThreadLocal<>();
+
+ @Override
+ public Scope activate(final Span span, final boolean finishSpanOnClose) {
+ final Thread thread = Thread.currentThread();
+ final Scope oldScope = current.get();
+ return new ScopeImpl(() -> {
+ if (Thread.currentThread() == thread) {
+ current.set(oldScope);
+ } // else error?
+ }, span, finishSpanOnClose);
+ }
+
+ @Override
+ public Scope active() {
+ final Scope scope = current.get();
+ if (scope == null) {
+ current.remove();
+ }
+ return scope;
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanBuilderImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanBuilderImpl.java
new file mode 100644
index 0000000..f943540
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanBuilderImpl.java
@@ -0,0 +1,145 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import static java.util.stream.Collectors.toMap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.stream.StreamSupport;
+
+import io.opentracing.References;
+import io.opentracing.Scope;
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+import io.opentracing.Tracer;
+
+public class SpanBuilderImpl implements Tracer.SpanBuilder {
+
+ private final Tracer tracer;
+
+ private final Consumer<Span> onFinish;
+
+ private final String operationName;
+
+ private final Collection<ReferenceImpl> references = new ArrayList<>();
+
+ private final Map<String, Object> tags = new HashMap<>();
+
+ private final IdGenerator idGenerator;
+
+ private boolean ignoreActiveSpan;
+
+ private long timestamp = -1;
+
+ public SpanBuilderImpl(final Tracer tracer, final Consumer<Span> onFinish, final String operationName,
+ final IdGenerator idGenerator) {
+ this.tracer = tracer;
+ this.onFinish = onFinish;
+ this.operationName = operationName;
+ this.idGenerator = idGenerator;
+ }
+
+ @Override
+ public Tracer.SpanBuilder asChildOf(final SpanContext parent) {
+ return addReference(References.CHILD_OF, parent);
+ }
+
+ @Override
+ public Tracer.SpanBuilder asChildOf(final Span parent) {
+ if (parent == null) {
+ return this;
+ }
+ return asChildOf(parent.context());
+ }
+
+ @Override
+ public Tracer.SpanBuilder addReference(final String referenceType, final SpanContext referencedContext) {
+ references.add(new ReferenceImpl(referenceType, SpanContextImpl.class.cast(referencedContext)));
+ return this;
+ }
+
+ @Override
+ public Tracer.SpanBuilder ignoreActiveSpan() {
+ this.ignoreActiveSpan = ignoreActiveSpan;
+ return this;
+ }
+
+ @Override
+ public Tracer.SpanBuilder withTag(final String key, final String value) {
+ tags.put(key, value);
+ return this;
+ }
+
+ @Override
+ public Tracer.SpanBuilder withTag(final String key, final boolean value) {
+ tags.put(key, value);
+ return this;
+ }
+
+ @Override
+ public Tracer.SpanBuilder withTag(final String key, final Number value) {
+ tags.put(key, value);
+ return this;
+ }
+
+ @Override
+ public Tracer.SpanBuilder withStartTimestamp(final long microseconds) {
+ this.timestamp = microseconds;
+ return this;
+ }
+
+ @Override
+ public Scope startActive(boolean finishSpanOnClose) {
+ return new ScopeImpl(null, startManual(), finishSpanOnClose);
+ }
+
+ @Override
+ public Span startManual() {
+ if (timestamp < 0) {
+ timestamp = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
+ }
+ if (!ignoreActiveSpan && references.stream().noneMatch(it -> it.getType().equalsIgnoreCase(References.CHILD_OF))) {
+ final Span span = tracer.activeSpan();
+ if (span != null) {
+ addReference(References.CHILD_OF, span.context());
+ }
+ }
+ final ReferenceImpl parent = references.stream().filter(it -> References.CHILD_OF.equals(it.getType())).findFirst()
+ .orElseGet(() -> references.isEmpty() ? null : references.iterator().next());
+ final Map<String, String> baggages = references.stream()
+ .flatMap(r -> StreamSupport.stream(
+ Spliterators.spliteratorUnknownSize(r.getValue().baggageItems().iterator(), Spliterator.IMMUTABLE),
+ false))
+ .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
+ return new SpanImpl(operationName, timestamp, references, tags, onFinish,
+ parent == null ? new SpanContextImpl(idGenerator.next(), idGenerator.next(), baggages)
+ : new SpanContextImpl(parent.getValue().getTraceId(), idGenerator.next(), baggages),
+ parent == null ? null : parent.getValue().getSpanId());
+ }
+
+ @Override
+ public Span start() {
+ return startManual();
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanContextImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanContextImpl.java
new file mode 100644
index 0000000..bc71855
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanContextImpl.java
@@ -0,0 +1,63 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import java.util.Map;
+
+import io.opentracing.SpanContext;
+
+public class SpanContextImpl implements SpanContext {
+
+ private final Object traceId;
+
+ private final Object spanId;
+
+ private final Map<String, String> baggageItems;
+
+ public SpanContextImpl(final Object traceId, final Object spanId, final Map<String, String> baggageItems) {
+ this.traceId = traceId;
+ this.spanId = spanId;
+ this.baggageItems = baggageItems;
+ }
+
+ public Map<String, String> getBaggageItems() {
+ return baggageItems;
+ }
+
+ public Object getTraceId() {
+ return traceId;
+ }
+
+ public Object getSpanId() {
+ return spanId;
+ }
+
+ @Override
+ public Iterable<Map.Entry<String, String>> baggageItems() {
+ return baggageItems.entrySet();
+ }
+
+ @Deprecated // TCK
+ public Object traceId() {
+ return getTraceId();
+ }
+
+ @Deprecated // TCK
+ public Object spanId() {
+ return getSpanId();
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanImpl.java
new file mode 100644
index 0000000..968486b
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanImpl.java
@@ -0,0 +1,189 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import static java.util.Collections.singletonMap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+
+public class SpanImpl implements Span {
+
+ private final Collection<ReferenceImpl> references;
+
+ private final Map<String, Object> tags;
+
+ private final Consumer<Span> onFinish;
+
+ private final SpanContextImpl context;
+
+ private final long startTimestamp;
+
+ private final Object parentId;
+
+ private String operationName;
+
+ private long finishTimestamp;
+
+ private final Collection<Log> logs = new ArrayList<>();
+
+ public SpanImpl(final String operationName, final long startTimestamp, final Collection<ReferenceImpl> references,
+ final Map<String, Object> tags, final Consumer<Span> onFinish, final SpanContextImpl context, final Object parentId) {
+ this.operationName = operationName;
+ this.startTimestamp = startTimestamp;
+ this.references = references;
+ this.tags = tags;
+ this.context = context;
+ this.parentId = parentId;
+ this.onFinish = onFinish;
+ }
+
+ @Override
+ public Span log(final long timestampMicroseconds, final Map<String, ?> fields) {
+ synchronized (logs) {
+ logs.add(new Log(timestampMicroseconds, fields));
+ }
+ return this;
+ }
+
+ @Override
+ public SpanContext context() {
+ return context;
+ }
+
+ @Override
+ public Span log(final long timestampMicroseconds, final String event) {
+ return log(singletonMap("event", event));
+ }
+
+ @Override
+ public void finish() {
+ finish(TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()));
+ }
+
+ @Override
+ public void finish(final long finishMicros) {
+ finishTimestamp = finishMicros;
+ onFinish.accept(this);
+ }
+
+ @Override
+ public Span setTag(final String key, final String value) {
+ tags.put(key, value);
+ return this;
+ }
+
+ @Override
+ public Span setTag(final String key, final boolean value) {
+ tags.put(key, value);
+ return this;
+ }
+
+ @Override
+ public Span setTag(final String key, final Number value) {
+ tags.put(key, value);
+ return this;
+ }
+
+ @Override
+ public Span log(final Map<String, ?> fields) {
+ return log(startTimestamp, fields);
+ }
+
+ @Override
+ public Span log(final String event) {
+ return log(startTimestamp, event);
+ }
+
+ @Override
+ public Span setBaggageItem(final String key, final String value) {
+ context.getBaggageItems().put(key, value);
+ return this;
+ }
+
+ @Override
+ public String getBaggageItem(final String key) {
+ return context.getBaggageItems().get(key);
+ }
+
+ @Override
+ public Span setOperationName(final String operationName) {
+ this.operationName = operationName;
+ return this;
+ }
+
+ @Deprecated // TCK compat
+ public long startMicros() {
+ return startTimestamp;
+ }
+
+ @Deprecated // TCK compat
+ public long finishMicros() {
+ return finishTimestamp;
+ }
+
+ @Deprecated // TCK compat
+ public String operationName() {
+ return operationName;
+ }
+
+ @Deprecated // TCK compat
+ public Object parentId() {
+ return parentId;
+ }
+
+ @Deprecated // TCK compat
+ public Map<String, Object> tags() {
+ return tags;
+ }
+
+ @Deprecated // TCK compat
+ public Collection<Log> logEntries() {
+ return logs;
+ }
+
+ public static class Log {
+
+ private final long timestampMicros;
+
+ private final Map<String, ?> fields;
+
+ private Log(long timestampMicros, Map<String, ?> fields) {
+ this.timestampMicros = timestampMicros;
+ this.fields = fields;
+ }
+
+ public long getTimestampMicros() {
+ return timestampMicros;
+ }
+
+ public Map<String, ?> getFields() {
+ return fields;
+ }
+
+ @Deprecated // TCK compat
+ public Map<String, ?> fields() {
+ return getFields();
+ }
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/GeronimoClientTracingRegistrarProvider.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/GeronimoClientTracingRegistrarProvider.java
new file mode 100644
index 0000000..309a3dd
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/GeronimoClientTracingRegistrarProvider.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.geronimo.microprofile.opentracing.microprofile.client;
+
+import java.util.concurrent.ExecutorService;
+
+import javax.enterprise.inject.spi.CDI;
+import javax.ws.rs.client.ClientBuilder;
+
+import org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider;
+
+import io.opentracing.Tracer;
+
+public class GeronimoClientTracingRegistrarProvider implements ClientTracingRegistrarProvider {
+
+ private final OpenTracingClientRequestFilter requestFilter;
+
+ private final OpenTracingClientResponseFilter responseFilter;
+
+ private final Tracer tracer;
+
+ public GeronimoClientTracingRegistrarProvider() {
+ final CDI<Object> cdi = CDI.current();
+ requestFilter = cdi.select(OpenTracingClientRequestFilter.class).get();
+ responseFilter = cdi.select(OpenTracingClientResponseFilter.class).get();
+ tracer = cdi.select(Tracer.class).get();
+ }
+
+ @Override
+ public ClientBuilder configure(final ClientBuilder builder) {
+ return builder.register(requestFilter).register(responseFilter);
+ }
+
+ @Override
+ public ClientBuilder configure(final ClientBuilder builder, final ExecutorService executorService) {
+ final ExecutorService executor = wrapExecutor(executorService);
+ return configure(builder).property("executorService" /* cxf */, executor);
+ }
+
+ private ExecutorService wrapExecutor(final ExecutorService executorService) {
+ return new OpenTracingExecutorService(executorService, tracer);
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientRequestFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientRequestFilter.java
new file mode 100644
index 0000000..fb98146
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientRequestFilter.java
@@ -0,0 +1,77 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.client;
+
+import static io.opentracing.References.CHILD_OF;
+import static java.util.Optional.ofNullable;
+
+import java.util.function.Consumer;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+
+import org.apache.geronimo.microprofile.opentracing.impl.HeaderTextMap;
+
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format;
+import io.opentracing.tag.Tags;
+
+@ApplicationScoped
+public class OpenTracingClientRequestFilter implements ClientRequestFilter {
+
+ @Inject
+ private Tracer tracer;
+
+ @Override
+ public void filter(final ClientRequestContext context) {
+ if (context.getProperty(OpenTracingClientRequestFilter.class.getName()) != null || "true"
+ .equalsIgnoreCase(String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.skip")))) {
+ return;
+ }
+
+ final Tracer.SpanBuilder builder = tracer.buildSpan(context.getMethod());
+ builder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT);
+
+ ofNullable(SpanContext.class.cast(context.getProperty(CHILD_OF)))
+ .ifPresent(parent -> builder.ignoreActiveSpan().asChildOf(parent));
+
+ final Span span = builder.start();
+ if (span == null) {
+ return;
+ }
+
+ span.setOperationName(context.getUri().getPath());
+ if (!"true".equalsIgnoreCase(
+ String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.client.skipDefaultSpanTags")))) {
+ Tags.HTTP_METHOD.set(span, context.getMethod());
+ Tags.HTTP_URL.set(span, context.getUri().toASCIIString());
+ Tags.PEER_HOSTNAME.set(span, context.getUri().getHost());
+ Tags.PEER_PORT.set(span, context.getUri().getPort());
+ }
+ // customization point
+ ofNullable(context.getProperty("org.apache.geronimo.microprofile.opentracing.spanConsumer"))
+ .ifPresent(consumer -> Consumer.class.cast(consumer).accept(span));
+
+ tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new HeaderTextMap<>(context.getHeaders()));
+ context.setProperty(OpenTracingClientRequestFilter.class.getName(), span);
+
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientResponseFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientResponseFilter.java
new file mode 100644
index 0000000..4f9a528
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientResponseFilter.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.geronimo.microprofile.opentracing.microprofile.client;
+
+import static java.util.Optional.ofNullable;
+
+import javax.annotation.Priority;
+import javax.enterprise.context.ApplicationScoped;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+
+import io.opentracing.Span;
+import io.opentracing.tag.Tags;
+
+@ApplicationScoped
+@Priority(Priorities.HEADER_DECORATOR)
+public class OpenTracingClientResponseFilter implements ClientResponseFilter {
+
+ @Override
+ public void filter(final ClientRequestContext req, final ClientResponseContext resp) {
+ ofNullable(req.getProperty(OpenTracingClientRequestFilter.class.getName())).map(Span.class::cast).map(span -> {
+ Tags.HTTP_STATUS.set(span, resp.getStatus());
+ return span;
+ }).ifPresent(Span::finish);
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingExecutorService.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingExecutorService.java
new file mode 100644
index 0000000..37e1059
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingExecutorService.java
@@ -0,0 +1,155 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.client;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import io.opentracing.tag.Tags;
+
+public class OpenTracingExecutorService implements ExecutorService {
+
+ private final ExecutorService delegate;
+
+ private final Tracer tracer;
+
+ public OpenTracingExecutorService(final ExecutorService executorService, final Tracer tracer) {
+ this.delegate = executorService;
+ this.tracer = tracer;
+ }
+
+ private Span before() {
+ return tracer.activeSpan();
+ }
+
+ private void after(final Span span, final RuntimeException error) {
+ if (span != null && error != null) {
+ Tags.ERROR.set(span, true);
+ if (error.getMessage() != null) {
+ span.setTag("errorMessage", error.getMessage());
+ span.setTag("errorType", error.getClass().getName());
+ }
+ }
+ }
+
+ @Override
+ public void shutdown() {
+ delegate.shutdown();
+ }
+
+ @Override
+ public List<Runnable> shutdownNow() {
+ return delegate.shutdownNow();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return delegate.isShutdown();
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return delegate.isTerminated();
+ }
+
+ @Override
+ public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException {
+ return delegate.awaitTermination(timeout, unit);
+ }
+
+ @Override
+ public <T> Future<T> submit(final Callable<T> task) {
+ return delegate.submit(wrap(task));
+ }
+
+ @Override
+ public <T> Future<T> submit(final Runnable task, final T result) {
+ return delegate.submit(wrap(task), result);
+ }
+
+ @Override
+ public Future<?> submit(final Runnable task) {
+ return delegate.submit(wrap(task));
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(final Collection<? extends Callable<T>> tasks) throws InterruptedException {
+ return delegate.invokeAll(tasks.stream().map(this::wrap).collect(toList()));
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(final Collection<? extends Callable<T>> tasks, final long timeout, final TimeUnit unit)
+ throws InterruptedException {
+ return delegate.invokeAll(tasks.stream().map(this::wrap).collect(toList()), timeout, unit);
+ }
+
+ @Override
+ public <T> T invokeAny(final Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
+ return delegate.invokeAny(tasks.stream().map(this::wrap).collect(toList()));
+ }
+
+ @Override
+ public <T> T invokeAny(final Collection<? extends Callable<T>> tasks, final long timeout, final TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ return delegate.invokeAny(tasks.stream().map(this::wrap).collect(toList()), timeout, unit);
+ }
+
+ @Override
+ public void execute(final Runnable command) {
+ delegate.execute(wrap(command));
+ }
+
+ private Runnable wrap(final Runnable task) {
+ return () -> {
+ RuntimeException error = null;
+ final Span span = before();
+ try {
+ task.run();
+ } catch (final RuntimeException re) {
+ error = re;
+ throw re;
+ } finally {
+ after(span, error);
+ }
+ };
+ }
+
+ private <T> Callable<T> wrap(final Callable<T> task) {
+ return () -> {
+ RuntimeException error = null;
+ final Span span = before();
+ try {
+ return task.call();
+ } catch (final RuntimeException re) {
+ error = re;
+ throw re;
+ } finally {
+ after(span, error);
+ }
+ };
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/GeronimoOpenTracingFeature.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/GeronimoOpenTracingFeature.java
new file mode 100644
index 0000000..8032163
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/GeronimoOpenTracingFeature.java
@@ -0,0 +1,64 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.spi.CDI;
+import javax.inject.Inject;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.container.DynamicFeature;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.Provider;
+
+import org.eclipse.microprofile.opentracing.Traced;
+
+import io.opentracing.Tracer;
+
+@Provider
+@Dependent
+public class GeronimoOpenTracingFeature implements DynamicFeature {
+
+ @Inject
+ private Tracer tracer;
+
+ @Override
+ public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
+ if (tracer == null) { // configured instead of scanned
+ tracer = CDI.current().select(Tracer.class).get();
+ }
+
+ final Optional<Traced> traced = ofNullable(ofNullable(resourceInfo.getResourceMethod().getAnnotation(Traced.class))
+ .orElseGet(() -> resourceInfo.getResourceClass().getAnnotation(Traced.class)));
+ if (!traced.map(Traced::value).orElse(true)) {
+ return;
+ }
+
+ final String operationName = traced.map(Traced::operationName).filter(v -> !v.trim().isEmpty())
+ .orElseGet(() -> Stream.of(resourceInfo.getResourceMethod().getAnnotations())
+ .filter(a -> a.annotationType().isAnnotationPresent(HttpMethod.class)).findFirst()
+ .map(a -> a.annotationType().getAnnotation(HttpMethod.class).value()).orElse("") + ':'
+ + resourceInfo.getResourceClass().getName() + "." + resourceInfo.getResourceMethod().getName());
+ context.register(new OpenTracingServerResponseFilter())
+ .register(new OpenTracingServerRequestFilter(operationName, tracer));
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingFilter.java
new file mode 100644
index 0000000..7dc43f2
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingFilter.java
@@ -0,0 +1,87 @@
+package org.apache.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.enterprise.context.Dependent;
+import javax.inject.Inject;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import io.opentracing.Scope;
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import io.opentracing.tag.Tags;
+
+@Dependent
+@WebFilter(asyncSupported = true, urlPatterns = "/*")
+public class OpenTracingFilter implements Filter {
+
+ @Inject
+ private Tracer tracer;
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
+ throws IOException, ServletException {
+ if (!HttpServletRequest.class.isInstance(request)) {
+ chain.doFilter(request, response);
+ return;
+ }
+ try {
+ chain.doFilter(request, response);
+ } catch (final Exception ex) {
+ ofNullable(request.getAttribute(OpenTracingFilter.class.getName())).map(Span.class::cast).ifPresent(span -> {
+ Tags.HTTP_STATUS.set(span, HttpServletResponse.class.cast(response).getStatus());
+ Tags.ERROR.set(span, true);
+ span.log(new HashMap<String, Object>() {
+
+ {
+ put("event", Tags.ERROR.getKey());
+ put("event.object", ex);
+ }
+ });
+ });
+ throw ex;
+ } finally {
+ ofNullable(tracer.scopeManager().active()).ifPresent(Scope::close);
+ ofNullable(request.getAttribute(OpenTracingFilter.class.getName())).map(Span.class::cast).ifPresent(span -> {
+ if (request.isAsyncStarted()) {
+ request.getAsyncContext().addListener(new AsyncListener() {
+
+ @Override
+ public void onComplete(final AsyncEvent event) {
+ span.finish();
+ }
+
+ @Override
+ public void onTimeout(final AsyncEvent event) {
+ // no-op
+ }
+
+ @Override
+ public void onError(final AsyncEvent event) {
+ // no-op
+ }
+
+ @Override
+ public void onStartAsync(final AsyncEvent event) {
+ // no-op
+ }
+ });
+ } else {
+ span.finish();
+ }
+ });
+ }
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerRequestFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerRequestFilter.java
new file mode 100644
index 0000000..021ebf0
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerRequestFilter.java
@@ -0,0 +1,69 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+
+import org.apache.geronimo.microprofile.opentracing.impl.HeaderTextMap;
+import org.apache.geronimo.microprofile.opentracing.microprofile.client.OpenTracingClientRequestFilter;
+
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format;
+import io.opentracing.tag.Tags;
+
+public class OpenTracingServerRequestFilter implements ContainerRequestFilter {
+
+ private final String operationName;
+
+ private final Tracer tracer;
+
+ public OpenTracingServerRequestFilter(final String operationName, final Tracer tracer) {
+ this.operationName = operationName;
+ this.tracer = tracer;
+ }
+
+ @Override
+ public void filter(final ContainerRequestContext context) {
+ if (context.getProperty(OpenTracingClientRequestFilter.class.getName()) != null || "true"
+ .equalsIgnoreCase(String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.skip")))) {
+ return;
+ }
+
+ final Tracer.SpanBuilder builder = tracer.buildSpan(operationName);
+ builder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER);
+
+ ofNullable(ofNullable(tracer.activeSpan()).map(Span::context)
+ .orElseGet(() -> tracer.extract(Format.Builtin.HTTP_HEADERS, new HeaderTextMap<>(context.getHeaders()))))
+ .ifPresent(builder::asChildOf);
+
+ final Span span = builder.startActive(false/* filter does */).span();
+ if (span == null) {
+ return;
+ }
+ if (!"true".equalsIgnoreCase(
+ String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.server.skipDefaultSpanTags")))) {
+ Tags.HTTP_METHOD.set(span, context.getMethod());
+ Tags.HTTP_URL.set(span, context.getUriInfo().getRequestUri().toASCIIString());
+ }
+
+ context.setProperty(OpenTracingFilter.class.getName(), span);
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerResponseFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerResponseFilter.java
new file mode 100644
index 0000000..4191497
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerResponseFilter.java
@@ -0,0 +1,38 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+
+import io.opentracing.Span;
+import io.opentracing.tag.Tags;
+
+@Priority(Priorities.HEADER_DECORATOR)
+public class OpenTracingServerResponseFilter implements ContainerResponseFilter {
+
+ @Override
+ public void filter(final ContainerRequestContext req, final ContainerResponseContext resp) {
+ ofNullable(req.getProperty(OpenTracingFilter.class.getName())).map(Span.class::cast)
+ .ifPresent(span -> Tags.HTTP_STATUS.set(span, resp.getStatus()));
+ }
+}
diff --git a/geronimo-opentracing-impl/src/main/resources/META-INF/beans.xml b/geronimo-opentracing-impl/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..70dd4a9
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+ bean-discovery-mode="all"
+ version="2.0">
+ <trim/>
+</beans>
diff --git a/geronimo-opentracing-impl/src/main/resources/META-INF/services/org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider b/geronimo-opentracing-impl/src/main/resources/META-INF/services/org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider
new file mode 100644
index 0000000..f0f09c0
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/resources/META-INF/services/org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider
@@ -0,0 +1 @@
+org.apache.geronimo.microprofile.opentracing.microprofile.client.GeronimoClientTracingRegistrarProvider
diff --git a/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/LongIdGenerator.java b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/LongIdGenerator.java
new file mode 100644
index 0000000..d4e56c8
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/LongIdGenerator.java
@@ -0,0 +1,35 @@
+/*
+ * 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.geronimo.microprofile.opentracing.tck.setup;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Specializes;
+
+import org.apache.geronimo.microprofile.opentracing.impl.IdGenerator;
+
+@Specializes
+@ApplicationScoped
+public class LongIdGenerator extends IdGenerator {
+
+ private final AtomicLong id = new AtomicLong();
+
+ public Object next() {
+ return id.incrementAndGet();
+ }
+}
diff --git a/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java
new file mode 100644
index 0000000..788d6a4
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java
@@ -0,0 +1,41 @@
+/*
+ * 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.geronimo.microprofile.opentracing.tck.setup;
+
+import org.jboss.arquillian.container.spi.event.container.BeforeDeploy;
+import org.jboss.arquillian.core.api.annotation.Observes;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Filters;
+
+// the tck put the opentracing-api in the war but not our impl, let's fix it by using the apploader api jar!
+public class SkipOpentracingApiSetup implements LoadableExtension {
+
+ @Override
+ public void register(final ExtensionBuilder builder) {
+ builder.observer(Impl.class);
+ }
+
+ public static class Impl {
+
+ public void clean(@Observes final BeforeDeploy beforeDeploy) {
+ final Archive<?> archive = beforeDeploy.getDeployment().getArchive();
+ archive.delete(archive.getContent(Filters.include("\\/WEB-INF\\/lib\\/opentracing\\-api\\-.*\\.jar")).values()
+ .iterator().next().getPath());
+ }
+ }
+}
diff --git a/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/TckTracer.java b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/TckTracer.java
new file mode 100644
index 0000000..43ffc79
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/TckTracer.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 org.apache.geronimo.microprofile.opentracing.tck.setup;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Specializes;
+
+import org.apache.geronimo.microprofile.opentracing.impl.FinishedSpan;
+import org.apache.geronimo.microprofile.opentracing.impl.GeronimoTracer;
+
+import io.opentracing.Span;
+
+// compat for TCK, to drop once tcks are fixed - used by reflection!!!!
+@Specializes
+@ApplicationScoped
+public class TckTracer extends GeronimoTracer {
+ private final Collection<Span> spans = new ArrayList<>();
+
+ synchronized void onSpan(@Observes final FinishedSpan span) {
+ spans.add(span.getSpan());
+ }
+
+ public synchronized Iterable<Span> finishedSpans() {
+ return new ArrayList<>(spans);
+ }
+
+ public synchronized void reset() {
+ spans.clear();
+ }
+}
diff --git a/geronimo-opentracing-impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/geronimo-opentracing-impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..c34b326
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1 @@
+org.apache.geronimo.microprofile.opentracing.tck.setup.SkipOpentracingApiSetup
diff --git a/geronimo-opentracing-impl/src/test/resources/arquillian.xml b/geronimo-opentracing-impl/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..9d21c97
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/arquillian.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ 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.
+-->
+<arquillian xmlns="http://jboss.org/schema/arquillian"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://jboss.org/schema/arquillian
+ http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+ <container qualifier="default" default="true">
+ <configuration>
+ <property name="tempDir">target/meecrowave/temp</property>
+ <property name="jaxrsDefaultProviders">
+ com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider,
+ org.apache.geronimo.microprofile.opentracing.microprofile.server.GeronimoOpenTracingFeature
+ </property>
+ <property name="scanningExcludes">
+ arquillian,
+ bsh,
+ debugger,
+ jackson-,
+ jcommander,
+ microprofile-,
+ opentracing,
+ resteasy
+ </property>
+ </configuration>
+ </container>
+</arquillian>
diff --git a/geronimo-opentracing-impl/src/test/resources/tck-dev.xml b/geronimo-opentracing-impl/src/test/resources/tck-dev.xml
new file mode 100644
index 0000000..cfc75d1
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/tck-dev.xml
@@ -0,0 +1,28 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<!--
+ 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.
+-->
+<suite name="microprofile-opentracing-TCK" verbose="2" configfailurepolicy="continue">
+ <test name="microprofile-opentracing 1.0 TCK">
+ <classes>
+ <class name="org.eclipse.microprofile.opentracing.tck.OpentracingClientTests">
+ <methods>
+ <include name="testAnnotations" />
+ </methods>
+ </class>
+ </classes>
+ </test>
+</suite>
diff --git a/geronimo-opentracing-impl/src/test/resources/tck.xml b/geronimo-opentracing-impl/src/test/resources/tck.xml
new file mode 100644
index 0000000..bb8dfbd
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/tck.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<!--
+ 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.
+-->
+<suite name="microprofile-opentracing-TCK" verbose="2" configfailurepolicy="continue">
+ <test name="microprofile-opentracing 1.0 TCK">
+ <packages>
+ <package name="org.eclipse.microprofile.opentracing.tck.*"/>
+ </packages>
+ </test>
+</suite>
diff --git a/geronimo-opentracing-spec/pom.xml b/geronimo-opentracing-spec/pom.xml
new file mode 100644
index 0000000..acd05fe
--- /dev/null
+++ b/geronimo-opentracing-spec/pom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>geronimo-opentracing</artifactId>
+ <groupId>org.apache.geronimo</groupId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>geronimo-opentracing-spec</artifactId>
+ <name>Geronimo OpenTracing :: OpenTracing Spec</name>
+
+ <properties>
+ <geronimo.jpms.name>io.opentracing.api</geronimo.jpms.name>
+ </properties>
+</project>
\ No newline at end of file
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/References.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/References.java
new file mode 100644
index 0000000..1091e19
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/References.java
@@ -0,0 +1,27 @@
+/*
+ * 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 io.opentracing;
+
+public final class References {
+
+ public static final String CHILD_OF = "child_of";
+ public static final String FOLLOWS_FROM = "follows_from";
+
+ private References() {
+ // no-op
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/Scope.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/Scope.java
new file mode 100644
index 0000000..e46a5ed
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/Scope.java
@@ -0,0 +1,36 @@
+/*
+ * 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 io.opentracing;
+
+import java.io.Closeable;
+
+/**
+ * Abstract a span life.
+ */
+public interface Scope extends Closeable {
+
+ /**
+ * remove the span from the manager (active() will not return it anymore).
+ */
+ @Override
+ void close();
+
+ /**
+ * @return the related span.
+ */
+ Span span();
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/ScopeManager.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/ScopeManager.java
new file mode 100644
index 0000000..7aa512a
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/ScopeManager.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 io.opentracing;
+
+/**
+ * Abstracts span contextuality.
+ */
+public interface ScopeManager {
+
+ /**
+ * Set the active span.
+ */
+ Scope activate(Span span, boolean finishSpanOnClose);
+
+ /**
+ * @return current active span.
+ */
+ Scope active();
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/Span.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/Span.java
new file mode 100644
index 0000000..14778c6
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/Span.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 io.opentracing;
+
+import java.util.Map;
+
+public interface Span {
+
+ /**
+ * @return the context related to this span.
+ */
+ SpanContext context();
+
+ Span setTag(String key, String value);
+
+ Span setTag(String key, boolean value);
+
+ Span setTag(String key, Number value);
+
+ Span log(Map<String, ?> fields);
+
+ Span log(long timestampMicroseconds, Map<String, ?> fields);
+
+ Span log(String event);
+
+ Span log(long timestampMicroseconds, String event);
+
+ Span setBaggageItem(String key, String value);
+
+ String getBaggageItem(String key);
+
+ Span setOperationName(String operationName);
+
+ void finish();
+
+ void finish(long finishMicros);
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/SpanContext.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/SpanContext.java
new file mode 100644
index 0000000..2210079
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/SpanContext.java
@@ -0,0 +1,27 @@
+/*
+ * 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 io.opentracing;
+
+import java.util.Map;
+
+public interface SpanContext {
+
+ /**
+ * @return baggage items related to current span.
+ */
+ Iterable<Map.Entry<String, String>> baggageItems();
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/Tracer.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/Tracer.java
new file mode 100644
index 0000000..4477984
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/Tracer.java
@@ -0,0 +1,94 @@
+/*
+ * 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 io.opentracing;
+
+import io.opentracing.propagation.Format;
+
+public interface Tracer {
+
+ /**
+ * @return current {@link ScopeManager}.
+ */
+ ScopeManager scopeManager();
+
+ /**
+ * @return current {@link Span}.
+ */
+ Span activeSpan();
+
+ /**
+ * @return a new span builder.
+ */
+ SpanBuilder buildSpan(String operationName);
+
+ /**
+ * Inject a span context into a carrier.
+ */
+ <C> void inject(SpanContext spanContext, Format<C> format, C carrier);
+
+ /**
+ * @return the span context from the carrier.
+ */
+ <C> SpanContext extract(Format<C> format, C carrier);
+
+ interface SpanBuilder {
+
+ /**
+ * @return this span builder after having added CHILD_OFF reference.
+ */
+ SpanBuilder asChildOf(SpanContext parent);
+
+ /**
+ * @return this span builder after having added CHILD_OFF reference from the parent.
+ */
+ SpanBuilder asChildOf(Span parent);
+
+ /**
+ * @return this span builder after having added a reference.
+ */
+ SpanBuilder addReference(String referenceType, SpanContext referencedContext);
+
+ /**
+ * @return this span builder flag to ignore implicit CHILD_OFF reference.
+ */
+ SpanBuilder ignoreActiveSpan();
+
+ SpanBuilder withTag(String key, String value);
+
+ SpanBuilder withTag(String key, boolean value);
+
+ SpanBuilder withTag(String key, Number value);
+
+ SpanBuilder withStartTimestamp(long microseconds);
+
+ /**
+ * @return a new scope registered in the scope manager.
+ */
+ Scope startActive(boolean finishSpanOnClose);
+
+ /**
+ * @deprecated replaced by {@link #start} and {@link #startActive}.
+ */
+ @Deprecated
+ Span startManual();
+
+ /**
+ * @return a new scope not registered in the manager.
+ */
+ Span start();
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/log/Fields.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/log/Fields.java
new file mode 100644
index 0000000..8be899f
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/log/Fields.java
@@ -0,0 +1,34 @@
+/*
+ * 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 io.opentracing.log;
+
+public final class Fields {
+
+ private Fields() {
+ // no-op
+ }
+
+ public static final String ERROR_KIND = "error.kind";
+
+ public static final String ERROR_OBJECT = "error.object";
+
+ public static final String EVENT = "event";
+
+ public static final String MESSAGE = "message";
+
+ public static final String STACK = "stack";
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/Format.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/Format.java
new file mode 100644
index 0000000..a461c77
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/Format.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 io.opentracing.propagation;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Tracer interaction abstraction.
+ */
+public interface Format<C> {
+
+ final class Builtin<C> implements Format<C> {
+
+ public final static Format<TextMap> TEXT_MAP = new Builtin<TextMap>("TEXT_MAP");
+
+ public final static Format<TextMap> HTTP_HEADERS = new Builtin<TextMap>("HTTP_HEADERS");
+
+ public final static Format<ByteBuffer> BINARY = new Builtin<ByteBuffer>("BINARY");
+
+ private final String name;
+
+ private Builtin(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return Builtin.class.getSimpleName() + "." + name;
+ }
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMap.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMap.java
new file mode 100644
index 0000000..0b26473
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMap.java
@@ -0,0 +1,30 @@
+/*
+ * 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 io.opentracing.propagation;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Default carrier (kind of limited map).
+ */
+public interface TextMap extends Iterable<Map.Entry<String, String>> {
+
+ Iterator<Map.Entry<String, String>> iterator();
+
+ void put(String key, String value);
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapExtractAdapter.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapExtractAdapter.java
new file mode 100644
index 0000000..05a07c7
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapExtractAdapter.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 io.opentracing.propagation;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Read only TextMap adapter from a map.
+ */
+public final class TextMapExtractAdapter implements TextMap {
+
+ private final Map<String, String> map;
+
+ public TextMapExtractAdapter(final Map<String, String> map) {
+ this.map = map;
+ }
+
+ @Override
+ public Iterator<Map.Entry<String, String>> iterator() {
+ return map.entrySet().iterator();
+ }
+
+ @Override
+ public void put(final String key, final String value) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapInjectAdapter.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapInjectAdapter.java
new file mode 100644
index 0000000..e8b611b
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapInjectAdapter.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 io.opentracing.propagation;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Write only TextMap adapter from a map.
+ */
+public class TextMapInjectAdapter implements TextMap {
+
+ private final Map<String, String> map;
+
+ public TextMapInjectAdapter(final Map<String, String> map) {
+ this.map = map;
+ }
+
+ @Override
+ public Iterator<Map.Entry<String, String>> iterator() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void put(final String key, final String value) {
+ this.map.put(key, value);
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/AbstractTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/AbstractTag.java
new file mode 100644
index 0000000..dcac609
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/AbstractTag.java
@@ -0,0 +1,34 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public abstract class AbstractTag<T> {
+
+ protected final String key;
+
+ public AbstractTag(final String tagKey) {
+ this.key = tagKey;
+ }
+
+ protected abstract void set(Span span, T tagValue);
+
+ public String getKey() {
+ return key;
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/BooleanTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/BooleanTag.java
new file mode 100644
index 0000000..ac5f788
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/BooleanTag.java
@@ -0,0 +1,31 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class BooleanTag extends AbstractTag<Boolean> {
+
+ public BooleanTag(final String key) {
+ super(key);
+ }
+
+ @Override
+ public void set(final Span span, final Boolean tagValue) {
+ span.setTag(key, tagValue);
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntOrStringTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntOrStringTag.java
new file mode 100644
index 0000000..37f712c
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntOrStringTag.java
@@ -0,0 +1,30 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class IntOrStringTag extends IntTag {
+
+ public IntOrStringTag(final String key) {
+ super(key);
+ }
+
+ public void set(final Span span, final String tagValue) {
+ span.setTag(key, tagValue);
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntTag.java
new file mode 100644
index 0000000..53c1ede
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntTag.java
@@ -0,0 +1,31 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class IntTag extends AbstractTag<Integer> {
+
+ public IntTag(final String key) {
+ super(key);
+ }
+
+ @Override
+ public void set(final Span span, final Integer tagValue) {
+ span.setTag(key, tagValue);
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/StringTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/StringTag.java
new file mode 100644
index 0000000..ce2a703
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/StringTag.java
@@ -0,0 +1,31 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class StringTag extends AbstractTag<String> {
+
+ public StringTag(final String key) {
+ super(key);
+ }
+
+ @Override
+ public void set(final Span span, final String tagValue) {
+ span.setTag(key, tagValue);
+ }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/Tags.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/Tags.java
new file mode 100644
index 0000000..f482a38
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/Tags.java
@@ -0,0 +1,46 @@
+/*
+ * 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 io.opentracing.tag;
+
+public final class Tags {
+
+ public static final String SPAN_KIND_SERVER = "server";
+ public static final String SPAN_KIND_CLIENT = "client";
+ public static final String SPAN_KIND_PRODUCER = "producer";
+ public static final String SPAN_KIND_CONSUMER = "consumer";
+ public static final StringTag HTTP_URL = new StringTag("http.url");
+ public static final IntTag HTTP_STATUS = new IntTag("http.status_code");
+ public static final StringTag HTTP_METHOD = new StringTag("http.method");
+ public static final IntOrStringTag PEER_HOST_IPV4 = new IntOrStringTag("peer.ipv4");
+ public static final StringTag PEER_HOST_IPV6 = new StringTag("peer.ipv6");
+ public static final StringTag PEER_SERVICE = new StringTag("peer.service");
+ public static final StringTag PEER_HOSTNAME = new StringTag("peer.hostname");
+ public static final IntTag PEER_PORT = new IntTag("peer.port");
+ public static final IntTag SAMPLING_PRIORITY = new IntTag("sampling.priority");
+ public static final StringTag SPAN_KIND = new StringTag("span.kind");
+ public static final StringTag COMPONENT = new StringTag("component");
+ public static final BooleanTag ERROR = new BooleanTag("error");
+ public static final StringTag DB_TYPE = new StringTag("db.type");
+ public static final StringTag DB_INSTANCE = new StringTag("db.instance");
+ public static final StringTag DB_USER = new StringTag("db.user");
+ public static final StringTag DB_STATEMENT = new StringTag("db.statement");
+ public static final StringTag MESSAGE_BUS_DESTINATION = new StringTag("message_bus.destination");
+
+ private Tags() {
+ // no-op
+ }
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4ff6c7d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,150 @@
+<?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>
+
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>18</version>
+ </parent>
+
+ <groupId>org.apache.geronimo</groupId>
+ <artifactId>geronimo-opentracing</artifactId>
+ <version>1.0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Geronimo OpenTracing</name>
+
+ <description>
+ Apache Geronimo implementation of the Microprofile OpenTracing Specification
+ </description>
+
+ <scm>
+ <connection>scm:git:https://gitbox.apache.org/repos/asf/geronimo-opentracing.git</connection>
+ <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/geronimo-opentracing.git</developerConnection>
+ <url>https://gitbox.apache.org/repos/asf/geronimo-opentracing.git</url>
+ <tag>HEAD</tag>
+ </scm>
+
+ <modules>
+ <module>geronimo-microprofile-opentracing-spec</module>
+ <module>geronimo-opentracing-impl</module>
+ <module>geronimo-opentracing-impl</module>
+ <module>geronimo-opentracing-spec</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-servlet-api</artifactId>
+ <version>9.0.7</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jaxrs_2.0_spec</artifactId>
+ <version>1.0-alpha-1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-json_1.1_spec</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-interceptor_1.2_spec</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-atinject_1.0_spec</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jcdi_2.0_spec</artifactId>
+ <version>1.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-annotation_1.3_spec</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.7.0</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.0.2</version>
+ <configuration>
+ <archive combine.children="append">
+ <manifestEntries>
+ <Automatic-Module-Name>${geronimo.jpms.name}</Automatic-Module-Name>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+ <organization>
+ <name>The Apache Software Foundation</name>
+ <url>http://www.apache.org/</url>
+ </organization>
+
+ <inceptionYear>2017</inceptionYear>
+
+ <licenses>
+ <license>
+ <name>Apache License, Version 2.0</name>
+ <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <name>Apache Geronimo Community</name>
+ <url>https://geronimo.apache.org</url>
+ <organization>Apache</organization>
+ </developer>
+ </developers>
+
+ <issueManagement>
+ <system>ASF JIRA</system>
+ <url>https://issues.apache.org/jira/browse/GERONIMO</url>
+ </issueManagement>
+</project>