forked from openzipkin/brave
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OkHttp Request and Response Interceptor for cs/cr annotations (openzi…
- Loading branch information
1 parent
2d2dd3d
commit ac05b7b
Showing
8 changed files
with
349 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# brave-okhttp # | ||
|
||
This implementation makes it easy to integrate with brave to catch/trace [OkHttp](https://github.com/square/okhttp) requests. The `BraveOkHttpRequestResponseInterceptor` OkHttp [`Interceptor`](http://square.github.io/okhttp/3.x/okhttp/index.html?okhttp3/Interceptor.html) implementation will start a new Span and submit a `cs` (client sent) annotation and then submit `cr` (client received) annotation after the request is received. | ||
|
||
Example of configuring the interceptor with OkHttp: | ||
|
||
``` | ||
import com.github.kristofa.brave.okhttp.BraveOkHttpRequestResponseInterceptor; | ||
import okhttp3.OkHttpClient; | ||
... | ||
OkHttpClient client = new OkHttpClient.Builder() | ||
.addInterceptor(new BraveOkHttpRequestResponseInterceptor(...)) | ||
.build(); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?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>brave</artifactId> | ||
<groupId>com.github.kristofa</groupId> | ||
<version>3.7.1-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>brave-okhttp</artifactId> | ||
|
||
<description>OkHttp request and response interceptor implementation</description> | ||
|
||
<url>https://github.com/kristofa/brave</url> | ||
|
||
<licenses> | ||
<license> | ||
<name>Apache 2</name> | ||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> | ||
<distribution>repo</distribution> | ||
</license> | ||
</licenses> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<okhttp.version>3.2.0</okhttp.version> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.squareup.okhttp3</groupId> | ||
<artifactId>okhttp</artifactId> | ||
<version>${okhttp.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.github.kristofa</groupId> | ||
<artifactId>brave-http</artifactId> | ||
<version>3.7.1-SNAPSHOT</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.squareup.okhttp3</groupId> | ||
<artifactId>mockwebserver</artifactId> | ||
<version>${okhttp.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
38 changes: 38 additions & 0 deletions
38
...src/main/java/com/github/kristofa/brave/okhttp/BraveOkHttpRequestResponseInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.github.kristofa.brave.okhttp; | ||
|
||
|
||
import com.github.kristofa.brave.ClientRequestInterceptor; | ||
import com.github.kristofa.brave.ClientResponseInterceptor; | ||
import com.github.kristofa.brave.http.HttpClientRequestAdapter; | ||
import com.github.kristofa.brave.http.HttpClientResponseAdapter; | ||
import com.github.kristofa.brave.http.SpanNameProvider; | ||
import okhttp3.Interceptor; | ||
import okhttp3.Request; | ||
import okhttp3.Response; | ||
|
||
import java.io.IOException; | ||
|
||
public class BraveOkHttpRequestResponseInterceptor implements Interceptor { | ||
|
||
private final ClientRequestInterceptor clientRequestInterceptor; | ||
private final ClientResponseInterceptor clientResponseInterceptor; | ||
private final SpanNameProvider spanNameProvider; | ||
|
||
public BraveOkHttpRequestResponseInterceptor(ClientRequestInterceptor requestInterceptor, ClientResponseInterceptor responseInterceptor, SpanNameProvider spanNameProvider) { | ||
this.spanNameProvider = spanNameProvider; | ||
this.clientRequestInterceptor = requestInterceptor; | ||
this.clientResponseInterceptor = responseInterceptor; | ||
} | ||
|
||
@Override | ||
public Response intercept(Interceptor.Chain chain) throws IOException { | ||
Request request = chain.request(); | ||
Request.Builder builder = request.newBuilder(); | ||
OkHttpRequest okHttpRequest = new OkHttpRequest(builder, request); | ||
clientRequestInterceptor.handle(new HttpClientRequestAdapter(okHttpRequest, spanNameProvider)); | ||
Response response = chain.proceed(builder.build()); | ||
clientResponseInterceptor.handle(new HttpClientResponseAdapter(new OkHttpResponse(response))); | ||
return response; | ||
} | ||
|
||
} |
34 changes: 34 additions & 0 deletions
34
brave-okhttp/src/main/java/com/github/kristofa/brave/okhttp/OkHttpRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.github.kristofa.brave.okhttp; | ||
|
||
|
||
import com.github.kristofa.brave.http.HttpClientRequest; | ||
import okhttp3.Request; | ||
|
||
import java.net.URI; | ||
|
||
class OkHttpRequest implements HttpClientRequest { | ||
|
||
private final Request.Builder requestBuilder; | ||
private final Request request; | ||
|
||
OkHttpRequest(Request.Builder requestBuilder, Request request) { | ||
this.requestBuilder = requestBuilder; | ||
this.request = request; | ||
} | ||
|
||
@Override | ||
public void addHeader(String header, String value) { | ||
requestBuilder.addHeader(header, value); | ||
} | ||
|
||
@Override | ||
public String getHttpMethod() { | ||
return request.method(); | ||
} | ||
|
||
@Override | ||
public URI getUri() { | ||
return request.url().uri(); | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
brave-okhttp/src/main/java/com/github/kristofa/brave/okhttp/OkHttpResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.github.kristofa.brave.okhttp; | ||
|
||
|
||
import com.github.kristofa.brave.http.HttpResponse; | ||
import okhttp3.Response; | ||
|
||
class OkHttpResponse implements HttpResponse { | ||
|
||
private final Response response; | ||
|
||
OkHttpResponse(Response response) { | ||
this.response = response; | ||
} | ||
|
||
@Override | ||
public int getHttpStatusCode() { | ||
return response.code(); | ||
} | ||
} |
179 changes: 179 additions & 0 deletions
179
...test/java/com/github/kristofa/brave/okhttp/BraveOkHttpRequestResponseInterceptorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
package com.github.kristofa.brave.okhttp; | ||
|
||
import com.github.kristofa.brave.ClientRequestInterceptor; | ||
import com.github.kristofa.brave.ClientResponseInterceptor; | ||
import com.github.kristofa.brave.ClientTracer; | ||
import com.github.kristofa.brave.SpanId; | ||
import com.github.kristofa.brave.TraceKeys; | ||
import com.github.kristofa.brave.http.BraveHttpHeaders; | ||
import com.github.kristofa.brave.http.DefaultSpanNameProvider; | ||
import okhttp3.OkHttpClient; | ||
import okhttp3.Request; | ||
import okhttp3.Response; | ||
import okhttp3.mockwebserver.MockResponse; | ||
import okhttp3.mockwebserver.MockWebServer; | ||
import okhttp3.mockwebserver.RecordedRequest; | ||
import org.junit.Before; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.ExpectedException; | ||
import org.mockito.Answers; | ||
import org.mockito.InOrder; | ||
import org.mockito.Mock; | ||
import org.mockito.MockitoAnnotations; | ||
|
||
import java.io.IOException; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.mockito.Mockito.*; | ||
|
||
public class BraveOkHttpRequestResponseInterceptorTest { | ||
|
||
private static final Long SPAN_ID = 151864l; | ||
private static final Long TRACE_ID = 8494864l; | ||
private static final String HTTP_METHOD_GET = "GET"; | ||
|
||
@Rule | ||
public final ExpectedException thrown = ExpectedException.none(); | ||
@Rule | ||
public final MockWebServer server = new MockWebServer(); | ||
|
||
@Mock(answer = Answers.RETURNS_SMART_NULLS) | ||
private ClientTracer clientTracer; | ||
|
||
private SpanId spanId; | ||
private OkHttpClient client; | ||
|
||
@Before | ||
public void setup() throws IOException { | ||
MockitoAnnotations.initMocks(this); | ||
this.spanId = SpanId.builder().spanId(SPAN_ID).traceId(TRACE_ID).parentId(null).build(); | ||
this.client = new OkHttpClient.Builder() | ||
.addInterceptor(new BraveOkHttpRequestResponseInterceptor(new ClientRequestInterceptor(clientTracer), new ClientResponseInterceptor(clientTracer), new DefaultSpanNameProvider())) | ||
.build(); | ||
} | ||
|
||
@Test | ||
public void testTracingTrue() throws IOException, InterruptedException { | ||
when(clientTracer.startNewSpan(HTTP_METHOD_GET)).thenReturn(spanId); | ||
|
||
String url = "http://localhost:" + server.getPort() + "/foo"; | ||
Request request = new Request.Builder() | ||
.url(url) | ||
.build(); | ||
|
||
server.enqueue(new MockResponse() | ||
.setBody("bar") | ||
.setResponseCode(200) | ||
); | ||
|
||
Response response = client.newCall(request).execute(); | ||
|
||
assertEquals(200, response.code()); | ||
|
||
InOrder inOrder = inOrder(clientTracer); | ||
inOrder.verify(clientTracer).startNewSpan(HTTP_METHOD_GET); | ||
inOrder.verify(clientTracer).submitBinaryAnnotation(TraceKeys.HTTP_URL, url); | ||
inOrder.verify(clientTracer).setClientSent(); | ||
inOrder.verify(clientTracer).setClientReceived(); | ||
verifyNoMoreInteractions(clientTracer); | ||
|
||
RecordedRequest serverRequest = server.takeRequest(); | ||
assertEquals(HTTP_METHOD_GET, serverRequest.getMethod()); | ||
assertEquals("1", serverRequest.getHeader(BraveHttpHeaders.Sampled.getName())); | ||
assertEquals(Long.toString(TRACE_ID, 16), serverRequest.getHeader(BraveHttpHeaders.TraceId.getName())); | ||
assertEquals(Long.toString(SPAN_ID, 16), serverRequest.getHeader(BraveHttpHeaders.SpanId.getName())); | ||
} | ||
|
||
@Test | ||
public void testTracingTrueHttpNoOk() throws IOException, InterruptedException { | ||
when(clientTracer.startNewSpan(HTTP_METHOD_GET)).thenReturn(spanId); | ||
|
||
String url = "http://localhost:" + server.getPort() + "/foo"; | ||
Request request = new Request.Builder() | ||
.url(url) | ||
.build(); | ||
|
||
server.enqueue(new MockResponse() | ||
.setBody("bar") | ||
.setResponseCode(400) | ||
); | ||
|
||
Response response = client.newCall(request).execute(); | ||
|
||
assertEquals(400, response.code()); | ||
|
||
InOrder inOrder = inOrder(clientTracer); | ||
inOrder.verify(clientTracer).startNewSpan(HTTP_METHOD_GET); | ||
inOrder.verify(clientTracer).submitBinaryAnnotation(TraceKeys.HTTP_URL, url); | ||
inOrder.verify(clientTracer).setClientSent(); | ||
inOrder.verify(clientTracer).submitBinaryAnnotation(TraceKeys.HTTP_STATUS_CODE, "400"); | ||
inOrder.verify(clientTracer).setClientReceived(); | ||
verifyNoMoreInteractions(clientTracer); | ||
|
||
RecordedRequest serverRequest = server.takeRequest(); | ||
assertEquals(HTTP_METHOD_GET, serverRequest.getMethod()); | ||
assertEquals("1", serverRequest.getHeader(BraveHttpHeaders.Sampled.getName())); | ||
assertEquals(Long.toString(TRACE_ID, 16), serverRequest.getHeader(BraveHttpHeaders.TraceId.getName())); | ||
assertEquals(Long.toString(SPAN_ID, 16), serverRequest.getHeader(BraveHttpHeaders.SpanId.getName())); | ||
} | ||
|
||
@Test | ||
public void testTracingFalse() throws IOException, InterruptedException { | ||
when(clientTracer.startNewSpan(HTTP_METHOD_GET)).thenReturn(null); | ||
|
||
String url = "http://localhost:" + server.getPort() + "/foo"; | ||
Request request = new Request.Builder() | ||
.url(url) | ||
.build(); | ||
|
||
server.enqueue(new MockResponse() | ||
.setBody("bar") | ||
); | ||
|
||
Response response = client.newCall(request).execute(); | ||
|
||
assertEquals(200, response.code()); | ||
|
||
InOrder inOrder = inOrder(clientTracer); | ||
inOrder.verify(clientTracer).startNewSpan(HTTP_METHOD_GET); | ||
inOrder.verify(clientTracer).setClientReceived(); | ||
verifyNoMoreInteractions(clientTracer); | ||
|
||
RecordedRequest serverRequest = server.takeRequest(); | ||
assertEquals(HTTP_METHOD_GET, serverRequest.getMethod()); | ||
assertEquals("0", serverRequest.getHeader(BraveHttpHeaders.Sampled.getName())); | ||
} | ||
|
||
@Test | ||
public void testQueryParams() throws IOException, InterruptedException { | ||
when(clientTracer.startNewSpan(HTTP_METHOD_GET)).thenReturn(spanId); | ||
|
||
String url = "http://localhost:" + server.getPort() + "/foo?z=2&yAA"; | ||
Request request = new Request.Builder() | ||
.url(url) | ||
.build(); | ||
|
||
server.enqueue(new MockResponse() | ||
.setBody("bar") | ||
); | ||
|
||
Response response = client.newCall(request).execute(); | ||
|
||
assertEquals(200, response.code()); | ||
|
||
InOrder inOrder = inOrder(clientTracer); | ||
inOrder.verify(clientTracer).startNewSpan(HTTP_METHOD_GET); | ||
inOrder.verify(clientTracer).submitBinaryAnnotation(TraceKeys.HTTP_URL, url); | ||
inOrder.verify(clientTracer).setClientSent(); | ||
inOrder.verify(clientTracer).setClientReceived(); | ||
verifyNoMoreInteractions(clientTracer); | ||
|
||
RecordedRequest serverRequest = server.takeRequest(); | ||
assertEquals(HTTP_METHOD_GET, serverRequest.getMethod()); | ||
assertEquals("1", serverRequest.getHeader(BraveHttpHeaders.Sampled.getName())); | ||
assertEquals(Long.toString(TRACE_ID, 16), serverRequest.getHeader(BraveHttpHeaders.TraceId.getName())); | ||
assertEquals(Long.toString(SPAN_ID, 16), serverRequest.getHeader(BraveHttpHeaders.SpanId.getName())); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Configuration status="WARN"> | ||
<Appenders> | ||
<Console name="Console" target="SYSTEM_OUT"> | ||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> | ||
</Console> | ||
</Appenders> | ||
<Loggers> | ||
<Root level="error"> | ||
<AppenderRef ref="Console"/> | ||
</Root> | ||
</Loggers> | ||
</Configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters