no.digipost.api.useragreements.client.DigipostUserAgreementsClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of digipost-useragreements-api-client-java Show documentation
Show all versions of digipost-useragreements-api-client-java Show documentation
Java library for interacting with the Digipost UserAgreements API
/**
* Copyright (C) Posten Norge AS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package no.digipost.api.useragreements.client;
import no.digipost.api.useragreements.client.filters.request.RequestContentSHA256Filter;
import no.digipost.api.useragreements.client.filters.request.RequestDateInterceptor;
import no.digipost.api.useragreements.client.filters.request.RequestSignatureInterceptor;
import no.digipost.api.useragreements.client.filters.request.RequestUserAgentInterceptor;
import no.digipost.api.useragreements.client.filters.response.ResponseDateInterceptor;
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 java.io.InputStream;
import java.net.URI;
import java.security.PrivateKey;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import static no.digipost.api.useragreements.client.response.ResponseUtils.isOkResponse;
import static no.digipost.api.useragreements.client.response.ResponseUtils.mapOkResponseOrThrowException;
import static no.digipost.api.useragreements.client.response.ResponseUtils.readErrorEntity;
import static no.digipost.api.useragreements.client.response.ResponseUtils.unmarshallEntity;
/**
* API client for managing Digipost documents on behalf of users
*/
public class DigipostUserAgreementsClient {
static {
CryptoUtil.addBouncyCastleProviderAndVerify_AES256_CBC_Support();
}
private final ApiService apiService;
public DigipostUserAgreementsClient(final ApiService apiService) {
this.apiService = apiService;
CryptoUtil.verifyTLSCiphersAvailable();
}
public IdentificationResult identifyUser(final SenderId senderId, final UserId userId) {
return identifyUser(senderId, userId, null); }
public IdentificationResult identifyUser(final SenderId senderId, final UserId userId, final String requestTrackingId) {
Objects.requireNonNull(senderId, "senderId cannot be null");
Objects.requireNonNull(userId, "userId cannot be null");
return apiService.identifyUser(senderId, userId, requestTrackingId, singleJaxbEntityHandler(IdentificationResult.class));
}
public void createOrReplaceAgreement(final SenderId senderId, final Agreement agreement) {
createOrReplaceAgreement(senderId, agreement, null); }
public void createOrReplaceAgreement(final SenderId senderId, final Agreement agreement, final String requestTrackingId) {
Objects.requireNonNull(senderId, "senderId cannot be null");
Objects.requireNonNull(agreement, "agreement cannot be null");
apiService.createAgreement(senderId, agreement, requestTrackingId, voidOkHandler());
}
public GetAgreementResult getAgreement(final SenderId senderId, final AgreementType type, final UserId userId) {
return getAgreement(senderId, type, userId, null);
}
public GetAgreementResult getAgreement(final SenderId senderId, final AgreementType type, final UserId userId, final String requestTrackingId) {
Objects.requireNonNull(senderId, "senderId cannot be null");
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();
if (isOkResponse(status.getStatusCode())) {
return new GetAgreementResult(unmarshallEntity(response, Agreement.class));
} else {
final Error error = readErrorEntity(response);
if (status.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
if (error.hasCode(ErrorCode.UNKNOWN_USER_ID)) {
return new GetAgreementResult(GetAgreementResult.FailedReason.UNKNOWN_USER, () -> new UnexpectedResponseException(status, error));
} else if (error.hasCode(ErrorCode.AGREEMENT_NOT_FOUND)) {
return new GetAgreementResult(GetAgreementResult.FailedReason.NO_AGREEMENT, () -> new UnexpectedResponseException(status, error));
}
}
throw new UnexpectedResponseException(status, error);
}
});
}
public List getAgreements(final SenderId senderId, final UserId userId) {
return getAgreements(senderId, userId, null);
}
public List getAgreements(final SenderId senderId, final UserId userId, final String requestTrackingId) {
return apiService.getAgreements(senderId, userId, requestTrackingId, singleJaxbEntityHandler(Agreements.class)).getAgreements();
}
public void deleteAgreement(final SenderId senderId, final AgreementType agreementType, final UserId userId) {
deleteAgreement(senderId, agreementType, userId, null);
}
public void deleteAgreement(final SenderId senderId, final AgreementType agreementType, final UserId userId, final String requestTrackingId) {
apiService.deleteAgrement(senderId, agreementType, userId, requestTrackingId, voidOkHandler());
}
public List getDocuments(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query) {
return getDocuments(senderId, agreementType, userId, query, null);
}
public List getDocuments(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query, final String requestTrackingId) {
Objects.requireNonNull(senderId, "senderId cannot be null");
Objects.requireNonNull(agreementType, "agreementType cannot be null");
Objects.requireNonNull(userId, "userId cannot be null");
final Documents documents = apiService.getDocuments(senderId, agreementType, userId, query, requestTrackingId, singleJaxbEntityHandler(Documents.class));
return documents.getDocuments();
}
public Document getDocument(final SenderId senderId, final AgreementType agreementType, final long documentId) {
return getDocument(senderId, agreementType, documentId, null);
}
public Document getDocument(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId) {
return apiService.getDocument(senderId, agreementType, documentId, requestTrackingId, singleJaxbEntityHandler(Document.class));
}
public void payInvoice(final SenderId senderId, final AgreementType agreementType, final long documentId, final InvoicePayment invoicePayment) {
payInvoice(senderId, agreementType, documentId, invoicePayment, null);
}
public void payInvoice(final SenderId senderId, final AgreementType agreementType, final long documentId, final InvoicePayment invoicePayment, final String requestTrackingId) {
apiService.updateInvoice(senderId, agreementType, documentId, invoicePayment.asInvoiceUpdate(), requestTrackingId, voidOkHandler());
}
public void updateInvoice(final SenderId senderId, final AgreementType agreementType, final long documentId, final InvoiceUpdate invoiceUpdate) {
updateInvoice(senderId, agreementType, documentId, invoiceUpdate, null);
}
public void updateInvoice(final SenderId senderId, final AgreementType agreementType, final long documentId, final InvoiceUpdate invoiceUpdate, final String requestTrackingId) {
apiService.updateInvoice(senderId, agreementType, documentId, invoiceUpdate, requestTrackingId, voidOkHandler());
}
public void deleteInvoice(final SenderId senderId, final AgreementType agreementType, final long documentId) {
deleteInvoice(senderId, agreementType, documentId, null);
}
public void deleteInvoice(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId) {
apiService.updateInvoice(senderId, agreementType, documentId, new InvoiceUpdate(InvoiceStatus.DELETED), requestTrackingId, voidOkHandler());
}
public long getDocumentCount(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query) {
return getDocumentCount(senderId, agreementType, userId, query, null);
}
public long getDocumentCount(final SenderId senderId, final AgreementType agreementType, final UserId userId, final GetDocumentsQuery query, final String requestTrackingId) {
Objects.requireNonNull(senderId, "senderId cannot be null");
Objects.requireNonNull(agreementType, "agreementType cannot be null");
Objects.requireNonNull(userId, "userId cannot be null");
return apiService.getDocumentCount(senderId, agreementType, userId, query, requestTrackingId, singleJaxbEntityHandler(DocumentCount.class)).getCount();
}
public DocumentContent getDocumentContent(final SenderId senderId, final AgreementType agreementType, final long documentId) {
return getDocumentContent(senderId, agreementType, documentId, null);
}
public DocumentContent getDocumentContent(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId) {
return apiService.getDocumentContent(senderId, agreementType, documentId, requestTrackingId, singleJaxbEntityHandler(DocumentContent.class));
}
public StreamingRateLimitedResponse getAgreementOwners(final SenderId senderId, final AgreementType agreementType) {
return getAgreementOwners(senderId, agreementType, null);
}
public StreamingRateLimitedResponse getAgreementOwners(final SenderId senderId, final AgreementType agreementType, final Boolean smsNotificationEnabled) {
return getAgreementOwners(senderId, agreementType, smsNotificationEnabled, null);
}
public StreamingRateLimitedResponse getAgreementOwners(final SenderId senderId, final AgreementType agreementType, final Boolean smsNotificationEnabled, final String requestTrackingId) {
Objects.requireNonNull(senderId, "senderId cannot be null");
Objects.requireNonNull(agreementType, "agreementType cannot be null");
return apiService.getAgreementOwners(senderId, agreementType, smsNotificationEnabled, requestTrackingId);
}
private ResponseHandler voidOkHandler() {
return response -> mapOkResponseOrThrowException(response, r -> null);
}
private ResponseHandler singleJaxbEntityHandler(Class responseType) {
return response -> mapOkResponseOrThrowException(response, r -> unmarshallEntity(r, responseType));
}
public static class Builder {
private static final URI PRODUCTION_ENDPOINT = URI.create("https://api.digipost.no");
private URI serviceEndpoint;
private final BrokerId brokerId;
private final InputStream certificateP12File;
private final String certificatePassword;
private final Optional privateKey;
private HttpClientBuilder httpClientBuilder;
private Optional proxyHost = Optional.empty();
public Builder(final BrokerId brokerId, InputStream certificateP12File, String certificatePassword){
this(brokerId, certificateP12File, certificatePassword, null);
}
public Builder(BrokerId brokerId, PrivateKey privateKey) {
this(brokerId, null, null, privateKey);
}
private Builder(BrokerId brokerId, InputStream certificateP12File, String certificatePassword, PrivateKey privateKey) {
this.brokerId = brokerId;
if (privateKey == null && (certificateP12File == null || certificatePassword == null)) {
throw new IllegalArgumentException("Client must be supplied either PrivateKey, or Certificate and password for certificate");
}
this.certificateP12File = certificateP12File;
this.certificatePassword = certificatePassword;
this.privateKey = Optional.ofNullable(privateKey);
serviceEndpoint(PRODUCTION_ENDPOINT);
httpClientBuilder = DigipostHttpClientFactory.createBuilder(DigipostHttpClientSettings.DEFAULT);
}
public Builder useProxy(final HttpHost proxyHost) {
this.proxyHost = Optional.ofNullable(proxyHost);
return this;
}
public Builder serviceEndpoint(URI endpointUri) {
this.serviceEndpoint = endpointUri;
return this;
}
public Builder setHttpClientBuilder(final HttpClientBuilder httpClientBuilder) {
this.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());
PrivateKeySigner pkSigner = privateKey.map(PrivateKeySigner::new).orElseGet(() -> new PrivateKeySigner(certificateP12File, certificatePassword));
httpClientBuilder.addInterceptorLast(new RequestSignatureInterceptor(pkSigner, new RequestContentSHA256Filter()));
httpClientBuilder.addInterceptorLast(new ResponseDateInterceptor());
proxyHost.ifPresent(httpClientBuilder::setProxy);
ApiService apiService = new ApiService(serviceEndpoint, brokerId, httpClientBuilder.build());
return new DigipostUserAgreementsClient(apiService);
}
}
}