Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jkunle committed Jan 31, 2025
1 parent 8019cbb commit 0c8bd74
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 2 deletions.
9 changes: 7 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ subprojects {

soap "com.sun.xml.messaging.saaj:saaj-impl:1.5.3",
"org.apache.cxf:cxf-rt-frontend-jaxws:3.4.5",
"org.apache.cxf:cxf-rt-transports-http:3.4.5"
"org.apache.cxf:cxf-rt-transports-http:3.4.5",
"org.apache.httpcomponents:httpclient:4.1.4"

powertools "software.amazon.lambda:powertools-logging:${dependencyVersions.powertools_version}",
"software.amazon.lambda:powertools-metrics:${dependencyVersions.powertools_version}",
Expand Down Expand Up @@ -136,7 +137,11 @@ subprojects {
"uk.org.webcompere:system-stubs-jupiter:${dependencyVersions.webcompere_version}"

otel "io.opentelemetry.instrumentation:opentelemetry-aws-sdk-2.2-autoconfigure:2.12.0-alpha",
"io.opentelemetry.instrumentation:opentelemetry-java-http-client:2.12.0-alpha"
"io.opentelemetry.instrumentation:opentelemetry-java-http-client:2.12.0-alpha",

'io.opentelemetry:opentelemetry-sdk:1.29.0',
'io.opentelemetry:opentelemetry-sdk-logs:1.29.0',
'io.opentelemetry:opentelemetry-exporter-otlp:1.29.0'
}

apply plugin: 'java'
Expand Down
2 changes: 2 additions & 0 deletions lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ repositories {
}

dependencies {
implementation configurations.otel

implementation configurations.cri_common_lib,
configurations.aws,
configurations.dynamodb,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package uk.gov.di.ipv.cri.kbv.api.service;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.httpclient.JavaHttpClientTelemetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.http.HttpClient;
import java.time.Duration;

public class OtelHttpClientWrapper {
private static final Logger LOGGER = LoggerFactory.getLogger(OtelHttpClientWrapper.class);
private final HttpClient telemetryHttpClient;

public OtelHttpClientWrapper() {
this.telemetryHttpClient = createTelemetryHttpClient();
}

private HttpClient createTelemetryHttpClient() {
LOGGER.info("Creating OpenTelemetry-instrumented HttpClient.");

return JavaHttpClientTelemetry.builder(GlobalOpenTelemetry.get())
.build()
.newHttpClient(
HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.followRedirects(HttpClient.Redirect.NORMAL)
.build());
}

public HttpClient getTelemetryHttpClient() {
return telemetryHttpClient;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package uk.gov.di.ipv.cri.kbv.api.service;

import org.apache.cxf.Bus;
import org.apache.cxf.message.Message;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.transport.http.Address;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.apache.cxf.ws.addressing.EndpointReferenceType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

public class OtelHttpConduit extends HTTPConduit {
private static final Logger LOGGER = LoggerFactory.getLogger(OtelHttpConduit.class);

private final OtelHttpClientWrapper otelHttpClientWrapper;
private final HttpClient httpClient;

public OtelHttpConduit(
Bus bus,
EndpointInfo endpointInfo,
EndpointReferenceType target,
OtelHttpClientWrapper otelHttpClientWrapper)
throws IOException {
super(bus, endpointInfo, target);
this.otelHttpClientWrapper = otelHttpClientWrapper;
this.httpClient = otelHttpClientWrapper.getTelemetryHttpClient();
}

@Override
protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy)
throws IOException {
LOGGER.info("Setting up connection for URL: {}", address.getString());
if (csPolicy != null) {
LOGGER.info("Applying HTTP client policy settings...");
}
}

@Override
protected OutputStream createOutputStream(
Message message, boolean needToCacheRequest, boolean isChunking, int chunkThreshold)
throws IOException {
LOGGER.info("Creating output stream for HTTP request.");
return new ByteArrayOutputStream();
}

@Override
public void close() {
LOGGER.info("Closing OtelHttpConduit.");
super.close();
}

/** Sends an HTTP request asynchronously using the OpenTelemetry instrumented HttpClient. */
public CompletableFuture<HttpResponse<String>> sendRequestAsync(String url) {
try {
URI uri = URI.create(url);
HttpRequest request = HttpRequest.newBuilder().uri(uri).GET().build();

LOGGER.info("Sending HTTP request to {}", url);
return httpClient
.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(
response -> {
LOGGER.info(
"Received response with status: {}", response.statusCode());
return response;
});
} catch (Exception e) {
LOGGER.error("Error sending HTTP request", e);
CompletableFuture<HttpResponse<String>> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(e);
return failedFuture;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package uk.gov.di.ipv.cri.kbv.api.service;

import org.apache.cxf.Bus;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.HTTPConduitFactory;
import org.apache.cxf.transport.http.HTTPTransportFactory;
import org.apache.cxf.ws.addressing.EndpointReferenceType;

import java.io.IOException;

public class OtelHttpConduitFactory implements HTTPConduitFactory {
private final OtelHttpClientWrapper otelHttpClientWrapper;

public OtelHttpConduitFactory() {
this.otelHttpClientWrapper = new OtelHttpClientWrapper();
}

@Override
public HTTPConduit createConduit(
HTTPTransportFactory factory,
Bus bus,
EndpointInfo endpointInfo,
EndpointReferenceType target)
throws IOException {
return new OtelHttpConduit(bus, endpointInfo, target, otelHttpClientWrapper);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import com.experian.uk.schema.experian.identityiq.services.webservice.IdentityIQWebService;
import com.experian.uk.wasp.TokenService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.transport.http.HTTPConduitFactory;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.lambda.powertools.parameters.SSMProvider;
Expand Down Expand Up @@ -89,6 +92,9 @@ KBVGateway getKbvGateway(KeyStoreLoader keyStoreLoader, KBVClientFactory kbvClie
}

private KBVClientFactory getKbvClientFactory() {
Bus bus = BusFactory.getDefaultBus();
bus.setExtension(new OtelHttpConduitFactory(), HTTPConduitFactory.class);

TokenService tokenService = new TokenService();
SoapToken soapToken = new SoapToken(APPLICATION, true, tokenService, configurationService);
HeaderHandler headerHandler = new HeaderHandler(soapToken);
Expand Down

0 comments on commit 0c8bd74

Please sign in to comment.