package brave.http.features; import brave.Span; import brave.Tracer; import brave.http.HttpServerAdapter; import brave.http.HttpServerHandler; import brave.http.HttpTracing; import brave.propagation.TraceContext; import okhttp3.mockwebserver.Dispatcher; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.RecordedRequest; final class TracingDispatcher extends Dispatcher { final Dispatcher delegate; final Tracer tracer; final HttpServerHandler<RecordedRequest, MockResponse> handler; final TraceContext.Extractor<RecordedRequest> extractor; TracingDispatcher(HttpTracing httpTracing, Dispatcher delegate) { tracer = httpTracing.tracing().tracer(); handler = HttpServerHandler.create(httpTracing, new MockWebServerAdapter()); extractor = httpTracing.tracing().propagation().extractor(RecordedRequest::getHeader); this.delegate = delegate; } @Override public MockResponse dispatch(RecordedRequest request) throws InterruptedException { Span span = handler.handleReceive(extractor, request); MockResponse response = null; Throwable error = null; try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) { return response = delegate.dispatch(request); } catch (InterruptedException | RuntimeException | Error e) { error = e; throw e; } finally { handler.handleSend(response, error, span); } } static final class MockWebServerAdapter extends HttpServerAdapter<RecordedRequest, MockResponse> { @Override public String method(RecordedRequest request) { return request.getMethod(); } @Override public String path(RecordedRequest request) { return request.getPath(); } @Override public String url(RecordedRequest request) { return request.getRequestUrl().toString(); } @Override public String requestHeader(RecordedRequest request, String name) { return request.getHeader(name); } @Override public Integer statusCode(MockResponse response) { return Integer.parseInt(response.getStatus().split(" ")[1]); } } }