package net.curisit.securis; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Map; import net.curisit.securis.beans.RequestBean; import net.curisit.securis.utils.JsonUtils; import net.curisit.securis.utils.Params; import org.apache.commons.io.IOUtils; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * Manage all server connections * * @author roberto */ public class ConnectionManager { private static final Logger LOG = LogManager.getLogger(ConnectionManager.class); private static final int HTTP_STATUS_APP_ERRROR = 418; private static final String JSON_MEDIA_TYPE = "application/json"; private static final String ERROR_MESSAGE_HEADER = "X-SECURIS-ERROR-MSG"; private static final String ERROR_CODE_MESSAGE_HEADER = "X-SECURIS-ERROR-CODE"; private static final String TOKEN_HEADER = "X-SECURIS-TOKEN"; private static final String API_CLIENT_TOKEN = "NjdiMGVjN2ZlYjQ2MjI4ZjQwOGU4MDE2OTQ3YjdjMzJkZTEwMDdlZmZjODJjMWNhZmQyM2UwMGZjMDBkZDExNyBfY2xpZW50IDE5NjktMTItMzFUMjM6NTk6NTkuOTk5KzAwMDA="; private static ConnectionManager singleton; private final String serverUrl; private final HttpClientBuilder httpClientBuilder; private ConnectionManager() throws SeCurisException { String aux = Params.get(Params.KEYS.LICENSE_SERVER_URL, Params.DEFAUT_SERVER_URL); if (aux.endsWith("/")) { serverUrl = aux.substring(0, aux.length() - 2); } else { serverUrl = aux; } httpClientBuilder = createHttpClientBuilder(); } private HttpClientBuilder createHttpClientBuilder() throws SeCurisException { SSLContextBuilder builder = new SSLContextBuilder(); SSLConnectionSocketFactory sslsf = null; try { builder.loadTrustMaterial((KeyStore) null, new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }); sslsf = new SSLConnectionSocketFactory(builder.build()); } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e1) { LOG.error(e1); throw new SeCurisException("Error creating SSL socket factory"); } return HttpClientBuilder.create().setSSLSocketFactory(sslsf); } public synchronized static ConnectionManager getInstance() throws SeCurisException { if (singleton == null) { singleton = new ConnectionManager(); } return singleton; } public T executePost(String command, Class returnType, RequestBean req) throws SeCurisException { return executePost(command, returnType, req, null); } public T executePost(String command, Class returnType, RequestBean req, Map headers) throws SeCurisException { HttpPost postRequest = new HttpPost(String.format("%s/%s", serverUrl, command)); postRequest.addHeader(TOKEN_HEADER, API_CLIENT_TOKEN); postRequest.addHeader("accept", JSON_MEDIA_TYPE); postRequest.addHeader("content-type", JSON_MEDIA_TYPE); if (headers != null) { for (String header : headers.keySet()) { String headerValue = headers.get(header); postRequest.addHeader(header, headerValue); } } try { postRequest.setEntity(new StringEntity(JsonUtils.toJSON(req))); } catch (UnsupportedEncodingException | SeCurisException e1) { throw new SeCurisException("Error preparing POST command", e1); } HttpResponse response; try { response = httpClientBuilder.build().execute(postRequest); checkErrors(command, response); String jsonLic = IOUtils.toString(response.getEntity().getContent()); LOG.debug("Response content read OK: {}", jsonLic); T responseBean = JsonUtils.json2object(jsonLic, returnType); LOG.debug("Response bean read OK: {}", responseBean); return responseBean; } catch (IOException e) { LOG.error("Error accessing SeCuris server with command: " + command, e); throw new SeCurisException("Error accessing SeCuris server with command: " + command, e); } } private void checkErrors(String command, HttpResponse response) throws SeCurisException { if (response.getStatusLine().getStatusCode() != 200) { if (response.getStatusLine().getStatusCode() == HTTP_STATUS_APP_ERRROR) { String errorCode = response.getFirstHeader(ERROR_CODE_MESSAGE_HEADER).getValue(); String errorMsg = response.getFirstHeader(ERROR_MESSAGE_HEADER).getValue(); throw new SeCurisException(String.format("[%s] - %s", errorCode, errorMsg)); } LOG.error("Unexpected error executing {}, Reason: {}", command, response.getStatusLine().getReasonPhrase()); throw new SeCurisException("Error executing command " + command + ", status: " + response.getStatusLine().getStatusCode(), new IOException("Unexpected server error")); } } public T executeGet(String command, Class returnType) throws SeCurisException { HttpGet getRequest = new HttpGet(String.format("%s/%s", serverUrl, command)); getRequest.addHeader(TOKEN_HEADER, API_CLIENT_TOKEN); getRequest.addHeader("accept", JSON_MEDIA_TYPE); HttpResponse response; try { response = httpClientBuilder.build().execute(getRequest); if (response.getStatusLine().getStatusCode() != 200) { throw new SeCurisException("Error executing command " + command + ", status: " + response.getStatusLine().getStatusCode()); } String jsonLic = IOUtils.toString(response.getEntity().getContent()); LOG.debug("Response content read OK: {}", jsonLic); T responseBean = JsonUtils.json2object(jsonLic, returnType); LOG.debug("Response bean read OK: {}", responseBean); return responseBean; } catch (IOException e) { LOG.error("Error acessing SeCuris server", e); throw new SeCurisException("Error accessing SeCuris server"); } } public static class Command { public static final String TEST = "ping"; public static final String CREATE_LIC = "request"; public static final String RENEW_LIC = "renew"; public static final String VALIDATE = "validate"; } }