Skip to content

Commit

Permalink
Add wiremock tests for HttpClient 5.x instrumentation
Browse files Browse the repository at this point in the history
See gh-3800
Closes gh-3941
  • Loading branch information
cachescrubber authored and bclozel committed Jun 28, 2023
1 parent 85d501b commit 80e8682
Show file tree
Hide file tree
Showing 4 changed files with 454 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ public class DefaultApacheHttpClientObservationConvention implements ApacheHttpC

private static final KeyValue URI_UNKNOWN = KeyValue.of(ApacheHttpClientKeyNames.URI, "UNKNOWN");

private static final KeyValue STATUS_IOERROR = KeyValue.of(ApacheHttpClientKeyNames.STATUS, "IO_ERROR");
private static final KeyValue STATUS_IO_ERROR = KeyValue.of(ApacheHttpClientKeyNames.STATUS, "IO_ERROR");

private static final KeyValue STATUS_CLIENTERROR = KeyValue.of(ApacheHttpClientKeyNames.STATUS, "CLIENT_ERROR");
private static final KeyValue STATUS_CLIENT_ERROR = KeyValue.of(ApacheHttpClientKeyNames.STATUS, "CLIENT_ERROR");

private static final KeyValue EXCEPTION_NONE = KeyValue.of(ApacheHttpClientKeyNames.EXCEPTION, KeyValue.NONE_VALUE);

Expand Down Expand Up @@ -106,10 +106,10 @@ protected KeyValue status(ApacheHttpClientContext context) {
Throwable error = context.getError();
HttpResponse response = context.getResponse();
if (error instanceof IOException || error instanceof HttpException || error instanceof RuntimeException) {
return STATUS_IOERROR;
return STATUS_IO_ERROR;
}
else if (response == null) {
return STATUS_CLIENTERROR;
return STATUS_CLIENT_ERROR;
}
return KeyValue.of(ApacheHttpClientKeyNames.STATUS, Integer.toString(response.getCode()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
import org.apache.hc.client5.http.classic.ExecChain;
import org.apache.hc.client5.http.classic.ExecChainHandler;
import org.apache.hc.client5.http.impl.ChainElement;
import org.apache.hc.core5.concurrent.Cancellable;
import org.apache.hc.core5.concurrent.CancellableDependency;
import org.apache.hc.core5.http.*;
Expand All @@ -42,15 +43,17 @@
* <p>
* For a "classic" client, it can be configured as an interceptor in the chain: <pre>
* CloseableHttpClient client = HttpClientBuilder.create()
* .addExecInterceptorFirst("micrometer", new ObservationExecChainHandler(observationRegistry))
* .addExecInterceptorLast("micrometer", new ObservationExecChainHandler(observationRegistry))
* .build()
* </pre>
* <p>
* For an "async" client, it can also be configured as an interceptor in the chain: <pre>
* CloseableHttpAsyncClient client = HttpAsyncClients.custom()
* .addExecInterceptorFirst("micrometer", new ObservationExecChainHandler(observationRegistry))
* .addExecInterceptorLast("micrometer", new ObservationExecChainHandler(observationRegistry))
* .build();
* </pre>
* <p>Note that the {@link ObservationExecChainHandler} must always be inserted after the
* {@link ChainElement#RETRY retry interceptor}, preferably last.
*
* @author Brian Clozel
* @since 1.12.0
Expand All @@ -62,6 +65,7 @@ public class ObservationExecChainHandler implements ExecChainHandler, AsyncExecC
@Nullable
private final ApacheHttpClientObservationConvention observationConvention;


public ObservationExecChainHandler(ObservationRegistry observationRegistry,
@Nullable ApacheHttpClientObservationConvention observationConvention) {
this.observationRegistry = observationRegistry;
Expand All @@ -72,20 +76,21 @@ public ObservationExecChainHandler(ObservationRegistry observationRegistry) {
this(observationRegistry, null);
}


@Override
public void execute(HttpRequest request, AsyncEntityProducer entityProducer, AsyncExecChain.Scope scope,
AsyncExecChain chain, AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
ApacheHttpClientContext observationContext = new ApacheHttpClientContext(request, scope.clientContext);
Observation observation = ApacheHttpClientObservationDocumentation.DEFAULT
.observation(observationConvention, DefaultApacheHttpClientObservationConvention.INSTANCE,
() -> observationContext, observationRegistry)
() -> observationContext, observationRegistry)
.start();
ObervableCancellableDependency cancellable = new ObervableCancellableDependency(observation);
chain.proceed(request, entityProducer, cancellable.wrapScope(scope), new AsyncExecCallback() {

@Override
public AsyncDataConsumer handleResponse(HttpResponse response, EntityDetails entityDetails)
throws HttpException, IOException {
throws HttpException, IOException {
observationContext.setResponse(response);
observation.stop();
return asyncExecCallback.handleResponse(response, entityDetails);
Expand All @@ -109,7 +114,6 @@ public void failed(Exception cause) {
}

});

}

@Override
Expand Down

0 comments on commit 80e8682

Please sign in to comment.