/* * Copyright (C) 2014 Jan Pokorsky * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package cz.cas.lib.proarc.urnnbn; import cz.cas.lib.proarc.urnnbn.model.registration.Import; import cz.cas.lib.proarc.urnnbn.model.response.Response; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.ws.rs.WebApplicationException; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.ResponseProcessingException; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; import org.glassfish.jersey.logging.LoggingFeature; /** * The resolver HTTP client. * * @author Jan Pokorsky */ public final class ResolverClient { /** * The supported API version. */ public static final String API_VERSION = "v3"; private static final Logger LOG = Logger.getLogger(ResolverClient.class.getName()); private Client httpClient; private final String serviceUrl; private final String registrar; private final Long archiver; private final String user; private final String passwd; public ResolverClient(String serviceUrl, String registrar, Long archiver, String user, String passwd) { this.serviceUrl = serviceUrl; this.registrar = registrar; this.archiver = archiver; this.user = user; this.passwd = passwd; } public String getDigitalInstances() { String response = resource().path("digitalInstances").request().get(String.class); return response; } /** * Registers an digital document to get URN:NBN. * <p>{@code POST http://resolver.nkp.cz/api/v3/registrars/boa001/digitalDocuments} * @param object a digital document * @return the resolver response */ public Response registerObject(Import object) { if (registrar == null || registrar.isEmpty()) { throw new IllegalArgumentException("registrar"); } if (object == null) { throw new NullPointerException("object"); } if (archiver != null && object.getDigitalDocument().getArchiverId() == null) { object.getDigitalDocument().setArchiverId(archiver); } Response response = null; try { response = resource() .path("registrars") .path(registrar) .path("digitalDocuments") .request() .post(Entity.entity(object, MediaType.APPLICATION_XML_TYPE), Response.class); } catch (WebApplicationException ex) { response = readResponseError(ex.getResponse(), ex); } catch (ResponseProcessingException ex) { response = readResponseError(ex.getResponse(), ex); } return response; } private Response readResponseError(javax.ws.rs.core.Response errResponse, RuntimeException ex) { try { Response response = null; errResponse.bufferEntity(); MediaType errType = errResponse.getMediaType(); if (errType != null && "xml".equalsIgnoreCase(errType.getSubtype())) { // try to map resolver warning to jaxb response try { response = errResponse.readEntity(Response.class); } catch (Exception exception) { String msg = errResponse.readEntity(String.class); throw new IllegalStateException(msg, ex); } } if (response == null) { throw ex; } return response; } finally { errResponse.close(); } } private WebTarget resource() { // https://resolver.nkp.cz/api/v3 WebTarget target = getHttpClient().target(serviceUrl); if (LOG.isLoggable(Level.FINEST)) { target.register(new LoggingFeature(LOG)); } return target; } Client getHttpClient() { if (httpClient == null) { try { SSLContext sslCtx = SSLContext.getInstance("SSL"); TrustManager tm = new TrustThemAll(); sslCtx.init(null, new TrustManager[] {tm}, null); httpClient = ClientBuilder.newBuilder() .sslContext(sslCtx) .register(HttpAuthenticationFeature.basic(user, passwd)) .build(); httpClient.property(ClientProperties.FOLLOW_REDIRECTS, true); httpClient.property(ClientProperties.CONNECT_TIMEOUT, 2 * 60 * 1000); // 2 min } catch (NoSuchAlgorithmException | KeyManagementException ex) { throw new IllegalStateException(ex); } } return httpClient; } public boolean isDebug() { return LOG.isLoggable(Level.FINEST); } public void setDebug(boolean debug) { LOG.setLevel(debug ? Level.FINEST : null); } private static class TrustThemAll implements X509TrustManager { public TrustThemAll() { } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }