Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ Licensed under Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.html
This software includes third party software subject to the following licenses:

Angus Activation Registries under EDL 1.0
Apache Commons Codec under Apache License, Version 2.0
Apache Commons Lang under Apache License, Version 2.0
Apache HttpClient under Apache License, Version 2.0
Apache HttpCore under Apache License, Version 2.0
Apache HttpComponents Core HTTP/1.1 under Apache License, Version 2.0
Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence
Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence
Bouncy Castle Provider under Bouncy Castle Licence
Expand Down
28 changes: 16 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<groupId>no.digipost</groupId>
<artifactId>digipost-open-super-pom</artifactId>
<version>14</version>
<version>15</version>
</parent>

<artifactId>digipost-useragreements-api-client-java</artifactId>
Expand Down Expand Up @@ -76,25 +76,29 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.4.4</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-h2</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.16</version>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5</artifactId>
<version>5.3.4</version>
</dependency>
<dependency>
<groupId>no.digipost</groupId>
<artifactId>http-client-builder3</artifactId>
<version>3.0.1</version>
<artifactId>http-client-builder5</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
Expand Down Expand Up @@ -370,10 +374,10 @@
<include>org.checkerframework:checker-compat-qual</include>
<include>org.codehaus.mojo:animal-sniffer-annotations</include>
<include>com.google.errorprone:error_prone_annotations</include>
<include>no.digipost:http-client-builder3</include>
<include>org.apache.httpcomponents:httpclient</include>
<include>no.digipost:http-client-builder5</include>
<include>org.apache.httpcomponents.client5:httpclient5</include>
<include>commons-codec:commons-codec</include>
<include>org.apache.httpcomponents:httpcore</include>
<include>org.apache.httpcomponents.core5:httpcore5</include>
<include>org.jboss.logging:jboss-logging</include>
<include>org.jboss.xnio:xnio-api</include>
</includes>
Expand Down
50 changes: 26 additions & 24 deletions src/main/java/no/digipost/api/useragreements/client/ApiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
import jakarta.xml.bind.JAXB;
import no.digipost.api.useragreements.client.response.StreamingRateLimitedResponse;
import no.digipost.cache2.inmemory.SingleCached;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.hc.client5.http.classic.methods.HttpDelete;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
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.HttpHeaders;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
import org.apache.hc.core5.net.URIBuilder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -61,30 +63,30 @@ public ApiService(final URI serviceEndpoint, final BrokerId brokerId, final Clos
this.httpClient = httpClient;
}

