Java源码示例:org.apache.http.impl.execchain.ClientExecChain
示例1
@DataProvider(value = {
"true",
"false"
}, splitBy = "\\|")
@Test
public void decorateProtocolExec_uses_subspan_option_value_at_time_of_creation_not_time_of_execution(
boolean subspanOptionOn
) throws IOException, HttpException {
// given
builder = WingtipsHttpClientBuilder.create(subspanOptionOn, tagAndNamingStrategy, tagAndNamingAdapterMock);
Span parentSpan = Tracer.getInstance().startRequestWithRootSpan("someParentSpan");
SpanCapturingClientExecChain origCec = spy(new SpanCapturingClientExecChain());
// when
ClientExecChain result = builder.decorateProtocolExec(origCec);
// Set builder's subspan option to the opposite of what it was when the ClientExecChain was decorated.
builder.setSurroundCallsWithSubspan(!subspanOptionOn);
// then
// Even though the *builder's* subspan option has been flipped, the ClientExecChain should still execute with
// the subspan option value from when the ClientExecChain was originally decorated.
verifyDecoratedClientExecChainPerformsTracingLogic(
result, origCec, parentSpan, subspanOptionOn, null
);
}
示例2
@DataProvider(value = {
"true | true | true",
"false | true | true",
"true | false | true",
"false | false | true",
"true | true | false",
"false | true | false",
"true | false | false",
"false | false | false"
}, splitBy = "\\|")
@Test
public void decorateProtocolExec_works_as_expected(
boolean subspanOptionOn, boolean parentSpanExists, boolean throwExceptionInInnerChain
) throws IOException, HttpException {
// given
builder = WingtipsHttpClientBuilder.create(subspanOptionOn, tagAndNamingStrategy, tagAndNamingAdapterMock);
RuntimeException exceptionToThrowInInnerChain = (throwExceptionInInnerChain)
? new RuntimeException("kaboom")
: null;
SpanCapturingClientExecChain origCec = spy(new SpanCapturingClientExecChain(exceptionToThrowInInnerChain));
Span parentSpan = null;
if (parentSpanExists) {
parentSpan = Tracer.getInstance().startRequestWithRootSpan("someParentSpan");
}
// when
ClientExecChain result = builder.decorateProtocolExec(origCec);
// then
verifyDecoratedClientExecChainPerformsTracingLogic(
result, origCec, parentSpan, subspanOptionOn, exceptionToThrowInInnerChain
);
}
示例3
@Override
protected ClientExecChain decorateMainExec(ClientExecChain mainExec) {
ClientExecChain result = mainExec;
result = addFetchEvent(result);
if (useCache) {
CacheAdapter cacheAdapter = new CacheAdapter();
cacheAdapter.init(properties);
result = cacheAdapter.wrapBackendHttpClient(result);
result = super.decorateMainExec(result);
result = cacheAdapter.wrapCachingHttpClient(result);
}
return result;
}
示例4
/**
* Decorate with fetch event managements
*
* @param wrapped
* @return the decorated ClientExecChain
*/
private ClientExecChain addFetchEvent(final ClientExecChain wrapped) {
return new ClientExecChain() {
@Override
public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request,
HttpClientContext httpClientContext, HttpExecutionAware execAware) throws IOException,
HttpException {
OutgoingRequestContext context = OutgoingRequestContext.adapt(httpClientContext);
// Create request event
FetchEvent fetchEvent = new FetchEvent(context, request);
eventManager.fire(EventManager.EVENT_FETCH_PRE, fetchEvent);
if (fetchEvent.isExit()) {
if (fetchEvent.getHttpResponse() == null) {
// Provide an error page in order to avoid a NullPointerException
fetchEvent.setHttpResponse(HttpErrorPage.generateHttpResponse(
HttpStatus.SC_INTERNAL_SERVER_ERROR,
"An extension stopped the processing of the request without providing a response"));
}
} else {
try {
fetchEvent.setHttpResponse(wrapped.execute(route, request, context, execAware));
eventManager.fire(EventManager.EVENT_FETCH_POST, fetchEvent);
} catch (IOException | HttpException e) {
fetchEvent.setHttpResponse(HttpErrorPage.generateHttpResponse(e));
// Usually we want to render and cache the exception but we let an extension decide
fetchEvent.setExit(true);
eventManager.fire(EventManager.EVENT_FETCH_POST, fetchEvent);
if (!fetchEvent.isExit())
throw e; // Throw the exception and let http client process it (may retry)
}
}
return fetchEvent.getHttpResponse();
}
};
}
示例5
TracingMainExec(HttpTracing httpTracing, ClientExecChain mainExec) {
this.tracer = httpTracing.tracing().tracer();
this.currentTraceContext = httpTracing.tracing().currentTraceContext();
this.serverName = "".equals(httpTracing.serverName()) ? null : httpTracing.serverName();
this.handler = HttpClientHandler.create(httpTracing);
this.mainExec = mainExec;
}
示例6
SignatureExec(Credentials credentials, Validator validator, ClientExecChain mainExec) {
this.credentials = credentials;
this.validator = validator;
this.mainExec = mainExec;
}
示例7
@Override
protected ClientExecChain decorateProtocolExec(final ClientExecChain requestExecutor) {
return new SignatureExec(this.credentials, this.validator, requestExecutor);
}
示例8
public ProxyFeedBackClientExecChain(ClientExecChain delegate) {
this.delegate = delegate;
}
示例9
@Override
protected ClientExecChain decorateProtocolExec(ClientExecChain protocolExec) {
return new ProxyFeedBackClientExecChain(protocolExec);
}
示例10
private void verifyDecoratedClientExecChainPerformsTracingLogic(
ClientExecChain decoratedCec, SpanCapturingClientExecChain origCecSpy, Span parentSpan,
boolean expectSubspan, Throwable expectedError
) throws IOException, HttpException {
// given
HttpRoute httpRoute = new HttpRoute(new HttpHost("localhost"));
HttpRequestWrapper requestWrapperSpy = spy(HttpRequestWrapper.wrap(requestMock));
HttpClientContext httpClientContextMock = mock(HttpClientContext.class);
HttpExecutionAware httpExecutionAwareMock = mock(HttpExecutionAware.class);
assertThat(origCecSpy.capturedSpan).isNull();
assertThat(spanRecorder.completedSpans).isEmpty();
// when
CloseableHttpResponse result = null;
Throwable exFromChain = null;
try {
result = decoratedCec.execute(
httpRoute, requestWrapperSpy, httpClientContextMock, httpExecutionAwareMock
);
}
catch (Throwable ex) {
exFromChain = ex;
}
// then
verify(origCecSpy).execute(httpRoute, requestWrapperSpy, httpClientContextMock, httpExecutionAwareMock);
if (origCecSpy.exceptionToThrow == null) {
assertThat(result).isSameAs(origCecSpy.response);
}
else {
assertThat(exFromChain).isSameAs(origCecSpy.exceptionToThrow);
}
// The only time the capturedSpan should be null is if expectSubspan is false and parentSpan is null, and then
// no tracing propagation headers should have been set.
// Otherwise, the tracing propagation headers should match capturedSpan.
if (origCecSpy.capturedSpan == null) {
assertThat(expectSubspan).isFalse();
assertThat(parentSpan).isNull();
verify(requestWrapperSpy, never()).setHeader(anyString(), anyString());
}
else {
verify(requestWrapperSpy).setHeader(TRACE_ID, origCecSpy.capturedSpan.getTraceId());
verify(requestWrapperSpy).setHeader(SPAN_ID, origCecSpy.capturedSpan.getSpanId());
verify(requestWrapperSpy).setHeader(
TRACE_SAMPLED, convertSampleableBooleanToExpectedB3Value(origCecSpy.capturedSpan.isSampleable())
);
if (origCecSpy.capturedSpan.getParentSpanId() == null) {
verify(requestWrapperSpy, never()).setHeader(eq(PARENT_SPAN_ID), anyString());
}
else {
verify(requestWrapperSpy).setHeader(PARENT_SPAN_ID, origCecSpy.capturedSpan.getParentSpanId());
}
}
// If we have a subspan, then it should have been completed. Otherwise, no spans should have been completed.
// Also, if we have a subspan, then request and response tagging should have been done.
if (expectSubspan) {
assertThat(spanRecorder.completedSpans).containsExactly(origCecSpy.capturedSpan);
// Verify the request tags were set
assertThat(strategyInitialSpanNameMethodCalled.get()).isTrue();
assertThat(strategyInitialSpanNameArgs.get()).isNotNull();
strategyInitialSpanNameArgs.get().verifyArgs(requestWrapperSpy, tagAndNamingAdapterMock);
assertThat(strategyRequestTaggingMethodCalled.get()).isTrue();
assertThat(strategyRequestTaggingArgs.get()).isNotNull();
strategyRequestTaggingArgs.get().verifyArgs(
origCecSpy.capturedSpan, requestWrapperSpy, tagAndNamingAdapterMock
);
// Verify the response tags were set
assertThat(strategyResponseTaggingAndFinalSpanNameMethodCalled.get()).isTrue();
assertThat(strategyResponseTaggingArgs.get()).isNotNull();
strategyResponseTaggingArgs.get().verifyArgs(
origCecSpy.capturedSpan, requestWrapperSpy, result, expectedError, tagAndNamingAdapterMock
);
}
else {
assertThat(spanRecorder.completedSpans).isEmpty();
// None of the tag/naming stuff should have been called since there was no subspan.
assertThat(strategyInitialSpanNameMethodCalled.get()).isFalse();
assertThat(strategyInitialSpanNameArgs.get()).isNull();
assertThat(strategyRequestTaggingMethodCalled.get()).isFalse();
assertThat(strategyRequestTaggingArgs.get()).isNull();
assertThat(strategyResponseTaggingAndFinalSpanNameMethodCalled.get()).isFalse();
assertThat(strategyResponseTaggingArgs.get()).isNull();
}
}
示例11
@Override
protected ClientExecChain decorateMainExec(ClientExecChain mainExec) {
return mainExec;
}
示例12
public ClientExecChain wrapCachingHttpClient(final ClientExecChain wrapped) {
return new ClientExecChain() {
/**
* Removes client http cache directives like "Cache-control" and "Pragma". Users must not be able to bypass
* the cache just by making a refresh in the browser. Generates X-cache header.
*
*/
@Override
public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request,
HttpClientContext httpClientContext, HttpExecutionAware execAware) throws IOException,
HttpException {
OutgoingRequestContext context = OutgoingRequestContext.adapt(httpClientContext);
// Switch route for the cache to generate the right cache key
CloseableHttpResponse response = wrapped.execute(route, request, context, execAware);
// Remove previously added Cache-control header
if (request.getRequestLine().getMethod().equalsIgnoreCase("GET")
&& (staleWhileRevalidate > 0 || staleIfError > 0)) {
response.removeHeader(response.getLastHeader("Cache-control"));
}
// Add X-cache header
if (xCacheHeader) {
if (context != null) {
CacheResponseStatus cacheResponseStatus =
(CacheResponseStatus) context.getAttribute(HttpCacheContext.CACHE_RESPONSE_STATUS);
String xCacheString;
if (cacheResponseStatus.equals(CacheResponseStatus.CACHE_HIT)) {
xCacheString = "HIT";
} else if (cacheResponseStatus.equals(CacheResponseStatus.VALIDATED)) {
xCacheString = "VALIDATED";
} else {
xCacheString = "MISS";
}
xCacheString += " from " + route.getTargetHost().toHostString();
xCacheString +=
" (" + request.getRequestLine().getMethod() + " " + request.getRequestLine().getUri()
+ ")";
response.addHeader("X-Cache", xCacheString);
}
}
// Remove Via header
if (!viaHeader && response.containsHeader("Via")) {
response.removeHeaders("Via");
}
return response;
}
};
}
示例13
@Override protected ClientExecChain decorateProtocolExec(ClientExecChain protocolExec) {
return new TracingProtocolExec(httpTracing, protocolExec);
}
示例14
@Override protected ClientExecChain decorateMainExec(ClientExecChain exec) {
return new TracingMainExec(httpTracing, exec);
}
示例15
@Override protected ClientExecChain decorateProtocolExec(ClientExecChain protocolExec) {
return new TracingProtocolExec(httpTracing, protocolExec);
}
示例16
@Override protected ClientExecChain decorateMainExec(ClientExecChain exec) {
return new LocalIfFromCacheTracingMainExec(httpTracing, super.decorateMainExec(exec));
}
示例17
LocalIfFromCacheTracingMainExec(HttpTracing httpTracing, ClientExecChain mainExec) {
super(httpTracing, mainExec);
}
示例18
TracingProtocolExec(HttpTracing httpTracing, ClientExecChain protocolExec) {
this.tracer = httpTracing.tracing().tracer();
this.httpSampler = httpTracing.clientRequestSampler();
this.handler = HttpClientHandler.create(httpTracing);
this.protocolExec = protocolExec;
}