Merge pull request #1 from jgallimore/zipkin-v2
GERONIMO-6727 Zipkin v2 changes
diff --git a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/server/GeronimoOpenTracingFeature.java b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/server/GeronimoOpenTracingFeature.java
index 73c7f28..dbf197a 100644
--- a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/server/GeronimoOpenTracingFeature.java
+++ b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/server/GeronimoOpenTracingFeature.java
@@ -88,6 +88,7 @@
final String path = Stream.of(
ofNullable(resourceInfo.getResourceClass().getAnnotation(Path.class)).map(Path::value).orElse(""),
ofNullable(resourceInfo.getResourceMethod().getAnnotation(Path.class)).map(Path::value).orElse(""))
+ .map(it -> it.equals("/") ? "" : it)
.map(it -> it.substring(it.startsWith("/") ? 1 : 0, it.endsWith("/") ? it.length() - 1 : it.length()))
.filter(it -> !it.isEmpty())
.collect(joining("/", "/", ""));
diff --git a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinConverter.java b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinConverter.java
index 195cff8..4238844 100644
--- a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinConverter.java
+++ b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinConverter.java
@@ -50,6 +50,7 @@
private IdGenerator idGenerator;
private String serviceName;
+ private boolean useV2 = false;
public void setZipkinSpanEvent(final Bus<ZipkinSpan> zipkinSpanEvent) {
this.zipkinSpanEvent = zipkinSpanEvent;
@@ -65,6 +66,7 @@
public void init() {
serviceName = config.read("zipkin.serviceName", getHostName() + "_" + getPid());
+ useV2 = Boolean.parseBoolean(config.read("span.converter.zipkin.http.useV2", "false").trim());
}
@Override
@@ -91,7 +93,14 @@
private ZipkinSpan toZipkin(final SpanImpl span) {
final ZipkinSpan.ZipkinEndpoint endpoint = toEndpoint(span);
- final ZipkinSpan zipkin = new ZipkinSpan();
+ final ZipkinSpan zipkin;
+ if (useV2) {
+ zipkin = new ZipkinSpan();
+ } else {
+ zipkin = new ZipkinV1Span();
+ ((ZipkinV1Span) zipkin).setBinaryAnnotations(toBinaryAnnotations(span.getTags()));
+ }
+
if (idGenerator.isCounter()) {
zipkin.setParentId(asLong(span.getParentId()));
zipkin.setTraceId(asLong(span.getTraceId()));
@@ -106,7 +115,7 @@
zipkin.setTimestamp(span.getTimestamp());
zipkin.setDuration(span.getDuration());
zipkin.setAnnotations(toAnnotations(span));
- zipkin.setBinaryAnnotations(toBinaryAnnotations(span.getTags()));
+
zipkin.setTags(span.getTags().entrySet().stream().filter(e -> !Tags.SPAN_KIND.getKey().equalsIgnoreCase(e.getKey()))
.collect(toMap(Map.Entry::getKey, e -> String.valueOf(e.getValue()))));
diff --git a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinHttp.java b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinHttp.java
index 2301e68..ca43c3c 100644
--- a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinHttp.java
+++ b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinHttp.java
@@ -22,6 +22,7 @@
import static java.util.concurrent.TimeUnit.MINUTES;
import static javax.ws.rs.client.Entity.entity;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static javax.ws.rs.core.MediaType.MEDIA_TYPE_WILDCARD;
import java.util.ArrayList;
import java.util.List;
@@ -38,6 +39,7 @@
import javax.json.bind.JsonbBuilder;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.geronimo.microprofile.opentracing.common.config.GeronimoOpenTracingConfig;
@@ -178,7 +180,7 @@
private void doSend(final List<ZipkinSpan> copy) {
final Response result = client.target(collector)
- .request(APPLICATION_JSON_TYPE)
+ .request()
.post(entity(copy, APPLICATION_JSON_TYPE));
if (result.getStatus() >= 300) {
// todo: better handling but at least log them to not loose them completely or explode in memory
diff --git a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinSpan.java b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinSpan.java
index ba1a555..5a9ae63 100644
--- a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinSpan.java
+++ b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinSpan.java
@@ -30,7 +30,6 @@
private ZipkinEndpoint localEndpoint;
private ZipkinEndpoint remoteEndpoint;
private List<ZipkinAnnotation> annotations;
- private List<ZipkinBinaryAnnotation> binaryAnnotations;
private Map<String, String> tags;
private Boolean debug;
private Boolean shared;
@@ -91,14 +90,6 @@
this.annotations = annotations;
}
- public List<ZipkinBinaryAnnotation> getBinaryAnnotations() {
- return binaryAnnotations;
- }
-
- public void setBinaryAnnotations(final List<ZipkinBinaryAnnotation> binaryAnnotations) {
- this.binaryAnnotations = binaryAnnotations;
- }
-
public Boolean getDebug() {
return debug;
}
diff --git a/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinV1Span.java b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinV1Span.java
new file mode 100644
index 0000000..f89d00f
--- /dev/null
+++ b/geronimo-opentracing-common/src/main/java/org/apache/geronimo/microprofile/opentracing/common/microprofile/zipkin/ZipkinV1Span.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.common.microprofile.zipkin;
+
+import java.util.List;
+
+public class ZipkinV1Span extends ZipkinSpan {
+ private List<ZipkinBinaryAnnotation> binaryAnnotations;
+
+ public List<ZipkinBinaryAnnotation> getBinaryAnnotations() {
+ return binaryAnnotations;
+ }
+
+ public void setBinaryAnnotations(final List<ZipkinBinaryAnnotation> binaryAnnotations) {
+ this.binaryAnnotations = binaryAnnotations;
+ }
+}
diff --git a/geronimo-opentracing/pom.xml b/geronimo-opentracing/pom.xml
index 71f5f41..15dbac0 100644
--- a/geronimo-opentracing/pom.xml
+++ b/geronimo-opentracing/pom.xml
@@ -122,6 +122,12 @@
<version>1.2</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>io.zipkin.zipkin2</groupId>
+ <artifactId>zipkin-junit</artifactId>
+ <version>2.12.9</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/BasicZipkinTest.java b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/BasicZipkinTest.java
new file mode 100644
index 0000000..a6b909d
--- /dev/null
+++ b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/BasicZipkinTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.ClassLoaderAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+import zipkin2.Span;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import java.net.URL;
+import java.util.List;
+
+public class BasicZipkinTest extends Arquillian {
+
+ @Deployment
+ public static WebArchive createDeployment() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(SimpleService.class)
+ .addAsWebInfResource(new ClassLoaderAsset("test-beans.xml"), "beans.xml")
+ .addAsServiceProvider(javax.enterprise.inject.spi.Extension.class, UseGeronimoTracerExtension.class);
+ }
+
+ private ZipkinRule zipkin;
+
+ @ArquillianResource
+ private URL serviceUrl;
+
+ @BeforeMethod
+ public void configure() {
+
+
+ }
+
+ @BeforeSuite
+ public void setup() {
+ zipkin = new ZipkinRule();
+ System.setProperty("geronimo.opentracing.span.converter.zipkin.sender", "http");
+ System.setProperty("geronimo.opentracing.span.converter.zipkin.http.collector", zipkin.httpUrl() + "/api/v2/spans");
+ System.setProperty("geronimo.opentracing.span.converter.zipkin.http.bulkSendInterval", "6000");
+ System.setProperty("geronimo.opentracing.span.converter.zipkin.http.maxSpansPerBulk", "1");
+ System.setProperty("geronimo.opentracing.span.converter.zipkin.http.maxSpansIteration","1");
+ System.setProperty("geronimo.opentracing.span.converter.zipkin.http.bufferSize","1");
+ System.setProperty("geronimo.opentracing.span.converter.zipkin.http.useV2","true");
+
+ }
+
+
+ /**
+ * Test that server endpoint is adding standard tags
+ */
+ @Test
+ @RunAsClient
+ public void testSimpleService() throws Exception {
+ System.out.println(zipkin.httpUrl());
+
+ Client client = ClientBuilder.newClient();
+ String url = serviceUrl.toExternalForm() + "hello";
+
+ WebTarget target = client.target(url);
+ Response response = target.request().get();
+ if (response.getStatus() != 200) {
+ String unexpectedResponse = response.readEntity(String.class);
+ Assert.fail("Expected HTTP response code 200 but received " + response.getStatus() + "; Response: " + unexpectedResponse);
+ }
+
+ Thread.sleep(10000);
+
+ final List<List<Span>> traces = zipkin.getTraces();
+ Assert.assertTrue(traces.size() > 0, "Expected some traces");
+ }
+
+
+}
diff --git a/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SimpleService.java b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SimpleService.java
new file mode 100644
index 0000000..fc2fdfd
--- /dev/null
+++ b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SimpleService.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.microprofile.opentracing.tck.setup;
+
+import org.eclipse.microprofile.opentracing.Traced;
+
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Traced
+@RequestScoped
+@Path("hello")
+public class SimpleService {
+
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String sayHello() throws Exception {
+ return "Hello, world!";
+ }
+
+
+}
diff --git a/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java
index 788d6a4..01cfef1 100644
--- a/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java
+++ b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java
@@ -21,6 +21,9 @@
import org.jboss.arquillian.core.spi.LoadableExtension;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.Filters;
+import org.jboss.shrinkwrap.api.Node;
+
+import java.util.Collection;
// 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 {
@@ -34,8 +37,10 @@
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());
+ final Collection<Node> opentracingApi = archive.getContent(Filters.include("\\/WEB-INF\\/lib\\/opentracing\\-api\\-.*\\.jar")).values();
+ if (opentracingApi != null && !opentracingApi.isEmpty()) {
+ archive.delete(opentracingApi.iterator().next().getPath());
+ }
}
}
}
diff --git a/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/UseGeronimoTracerExtension.java b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/UseGeronimoTracerExtension.java
new file mode 100644
index 0000000..1836018
--- /dev/null
+++ b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/UseGeronimoTracerExtension.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.tck.setup;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+public class UseGeronimoTracerExtension implements Extension {
+
+ void vetoTckTracerIfScanned(@Observes final ProcessAnnotatedType<TckTracer> tckTracer) {
+ tckTracer.veto();
+ }
+
+}
diff --git a/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/ZipkinRule.java b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/ZipkinRule.java
new file mode 100644
index 0000000..08cda86
--- /dev/null
+++ b/geronimo-opentracing/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/ZipkinRule.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2015-2018 The OpenZipkin Authors
+ *
+ * Licensed 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.io.IOException;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import okhttp3.HttpUrl;
+import okhttp3.mockwebserver.Dispatcher;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+import okhttp3.mockwebserver.RecordedRequest;
+import okio.Buffer;
+import okio.GzipSource;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import zipkin2.Callback;
+import zipkin2.DependencyLink;
+import zipkin2.Span;
+import zipkin2.codec.SpanBytesDecoder;
+import zipkin2.collector.Collector;
+import zipkin2.collector.CollectorMetrics;
+import zipkin2.collector.InMemoryCollectorMetrics;
+import zipkin2.internal.Nullable;
+import zipkin2.internal.Platform;
+import zipkin2.junit.HttpFailure;
+import zipkin2.storage.InMemoryStorage;
+import zipkin2.storage.StorageComponent;
+
+import static okhttp3.mockwebserver.SocketPolicy.KEEP_OPEN;
+
+/**
+ * Starts up a local Zipkin server, listening for http requests on {@link #httpUrl}.
+ *
+ * <p>This can be used to test instrumentation. For example, you can POST spans directly to this
+ * server.
+ *
+ * <p>See http://openzipkin.github.io/zipkin-api/#/
+ */
+public final class ZipkinRule implements TestRule {
+ private final InMemoryStorage storage = InMemoryStorage.newBuilder().build();
+ private final InMemoryCollectorMetrics metrics = new InMemoryCollectorMetrics();
+ private final MockWebServer server = new MockWebServer();
+ private final BlockingQueue<MockResponse> failureQueue = new LinkedBlockingQueue<>();
+ private final AtomicInteger receivedSpanBytes = new AtomicInteger();
+
+ public ZipkinRule() {
+ Dispatcher dispatcher =
+ new Dispatcher() {
+ final ZipkinDispatcher successDispatch = new ZipkinDispatcher(storage, metrics, server);
+
+ @Override
+ public MockResponse dispatch(RecordedRequest request) {
+ MockResponse maybeFailure = failureQueue.poll();
+ if (maybeFailure != null) return maybeFailure;
+ MockResponse result = successDispatch.dispatch(request);
+ if (request.getMethod().equals("POST")) {
+ receivedSpanBytes.addAndGet((int) request.getBodySize());
+ }
+ return result;
+ }
+
+ @Override
+ public MockResponse peek() {
+ MockResponse maybeFailure = failureQueue.peek();
+ if (maybeFailure != null) return maybeFailure.clone();
+ return new MockResponse().setSocketPolicy(KEEP_OPEN);
+ }
+ };
+ server.setDispatcher(dispatcher);
+ }
+
+ /** Use this to connect. The zipkin v1 interface will be under "/api/v1" */
+ public String httpUrl() {
+ return String.format("http://%s:%s", server.getHostName(), server.getPort());
+ }
+
+ /** Use this to see how many requests you've sent to any zipkin http endpoint. */
+ public int httpRequestCount() {
+ return server.getRequestCount();
+ }
+
+ /** Use this to see how many spans or serialized bytes were collected on the http endpoint. */
+ public InMemoryCollectorMetrics collectorMetrics() {
+ return metrics;
+ }
+
+ /** Retrieves all traces this zipkin server has received. */
+ public List<List<Span>> getTraces() {
+ return storage.spanStore().getTraces();
+ }
+
+ /** Retrieves a trace by ID which zipkin server has received, or null if not present. */
+ @Nullable
+ public List<Span> getTrace(String traceId) {
+ try {
+ return storage.spanStore().getTrace(traceId).execute();
+ } catch (IOException e) {
+ throw Platform.get().assertionError("I/O exception in in-memory storage", e);
+ }
+ }
+
+ /** Retrieves all service links between traces this zipkin server has received. */
+ public List<DependencyLink> getDependencies() {
+ return storage.spanStore().getDependencies();
+ }
+
+ /**
+ * Used to manually start the server.
+ *
+ * @param httpPort choose 0 to select an available port
+ */
+ public void start(int httpPort) throws IOException {
+ server.start(httpPort);
+ }
+
+ /** Used to manually stop the server. */
+ public void shutdown() throws IOException {
+ server.shutdown();
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return server.apply(base, description);
+ }
+
+ final class ZipkinDispatcher extends Dispatcher {
+ private final Collector consumer;
+ private final CollectorMetrics metrics;
+ private final MockWebServer server;
+
+ ZipkinDispatcher(StorageComponent storage, CollectorMetrics metrics, MockWebServer server) {
+ this.consumer = Collector.newBuilder(getClass()).storage(storage).metrics(metrics).build();
+ this.metrics = metrics;
+ this.server = server;
+ }
+
+ @Override
+ public MockResponse dispatch(RecordedRequest request) {
+ HttpUrl url = server.url(request.getPath());
+ if (request.getMethod().equals("POST")) {
+ String type = request.getHeader("Content-Type");
+ if (url.encodedPath().equals("/api/v1/spans")) {
+ SpanBytesDecoder decoder =
+ type != null && type.contains("/x-thrift")
+ ? SpanBytesDecoder.THRIFT
+ : SpanBytesDecoder.JSON_V1;
+
+ return acceptSpans(request, decoder);
+ } else if (url.encodedPath().equals("/api/v2/spans")) {
+ SpanBytesDecoder decoder =
+ type != null && type.contains("/x-protobuf")
+ ? SpanBytesDecoder.PROTO3
+ : SpanBytesDecoder.JSON_V2;
+
+ return acceptSpans(request, decoder);
+ }
+ } else { // unsupported method
+ return new MockResponse().setResponseCode(405);
+ }
+ return new MockResponse().setResponseCode(404);
+ }
+
+ MockResponse acceptSpans(RecordedRequest request, SpanBytesDecoder decoder) {
+ metrics.incrementMessages();
+ byte[] body = request.getBody().readByteArray();
+
+ // check for the presence of binaryAnnotations, which should not be present in V2.
+ // @see ZipkinHttpCollector.testForUnexpectedFormat
+ if (SpanBytesDecoder.JSON_V2.equals(decoder) &&
+ new String(body).contains("\"binaryAnnotations\"")) {
+ final MockResponse mockResponse = new MockResponse();
+ mockResponse.setResponseCode(400);
+ mockResponse.setBody("Expected a JSON_V2 encoded list, but received: JSON_V1\n");
+ return mockResponse;
+ }
+
+ String encoding = request.getHeader("Content-Encoding");
+ if (encoding != null && encoding.contains("gzip")) {
+ try {
+ Buffer result = new Buffer();
+ GzipSource source = new GzipSource(new Buffer().write(body));
+ while (source.read(result, Integer.MAX_VALUE) != -1) ;
+ body = result.readByteArray();
+ } catch (IOException e) {
+ metrics.incrementMessagesDropped();
+ return new MockResponse().setResponseCode(400).setBody("Cannot gunzip spans");
+ }
+ }
+
+ final MockResponse result = new MockResponse();
+ consumer.acceptSpans(
+ body,
+ decoder,
+ new Callback<Void>() {
+ @Override
+ public void onSuccess(Void value) {
+ result.setResponseCode(202);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ String message = t.getMessage();
+ result.setBody(message).setResponseCode(message.startsWith("Cannot store") ? 500 : 400);
+ }
+ });
+ return result;
+ }
+ }
+
+}
diff --git a/geronimo-opentracing/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/geronimo-opentracing/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
index c34b326..5339e85 100644
--- a/geronimo-opentracing/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
+++ b/geronimo-opentracing/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -1 +1 @@
-org.apache.geronimo.microprofile.opentracing.tck.setup.SkipOpentracingApiSetup
+org.apache.geronimo.microprofile.opentracing.tck.setup.SkipOpentracingApiSetup
\ No newline at end of file
diff --git a/geronimo-opentracing/src/test/resources/test-beans.xml b/geronimo-opentracing/src/test/resources/test-beans.xml
new file mode 100644
index 0000000..f2297ba
--- /dev/null
+++ b/geronimo-opentracing/src/test/resources/test-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="annotated"
+ version="2.0">
+ <trim/>
+</beans>