no.digipost.api.useragreements.client.ApiService 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.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 javax.xml.bind.JAXB;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import static java.time.Duration.ofMinutes;
import static java.time.format.DateTimeFormatter.ISO_DATE_TIME;
import static no.digipost.api.useragreements.client.Headers.X_Digipost_UserId;
import static no.digipost.api.useragreements.client.response.ResponseUtils.mapOkResponseOrThrowException;
import static no.digipost.api.useragreements.client.response.ResponseUtils.unmarshallEntities;
import static no.digipost.api.useragreements.client.response.ResponseUtils.unmarshallEntity;
import static no.digipost.cache2.inmemory.CacheConfig.expireAfterAccess;
import static no.digipost.cache2.inmemory.CacheConfig.useSoftValues;
public class ApiService {
public static final String DIGIPOST_MEDIA_TYPE_USERS_V1 = "application/vnd.digipost.user-v1+xml";
public static final String DIGIPOST_MEDIA_TYPE_USERS_V2 = "application/vnd.digipost.user-v2+xml";
private static final String USER_DOCUMENTS_PATH = "user-documents";
private static final String USER_AGREEMENTS_PATH = "user-agreements";
private final URI serviceEndpoint;
private final BrokerId brokerId;
private final CloseableHttpClient httpClient;
public ApiService(final URI serviceEndpoint, final BrokerId brokerId, final CloseableHttpClient httpClient) {
this.serviceEndpoint = serviceEndpoint;
this.brokerId = brokerId;
this.httpClient = httpClient;
}
public IdentificationResult identifyUser(final SenderId senderId, final UserId userId, final String requestTrackingId, final ResponseHandler 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 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 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 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 handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userAgreementsPath(senderId))
.setParameter("user-id", userId.serialize())
.setParameter("agreement-type", agreementType.getType());
HttpDelete deleteAgreementRequest = new HttpDelete(buildUri(uriBuilder));
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 handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userDocumentsPath(senderId))
.setParameter(UserId.QUERY_PARAM_NAME, userId.serialize())
.setParameter(AgreementType.QUERY_PARAM_NAME, agreementType.getType());
setGetDocumentsQueryParams(uriBuilder, query);
return executeHttpRequest(newGetRequest(uriBuilder, requestTrackingId), handler);
}
private void setGetDocumentsQueryParams(final URIBuilder uriBuilder, final GetDocumentsQuery query) {
if (query.getDeliveryTimeFrom() != null) {
uriBuilder.setParameter("delivery-time-from", query.getDeliveryTimeFrom().format(ISO_DATE_TIME));
}
if (query.getDeliveryTimeTo() != null) {
uriBuilder.setParameter("delivery-time-to", query.getDeliveryTimeTo().format(ISO_DATE_TIME));
}
}
public Document getDocument(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId, final ResponseHandler 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 handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userDocumentsPath(senderId) + "/count")
.setParameter(UserId.QUERY_PARAM_NAME, userId.serialize())
.setParameter(AgreementType.QUERY_PARAM_NAME, agreementType.getType());
setGetDocumentsQueryParams(uriBuilder, query);
return executeHttpRequest(newGetRequest(uriBuilder, requestTrackingId), handler);
}
public DocumentContent getDocumentContent(final SenderId senderId, final AgreementType agreementType, final long documentId, final String requestTrackingId, final ResponseHandler handler) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userDocumentsPath(senderId) + "/" + documentId + "/content")
.setParameter(AgreementType.QUERY_PARAM_NAME, agreementType.getType());
return executeHttpRequest(newGetRequest(uriBuilder, requestTrackingId), handler);
}
public StreamingRateLimitedResponse getAgreementOwners(final SenderId senderId, final AgreementType agreementType, final String requestTrackingId) {
URIBuilder uriBuilder = new URIBuilder(serviceEndpoint)
.setPath(userAgreementsPath(senderId) + "/agreement-owners")
.setParameter(AgreementType.QUERY_PARAM_NAME, agreementType.getType());
HttpGet request = newGetRequest(uriBuilder, requestTrackingId);
request.setHeader(X_Digipost_UserId, brokerId.serialize());
CloseableHttpResponse response = null;
try {
response = httpClient.execute(request);
return new StreamingRateLimitedResponse<>(mapOkResponseOrThrowException(response, r -> unmarshallEntities(r, AgreementOwners.class)), AgreementOwners::getIdsAsStream);
} catch (IOException ioe) {
throw new RuntimeIOException(ioe.getMessage(), ioe);
} catch (RuntimeException rte) {
if (response != null) {
try {
response.close();
} catch (IOException e) {
rte.addSuppressed(e);
}
}
throw rte;
}
}
private static String userAgreementsPath(final SenderId senderId) {
return "/" + senderId.serialize() + "/" + USER_AGREEMENTS_PATH;
}
private static String userDocumentsPath(final SenderId senderId) {
return "/" + senderId.serialize() + "/" + USER_DOCUMENTS_PATH;
}
private T executeHttpRequest(final HttpRequestBase request, final ResponseHandler handler) {
try {
request.setHeader(X_Digipost_UserId, brokerId.serialize());
return httpClient.execute(request, handler);
} catch (IOException e) {
throw RuntimeIOException.from(e);
}
}
private HttpGet newGetRequest(final URIBuilder uriBuilder, String requestTrackingId) {
return newGetRequest(buildUri(uriBuilder), requestTrackingId);
}
private HttpGet newGetRequest(final URI uri, String requestTrackingId) {
return withCommonHeaders(new HttpGet(uri), requestTrackingId);
}
private HttpPost newPostRequest(final URIBuilder uriBuilder, String requestTrackingId, Object postBodyEntity) {
return newPostRequest(buildUri(uriBuilder), requestTrackingId, postBodyEntity);
}
private HttpPost newPostRequest(final URI uri, String requestTrackingId, Object postBodyEntity) {
HttpPost request = withCommonHeaders(new HttpPost(uri), requestTrackingId);
request.setHeader(HttpHeaders.CONTENT_TYPE, DIGIPOST_MEDIA_TYPE_USERS_V2);
request.setEntity(marshallJaxbEntity(postBodyEntity));
return request;
}
private static URI buildUri(URIBuilder builder) {
try {
return builder.build();
} catch (URISyntaxException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
private static REQ withCommonHeaders(REQ request, String requestTrackingId) {
request.setHeader(HttpHeaders.ACCEPT, DIGIPOST_MEDIA_TYPE_USERS_V2);
return withRequestTrackingHeader(request, requestTrackingId);
}
private static REQ withRequestTrackingHeader(REQ request, final String requestTrackingId) {
if (requestTrackingId != null && !requestTrackingId.isEmpty()) {
request.setHeader("X-Digipost-Request-Id", requestTrackingId);
}
return request;
}
private static HttpEntity marshallJaxbEntity(final Object obj) {
ByteArrayOutputStream bao = new ByteArrayOutputStream(1024);
JAXB.marshal(obj, bao);
return new ByteArrayEntity(bao.toByteArray());
}
public EntryPoint getEntryPoint() {
try {
return cachedEntryPoint.get();
} catch (RuntimeException e) {
if (e.getCause() instanceof UserAgreementsApiException) {
throw (UserAgreementsApiException) e.getCause();
} else {
throw e;
}
}
}
private EntryPoint performGetEntryPoint() {
return executeHttpRequest(newGetRequest(serviceEndpoint, null),
response -> mapOkResponseOrThrowException(response, r -> unmarshallEntity(r, EntryPoint.class)));
}
private final SingleCached cachedEntryPoint =
new SingleCached<>("digipost-entrypoint", this::performGetEntryPoint, expireAfterAccess(ofMinutes(5)), useSoftValues);
}