Skip to content

Commit

Permalink
Adds ability to specify zipkin http path relative to host (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
andystanton authored Sep 2, 2020
1 parent caf771a commit 0197e96
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Flag | Default | Description
--- | --- | ---
zipkin.http.host | localhost:9411 | The network location of the Zipkin http service. See http://twitter.github.io/finagle/guide/Names.html
zipkin.http.hostHeader | zipkin | The Host header used when sending spans to Zipkin
zipkin.http.path | /api/v2/spans | The path to the spans endpoint
zipkin.http.compressionEnabled | true | True implies that spans will be gzipped before transport
zipkin.http.tlsEnabled | false | Whether or not the Zipkin host uses TLS
zipkin.http.tlsValidationEnabled | true | Whether or not to enable TLS validation for the Zipkin host when TLS is enabled
Expand Down
35 changes: 35 additions & 0 deletions http/src/main/java/zipkin/http/path$.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2016-2020 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 zipkin.http;

import com.twitter.app.Flag;
import com.twitter.app.Flaggable;
import com.twitter.app.JavaGlobalFlag;

public final class path$ extends JavaGlobalFlag<String> {
public static String DEFAULT_PATH = "/api/v2/spans";

private path$() {
super(DEFAULT_PATH,
"The path to the spans endpoint",
Flaggable.ofString());
}

public static final Flag<String> Flag = new path$();

public static Flag<?> globalFlagInstance() {
return Flag;
}
}

2 changes: 1 addition & 1 deletion http/src/main/java/zipkin2/finagle/http/HttpSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ final class HttpSender extends FinagleSender<HttpZipkinTracer.Config, Request, R

@Override protected Request makeRequest(List<byte[]> spans) throws IOException {
byte[] json = BytesMessageEncoder.JSON.encode(spans);
Request request = Request.apply(POST, "/api/v2/spans");
Request request = Request.apply(POST, config.path());
request.headerMap().add("Host", config.hostHeader());
request.headerMap().add("Content-Type", "application/json");
// Eventhough finagle compression flag exists, it only works for servers!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import scala.runtime.BoxedUnit;
import zipkin.localServiceName$;
import zipkin2.finagle.ZipkinTracer;
import zipkin2.internal.Nullable;

@AutoService(Tracer.class)
public final class HttpZipkinTracer extends ZipkinTracer {
Expand Down Expand Up @@ -85,6 +84,7 @@ public static Builder builder() {
return new AutoValue_HttpZipkinTracer_Config.Builder()
.hostHeader(zipkin.http.hostHeader$.Flag.apply())
.host(zipkin.http.host$.Flag.apply())
.path(zipkin.http.path$.Flag.apply())
.compressionEnabled(zipkin.http.compressionEnabled$.Flag.apply())
.tlsEnabled(zipkin.http.tlsEnabled$.Flag.apply())
.tlsValidationEnabled(zipkin.http.tlsValidationEnabled$.Flag.apply())
Expand All @@ -104,6 +104,8 @@ public static Builder builder() {

abstract boolean compressionEnabled();

abstract String path();

@AutoValue.Builder
public abstract static class Builder {
/**
Expand All @@ -121,6 +123,9 @@ public abstract static class Builder {
/** The network location of the Zipkin http service. Defaults to "localhost:9411" */
public abstract Builder host(Name host);

/** The path to the Zipkin endpoint relative to the host. Defaults to "/api/v2/spans" */
public abstract Builder path(String path);

/** Shortcut for a {@link #host(Name)} encoded as a String */
public final Builder host(String host) {
return host(Resolver$.MODULE$.eval(host));
Expand Down
68 changes: 68 additions & 0 deletions http/src/test/java/zipkin/http/pathTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2016-2020 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 zipkin.http;

import com.twitter.app.Flag;
import com.twitter.app.GlobalFlag$;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.After;
import org.junit.Test;
import scala.Function0;
import scala.Option;
import scala.runtime.AbstractFunction0;
import scala.runtime.BoxedUnit;

import static org.assertj.core.api.Assertions.assertThat;
import static scala.collection.JavaConverters.asJavaCollection;

public class pathTest {

@After public void resetGlobalFlags() {
for (Flag<?> globalFlag: globalFlags()) globalFlag.reset();
}

@Test public void defaultValue() {
Option<Flag<?>> flagOption = GlobalFlag$.MODULE$.get("zipkin.http.path");
assertThat(flagOption.get().apply()).isEqualTo("/api/v2/spans");
}

@Test public void letOverridesDefault() {
final String override = "/custom/api/v2/spans";

final AtomicBoolean ran = new AtomicBoolean();
Function0<BoxedUnit> fn0 = new AbstractFunction0<BoxedUnit>() {
@Override public BoxedUnit apply() {
ran.set(true); // used to verify this block is executed.
assertThat(path$.Flag.isDefined()).isTrue();
assertThat(path$.Flag.apply()).isEqualTo(override);
return BoxedUnit.UNIT;
}
};
path$.Flag.let(override, fn0);

assertThat(ran.get()).isTrue();
}

@Test
public void registersGlobal() {
assertThat(globalFlags())
.extracting(f -> f.name())
.containsOnlyOnce("zipkin.http.path");
}

Collection<Flag<?>> globalFlags() {
return asJavaCollection(GlobalFlag$.MODULE$.getAll(getClass().getClassLoader()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import okhttp3.tls.HandshakeCertificates;
import okhttp3.tls.HeldCertificate;
import org.junit.Rule;
import org.junit.Test;
import scala.Option;
import zipkin.http.path$;
import zipkin2.Span;
import zipkin2.finagle.FinagleTestObjects;
import zipkin2.finagle.ZipkinTracer;
Expand Down Expand Up @@ -89,6 +93,43 @@ public class HttpZipkinTracerIntegrationTest extends ZipkinTracerIntegrationTest
);
}

@Test public void path() throws Exception {
http.shutdown(); // shutdown the normal zipkin rule

// create instructions to create a complete RPC span
List<Record> records = asList(
new Record(root, Time.fromMilliseconds(TODAY), new ServiceName("web"), none),
new Record(root, Time.fromMilliseconds(TODAY), new Rpc("get"), none),
new Record(root, Time.fromMilliseconds(TODAY), ClientSend$.MODULE$, none),
new Record(root, Time.fromMilliseconds(TODAY + 1), ClientRecv$.MODULE$, none)
);

MockWebServer server = new MockWebServer();
config = config.toBuilder().host("localhost:" + server.getPort()).build();
try {
List<RecordedRequest> requests = new ArrayList<>();
String customPath = "/custom/api/v2/spans";
for (Optional<String> overridePath : asList(Optional.<String>empty(),
Optional.of(customPath))) {
// recreate the tracer with the path configuration
closeTracer();
overridePath.ifPresent(s -> config = config.toBuilder().path(s).build());
createTracer();

// write a complete span so that it gets reported
records.forEach(tracer::record);

// block until the request arrived
requests.add(server.takeRequest());
}
// we expect the first request to be sent to the default path, and the second to the overridden path
assertThat(Objects.equals(requests.get(0).getPath(), path$.DEFAULT_PATH));
assertThat(Objects.equals(requests.get(1).getPath(), customPath));
} finally {
server.shutdown();
}
}

@Test public void compression() throws Exception {
http.shutdown(); // shutdown the normal zipkin rule

Expand Down

0 comments on commit 0197e96

Please sign in to comment.