public IdentificationResult identifyUser(final SenderId senderId, final UserId userId, final String requestTrackingId, final ResponseHandler<IdentificationResult> handler) {
public IdentificationResult identifyUser(final SenderId senderId, final UserId userId, final String requestTrackingId, final HttpClientResponseHandler<IdentificationResult> handler) {
return executeHttpRequest(newPostRequest(getEntryPoint().getIdentificationUri(), requestTrackingId, new Identification(userId.serialize())), handler);
}

public void createAgreement(final SenderId senderId, final Agreement agreement, final String requestTrackingId, final ResponseHandler<Void> handler) {
public void createAgreement(final SenderId senderId, final Agreement agreement, final String requestTrackingId, final HttpClientResponseHandler<Void> handler) {
executeHttpRequest(newPostRequest(new URIBuilder(serviceEndpoint).setPath(userAgreementsPath(senderId)), requestTrackingId, agreement), handler);
}

public GetAgreementResult getAgreement(final SenderId senderId, final AgreementType agreementType, final UserId userId, final String requestTrackingId, final ResponseHandler<GetAgreementResult> handler) {
public GetAgreementResult getAgreement(final SenderId senderId, final AgreementType agreementType, final UserId userId, final String requestTrackingId, final HttpClientResponseHandler<GetAgreementResult> handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userAgreementsPath(senderId))
.setParameter("user-id", userId.serialize())
.setParameter("agreement-type", agreementType.getType());
return executeHttpRequest(newGetRequest(uriBuilder, requestTrackingId), handler);
}

public Agreements getAgreements(final SenderId senderId, final UserId userId, final String requestTrackingId, final ResponseHandler<Agreements> handler) {
public Agreements getAgreements(final SenderId senderId, final UserId userId, final String requestTrackingId, final HttpClientResponseHandler<Agreements> handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userAgreementsPath(senderId))
.setParameter("user-id", userId.serialize());
return executeHttpRequest(newGetRequest(uriBuilder, requestTrackingId), handler);
}

public void deleteAgrement(final SenderId senderId, final AgreementType agreementType, final UserId userId, final String requestTrackingId, final ResponseHandler<Void> handler) {
public void deleteAgrement(final SenderId senderId, final AgreementType agreementType, final UserId userId, final String requestTrackingId, final HttpClientResponseHandler<Void> handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userAgreementsPath(senderId))
.setParameter("user-id", userId.serialize())
Expand All @@ -93,7 +95,7 @@ public void deleteAgrement(final SenderId senderId, final AgreementType agreemen
executeHttpRequest(withRequestTrackingHeader(deleteAgreementRequest, requestTrackingId), handler);
}

public Documents getDocuments(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query, final String requestTrackingId, final ResponseHandler<Documents> handler) {
public Documents getDocuments(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query, final String requestTrackingId, final HttpClientResponseHandler<Documents> handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userDocumentsPath(senderId))
.setParameter(UserId.QUERY_PARAM_NAME, userId.serialize())
Expand All @@ -111,14 +113,14 @@ private void setGetDocumentsQueryParams(final URIBuilder uriBuilder, final GetDo
}
}

public Document getDocument(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId, final ResponseHandler<Document> handler) {
public Document getDocument(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId, final HttpClientResponseHandler<Document> handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userDocumentsPath(senderId) + "/" + documentId)
.setParameter(AgreementType.QUERY_PARAM_NAME, agreementType.getType());
return executeHttpRequest(newGetRequest(uriBuilder, requestTrackingId), handler);
}

public DocumentCount getDocumentCount(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query, final String requestTrackingId, final ResponseHandler<DocumentCount> handler) {
public DocumentCount getDocumentCount(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query, final String requestTrackingId, final HttpClientResponseHandler<DocumentCount> handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userDocumentsPath(senderId) + "/count")
.setParameter(UserId.QUERY_PARAM_NAME, userId.serialize())
Expand All @@ -127,7 +129,7 @@ public DocumentCount getDocumentCount(final SenderId senderId, final AgreementTy
return executeHttpRequest(newGetRequest(uriBuilder, requestTrackingId), handler);
}

public DocumentContent getDocumentContent(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId, final ResponseHandler<DocumentContent> handler) {
public DocumentContent getDocumentContent(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId, final HttpClientResponseHandler<DocumentContent> handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userDocumentsPath(senderId) + "/" + documentId + "/content")
.setParameter(AgreementType.QUERY_PARAM_NAME, agreementType.getType());
Expand Down Expand Up @@ -167,7 +169,7 @@ private static String userDocumentsPath(final SenderId senderId) {
return "/" + senderId.serialize() + "/" + USER_DOCUMENTS_PATH;
}

private <T> T executeHttpRequest(final HttpRequestBase request, final ResponseHandler<T> handler) {
private <T> T executeHttpRequest(final ClassicHttpRequest request, final HttpClientResponseHandler<T> handler) {
try {
request.setHeader(X_Digipost_UserId, brokerId.serialize());
return httpClient.execute(request, handler);
Expand Down Expand Up @@ -203,12 +205,12 @@ private static URI buildUri(URIBuilder builder) {
}
}

private static <REQ extends HttpRequestBase> REQ withCommonHeaders(REQ request, String requestTrackingId) {
private static <REQ extends HttpRequest> REQ withCommonHeaders(REQ request, String requestTrackingId) {
request.setHeader(HttpHeaders.ACCEPT, DIGIPOST_MEDIA_TYPE_USERS_V2);
return withRequestTrackingHeader(request, requestTrackingId);
}

private static <REQ extends HttpRequestBase> REQ withRequestTrackingHeader(REQ request, final String requestTrackingId) {
private static <REQ extends HttpRequest> REQ withRequestTrackingHeader(REQ request, final String requestTrackingId) {
if (requestTrackingId != null && !requestTrackingId.isEmpty()) {
request.setHeader("X-Digipost-Request-Id", requestTrackingId);
}
Expand All @@ -218,7 +220,7 @@ private static <REQ extends HttpRequestBase> REQ withRequestTrackingHeader(REQ r
private static HttpEntity marshallJaxbEntity(final Object obj) {
ByteArrayOutputStream bao = new ByteArrayOutputStream(1024);
JAXB.marshal(obj, bao);
return new ByteArrayEntity(bao.toByteArray());
return new ByteArrayEntity(bao.toByteArray(), ContentType.APPLICATION_XML);
}

public EntryPoint getEntryPoint() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,13 @@
import no.digipost.api.useragreements.client.response.StreamingRateLimitedResponse;
import no.digipost.api.useragreements.client.security.CryptoUtil;
import no.digipost.api.useragreements.client.security.PrivateKeySigner;
import no.digipost.http.client3.DigipostHttpClientFactory;
import no.digipost.http.client3.DigipostHttpClientSettings;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.ResponseHandler;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import no.digipost.http.client.HttpClientFactory;
import no.digipost.http.client.HttpClientSettings;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.apache.hc.core5.http.message.StatusLine;

import java.io.InputStream;
import java.net.URI;
Expand Down Expand Up @@ -89,7 +86,7 @@ public GetAgreementResult getAgreement(final SenderId senderId, final AgreementT
Objects.requireNonNull(type, "agreementType cannot be null");
Objects.requireNonNull(userId, "userId cannot be null");
return apiService.getAgreement(senderId, type, userId, requestTrackingId, response -> {
StatusLine status = response.getStatusLine();
StatusLine status = new StatusLine(response);
if (isOkResponse(status.getStatusCode())) {
return new GetAgreementResult(unmarshallEntity(response, Agreement.class));
} else {
Expand Down Expand Up @@ -171,11 +168,11 @@ public StreamingRateLimitedResponse<UserId> getAgreementOwners(final SenderId se
return apiService.getAgreementOwners(senderId, agreementType, requestTrackingId);
}

private ResponseHandler<Void> voidOkHandler() {
private HttpClientResponseHandler<Void> voidOkHandler() {
return response -> mapOkResponseOrThrowException(response, r -> null);
}

private <T> ResponseHandler<T> singleJaxbEntityHandler(Class<T> responseType) {
private <T> HttpClientResponseHandler<T> singleJaxbEntityHandler(Class<T> responseType) {
return response -> mapOkResponseOrThrowException(response, r -> unmarshallEntity(r, responseType));
}

Expand Down Expand Up @@ -208,7 +205,7 @@ private Builder(BrokerId brokerId, InputStream certificateP12File, String certif
this.certificatePassword = certificatePassword;
this.privateKey = Optional.ofNullable(privateKey);
serviceEndpoint(PRODUCTION_ENDPOINT);
httpClientBuilder = DigipostHttpClientFactory.createBuilder(DigipostHttpClientSettings.DEFAULT);
httpClientBuilder = HttpClientFactory.createBuilder(HttpClientSettings.DEFAULT);
}

public Builder useProxy(final HttpHost proxyHost) {
Expand All @@ -226,30 +223,14 @@ public Builder setHttpClientBuilder(final HttpClientBuilder httpClientBuilder) {
return this;
}

public Builder veryDangerouslyDisableCertificateVerificationWhichIsAbsolutelyUnfitForProductionCode() {
if (this.serviceEndpoint.compareTo(PRODUCTION_ENDPOINT) == 0) {
throw new RuntimeException("You should never ever disable certificate verification when connecting to the production endpoint");
}
SSLContextBuilder sslContextBuilder= new SSLContextBuilder();
try {
sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostname, session) -> true);
httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory);
} catch (Exception e) {
throw new RuntimeException("Could not disable certificate verification: " + e.getMessage(), e);
}
System.err.println("Not checking validity of certificates for any hostnames");
return this;
}

public DigipostUserAgreementsClient build() {
CryptoUtil.addBouncyCastleProviderAndVerify_AES256_CBC_Support();

httpClientBuilder.addInterceptorLast(new RequestDateInterceptor());
httpClientBuilder.addInterceptorLast(new RequestUserAgentInterceptor());
httpClientBuilder.addRequestInterceptorLast(new RequestDateInterceptor());
httpClientBuilder.addRequestInterceptorLast(new RequestUserAgentInterceptor());
PrivateKeySigner pkSigner = privateKey.map(PrivateKeySigner::new).orElseGet(() -> new PrivateKeySigner(certificateP12File, certificatePassword));
httpClientBuilder.addInterceptorLast(new RequestSignatureInterceptor(pkSigner, new RequestContentSHA256Filter()));
httpClientBuilder.addInterceptorLast(new ResponseDateInterceptor());
httpClientBuilder.addRequestInterceptorLast(new RequestSignatureInterceptor(pkSigner, new RequestContentSHA256Filter()));
httpClientBuilder.addResponseInterceptorLast(new ResponseDateInterceptor());
proxyHost.ifPresent(httpClientBuilder::setProxy);

ApiService apiService = new ApiService(serviceEndpoint, brokerId, httpClientBuilder.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
package no.digipost.api.useragreements.client;

import org.apache.http.StatusLine;

import org.apache.hc.core5.http.message.StatusLine;

public class ServerSignatureException extends UnexpectedResponseException {
public ServerSignatureException(final StatusLine status, final String errorMessage) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
package no.digipost.api.useragreements.client;

import org.apache.http.StatusLine;

import org.apache.hc.core5.http.message.StatusLine;

import static java.lang.String.format;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package no.digipost.api.useragreements.client.filters.request;

import org.apache.http.HttpRequest;
import org.apache.hc.core5.http.HttpRequest;
import org.bouncycastle.crypto.ExtendedDigest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,26 @@
package no.digipost.api.useragreements.client.filters.request;

import no.digipost.api.useragreements.client.util.DateUtils;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.protocol.HttpContext;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpRequestInterceptor;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.time.ZonedDateTime;

import static no.digipost.api.useragreements.client.util.DateUtils.GMT;
import static org.apache.http.HttpHeaders.DATE;
import static org.apache.hc.core5.http.HttpHeaders.DATE;

public class RequestDateInterceptor implements HttpRequestInterceptor {

private final Logger log = LoggerFactory.getLogger(getClass());

@Override
public void process(HttpRequest httpRequest, HttpContext httpContext) throws HttpException, IOException {
public void process(HttpRequest httpRequest, EntityDetails entityDetails, HttpContext httpContext) throws HttpException, IOException {
setDateHeader(httpRequest);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
package no.digipost.api.useragreements.client.filters.request;

import org.apache.http.HttpHeaders;

import org.apache.hc.core5.http.HttpHeaders;

import java.util.Arrays;
import java.util.List;
Expand Down
Loading