Skip to content

Commit

Permalink
Bytt ut jetty client med hc 5 (#275)
Browse files Browse the repository at this point in the history
* Fjerner avhengighet av Jetty

* Trenger ikke være avhengig av maskinporten token

* Optimize imports

* Sett contenttype på part 2
  • Loading branch information
zapodot authored Oct 3, 2023
1 parent e742e25 commit ea017ad
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 156 deletions.
29 changes: 12 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</parent>
<groupId>no.ks.fiks</groupId>
<artifactId>fiks-io-send-klient</artifactId>
<version>3.0.3-SNAPSHOT</version>
<version>3.1.0-SNAPSHOT</version>
<name>FIKS IO send-klient</name>
<description>Klient for å sende meldinger til FIKS IO</description>
<url>https://github.com/ks-no/fiks-io</url>
Expand All @@ -24,19 +24,19 @@
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<enforcer.jdk.version>${java.version}</enforcer.jdk.version>
<mockito.version>5.5.0</mockito.version>

<apache-httpclient5.version>5.2.1</apache-httpclient5.version>
<assertj.version>3.24.2</assertj.version>
<commons-io.version>2.14.0</commons-io.version>
<jackson.version>2.15.2</jackson.version>
<revision>1.2.8</revision>
<lombok.version>1.18.24</lombok.version>
<junit-jupiter.version>5.10.0</junit-jupiter.version>
<jetty-client.version>11.0.16</jetty-client.version>
<validation-api.version>3.0.2</validation-api.version>
<logback-classic.version>1.4.11</logback-classic.version>
<commons-io.version>2.14.0</commons-io.version>
<lombok.version>1.18.24</lombok.version>
<maskinporten-client.version>3.1.4</maskinporten-client.version>
<assertj.version>3.24.2</assertj.version>
<slf4j.version>2.0.9</slf4j.version>
<mockito.version>5.5.0</mockito.version>
<mockserver.version>5.15.0</mockserver.version>
<slf4j.version>2.0.9</slf4j.version>
<validation-api.version>3.0.2</validation-api.version>
</properties>
<dependencyManagement>
<dependencies>
Expand Down Expand Up @@ -80,11 +80,6 @@
<artifactId>jakarta.validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${jetty-client.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
Expand All @@ -99,9 +94,9 @@
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>no.ks.fiks</groupId>
<artifactId>maskinporten-client</artifactId>
<version>${maskinporten-client.version}</version>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>${apache-httpclient5.version}</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package no.ks.fiks.io.klient;

import org.eclipse.jetty.client.api.Request;
import org.apache.hc.core5.http.ClassicHttpRequest;

public interface AuthenticationStrategy {
void setAuthenticationHeaders(Request request);
void setAuthenticationHeaders(ClassicHttpRequest request);
}
72 changes: 32 additions & 40 deletions src/main/java/no/ks/fiks/io/klient/FiksIOUtsendingKlient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,79 +5,71 @@
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.InputStreamRequestContent;
import org.eclipse.jetty.client.util.InputStreamResponseListener;
import org.eclipse.jetty.client.util.MultiPartRequestContent;
import org.eclipse.jetty.client.util.StringRequestContent;
import org.apache.hc.client5.http.entity.mime.InputStreamBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpStatus;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;

import static org.eclipse.jetty.http.HttpStatus.isClientError;
import static org.eclipse.jetty.http.HttpStatus.isServerError;

@Slf4j
public class FiksIOUtsendingKlient implements Closeable {

private final RequestFactory requestFactory;
private final AuthenticationStrategy authenticationStrategy;
private final Function<Request, Request> requestInterceptor;

private final Function<ClassicHttpRequest, ClassicHttpRequest> requestInterceptor;
private final CloseableHttpClient client;
private final ObjectMapper objectMapper;

FiksIOUtsendingKlient(@NonNull final RequestFactory requestFactory,
@NonNull AuthenticationStrategy authenticationStrategy,
@NonNull Function<Request, Request> requestInterceptor,
@NonNull final ObjectMapper objectMapper) {
@NonNull Function<ClassicHttpRequest, ClassicHttpRequest> requestInterceptor,
@NonNull final ObjectMapper objectMapper,
@NonNull final CloseableHttpClient client) {
this.requestFactory = requestFactory;
this.authenticationStrategy = authenticationStrategy;
this.requestInterceptor = requestInterceptor;
this.objectMapper = objectMapper;
this.client = client;
}

public static FiksIOUtsendingKlientBuilder builder() {
return new FiksIOUtsendingKlientBuilder();
}

public SendtMeldingApiModel send(@NonNull MeldingSpesifikasjonApiModel metadata, @NonNull Optional<InputStream> data) {
MultiPartRequestContent multipartRequestContent = createMultiPartContent(metadata, data);
InputStreamResponseListener listener = new InputStreamResponseListener();
final Request request = requestFactory.createSendToFiksIORequest(multipartRequestContent);
final ClassicHttpRequest request = requestFactory.createSendToFiksIORequest(createMultiPartContent(metadata, data));
authenticationStrategy.setAuthenticationHeaders(request);
requestInterceptor.apply(request);

requestInterceptor.apply(request).send(listener);

try (InputStream listenerInputStream = listener.getInputStream()) {
Response response = listener.get(1, TimeUnit.HOURS);
if (isClientError(response.getStatus()) || isServerError(response.getStatus())) {
int status = response.getStatus();
String content = IOUtils.toString(listenerInputStream, StandardCharsets.UTF_8);
throw new FiksIOHttpException(String.format("HTTP-feil under sending av melding (%d): %s", status, content), status, content);
}
return objectMapper.readValue(listenerInputStream, SendtMeldingApiModel.class);
} catch (InterruptedException | TimeoutException | ExecutionException | IOException e) {
try {
return client.execute(request, response -> {
final int responseCode = response.getCode();
log.debug("Response status: {}", responseCode);
if (responseCode >= HttpStatus.SC_BAD_REQUEST) {
final var contentAsString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
throw new FiksIOHttpException(String.format("HTTP-feil under sending av melding (%d): %s", responseCode, contentAsString), responseCode, contentAsString);
}
return objectMapper.readValue(response.getEntity().getContent(), SendtMeldingApiModel.class);
});
} catch (IOException e) {
throw new RuntimeException("Feil under invokering av FIKS IO api", e);
}

}

private MultiPartRequestContent createMultiPartContent(@NonNull MeldingSpesifikasjonApiModel metadata, @NonNull Optional<InputStream> data) {
var multipartRequestContent = new MultiPartRequestContent();
multipartRequestContent.addFieldPart("metadata", new StringRequestContent("application/json", serialiser(metadata), StandardCharsets.UTF_8), null);
data.ifPresent(inputStream ->
multipartRequestContent.addFilePart("data", UUID.randomUUID().toString(), new InputStreamRequestContent(inputStream), null));
multipartRequestContent.close();
return multipartRequestContent;
private HttpEntity createMultiPartContent(@NonNull MeldingSpesifikasjonApiModel metadata, @NonNull Optional<InputStream> data) {
var multipartRequestContentBuilder = MultipartEntityBuilder.create()
.addBinaryBody("metadata", serialiser(metadata).getBytes(StandardCharsets.UTF_8), ContentType.APPLICATION_JSON, null);
data.ifPresent(inputStream -> multipartRequestContentBuilder.addPart("data", new InputStreamBody(inputStream, ContentType.APPLICATION_OCTET_STREAM)));
return multipartRequestContentBuilder.build();
}

private String serialiser(@NonNull Object metadata) {
Expand All @@ -90,6 +82,6 @@ private String serialiser(@NonNull Object metadata) {

@Override
public void close() throws IOException {
requestFactory.close();
client.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.util.TimeValue;

import java.time.Duration;
import java.util.function.Function;

/**
Expand All @@ -15,8 +17,6 @@
@Slf4j
public class FiksIOUtsendingKlientBuilder {

private HttpClient httpClient;

private String scheme = "https";

private String hostName;
Expand All @@ -25,11 +25,17 @@ public class FiksIOUtsendingKlientBuilder {

private AuthenticationStrategy authenticationStrategy;

private Function<Request, Request> requestInterceptor;
private Function<ClassicHttpRequest, ClassicHttpRequest> requestInterceptor;

private ObjectMapper objectMapper;

public FiksIOUtsendingKlientBuilder withHttpClient(@NonNull final HttpClient httpClient) {
private CloseableHttpClient httpClient = HttpClients.custom()
.disableAutomaticRetries()
.useSystemProperties()
.evictIdleConnections(TimeValue.of(Duration.ofMinutes(1L)))
.build();

public FiksIOUtsendingKlientBuilder withHttpClient(@NonNull final CloseableHttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
Expand All @@ -54,7 +60,7 @@ public FiksIOUtsendingKlientBuilder withAuthenticationStrategy(@NonNull final Au
return this;
}

public FiksIOUtsendingKlientBuilder withRequestInterceptor(Function<Request, Request> requestInterceptor) {
public FiksIOUtsendingKlientBuilder withRequestInterceptor(Function<ClassicHttpRequest, ClassicHttpRequest> requestInterceptor) {
this.requestInterceptor = requestInterceptor;
return this;
}
Expand All @@ -70,7 +76,8 @@ public FiksIOUtsendingKlient build() {
createRequestFactory(),
authenticationStrategy,
getOrCreateRequestInterceptor(),
getOrCreateObjectMapper()
getOrCreateObjectMapper(),
httpClient
);
}

Expand All @@ -82,7 +89,7 @@ private RequestFactory createRequestFactory() {
.build();
}

private Function<Request, Request> getOrCreateRequestInterceptor() {
private Function<ClassicHttpRequest, ClassicHttpRequest> getOrCreateRequestInterceptor() {
return requestInterceptor == null ? request -> request : requestInterceptor;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,33 @@
package no.ks.fiks.io.klient;

import no.ks.fiks.maskinporten.AccessTokenRequest;
import no.ks.fiks.maskinporten.MaskinportenklientOperations;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpHeader;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.message.BasicHeader;

import java.util.UUID;
import java.util.function.Supplier;

public class IntegrasjonAuthenticationStrategy implements AuthenticationStrategy {

static final String INTEGRASJON_ID = "IntegrasjonId";

static final String INTEGRASJON_PASSWORD = "IntegrasjonPassord";

private final MaskinportenklientOperations maskinportenklient;
private final Supplier<String> maskinportenTokenSupplier;
private final UUID integrasjonId;
private final String integrasjonPassord;

public IntegrasjonAuthenticationStrategy(MaskinportenklientOperations maskinportenklient, UUID integrasjonId, String integrasjonPassord) {
this.maskinportenklient = maskinportenklient;
public IntegrasjonAuthenticationStrategy(Supplier<String> maskinportenTokenSupplier, UUID integrasjonId, String integrasjonPassord) {
this.maskinportenTokenSupplier = maskinportenTokenSupplier;
this.integrasjonId = integrasjonId;
this.integrasjonPassord = integrasjonPassord;
}

@Override
public void setAuthenticationHeaders(Request request) {
request.headers(m -> m.add(HttpHeader.AUTHORIZATION, "Bearer " + getAccessToken())
.add(INTEGRASJON_ID, integrasjonId.toString())
.add(INTEGRASJON_PASSWORD, integrasjonPassord));
public void setAuthenticationHeaders(ClassicHttpRequest request) {
request.addHeader(new BasicHeader(HttpHeaders.AUTHORIZATION, "Bearer " + maskinportenTokenSupplier.get()));
request.addHeader(new BasicHeader(INTEGRASJON_ID, integrasjonId.toString()));
request.addHeader(new BasicHeader(INTEGRASJON_PASSWORD, integrasjonPassord));
}

private String getAccessToken() {
return maskinportenklient.getAccessToken(AccessTokenRequest.builder().scope("ks:fiks").build());
}
}
13 changes: 6 additions & 7 deletions src/main/java/no/ks/fiks/io/klient/RequestFactory.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package no.ks.fiks.io.klient;

import org.eclipse.jetty.client.api.Request;

import java.io.Closeable;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.HttpEntity;

/**
* Factory for nye send requester
*/
public interface RequestFactory extends Closeable {
public interface RequestFactory {

/**
* Oppretter ny {@link Request} for å sende til fiks-io
* Oppretter ny {@link ClassicHttpRequest} for å sende til fiks-io
* @param contentProvider innhold som skal sendes
* @return en ny {@link Request}
* @return en ny {@link ClassicHttpRequest}
*/
Request createSendToFiksIORequest(Request.Content contentProvider);
ClassicHttpRequest createSendToFiksIORequest(HttpEntity contentProvider);
}
37 changes: 11 additions & 26 deletions src/main/java/no/ks/fiks/io/klient/RequestFactoryImpl.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package no.ks.fiks.io.klient;

import lombok.Builder;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpMethod;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.HttpEntity;

import java.time.Duration;
import java.net.URI;

public class RequestFactoryImpl implements RequestFactory {
static final String BASE_PATH = "/fiks-io/api/v1/";
private final HttpClient client;
private final String scheme;
private final String hostName;
private final Integer portNumber;
Expand All @@ -19,31 +18,17 @@ public RequestFactoryImpl(String scheme, String hostName, Integer portNumber) {
this.scheme = scheme;
this.hostName = hostName;
this.portNumber = portNumber;

this.client = new HttpClient();
this.client.setIdleTimeout(Duration.ofMinutes(1).toMillis());
try {
client.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
public Request createSendToFiksIORequest(Request.Content contentProvider) {
return client.newRequest(hostName, portNumber)
.scheme(scheme)
.method(HttpMethod.POST)
.path(BASE_PATH + "send")
.body(contentProvider);
public ClassicHttpRequest createSendToFiksIORequest(final HttpEntity contentProvider) {
return createPostRequest(contentProvider);
}

@Override
public void close() {
try {
client.stop();
} catch (Exception e) {
throw new RuntimeException(e);
}
private HttpPost createPostRequest(final HttpEntity contentProvider){
final HttpPost httpPost = new HttpPost(URI.create(scheme + "://" + hostName + ":" + portNumber + BASE_PATH + "send"));
httpPost.setEntity(contentProvider);
return httpPost;
}

}
Loading

0 comments on commit ea017ad

Please sign in to comment.