/* * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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 io.cellery.cell.gateway.initializer.utils; import io.cellery.cell.gateway.initializer.exceptions.APIException; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; 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.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.HttpURLConnection; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; /** * Utility methods for HTTP request processors */ public class RequestProcessor { private static final Logger log = LoggerFactory.getLogger(RequestProcessor.class); private CloseableHttpClient httpClient; public RequestProcessor() throws APIException { try { if (log.isDebugEnabled()) { log.debug("Ignoring SSL verification..."); } SSLContext sslContext = SSLContext.getInstance("SSL"); X509TrustManager x509TrustManager = new TrustAllTrustManager(); sslContext.init(null, new TrustManager[] {x509TrustManager}, new SecureRandom()); SSLConnectionSocketFactory sslsocketFactory = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null, (s, sslSession) -> true); httpClient = HttpClients.custom().setSSLSocketFactory(sslsocketFactory).build(); } catch (NoSuchAlgorithmException | KeyManagementException e) { String errorMessage = "Error occurred while ignoring ssl certificates to allow http connections"; log.error(errorMessage, e); throw new APIException(errorMessage, e); } } /** * Execute http get request. * * @param url url * @param contentType content type * @param acceptType accept type * @param authHeader authorization header * @return Closable http response * @throws APIException Api exception when an error occurred */ public CloseableHttpResponse doGet(String url, String contentType, String acceptType, String authHeader) throws APIException { CloseableHttpResponse response; try { HttpGet httpGet = new HttpGet(url); httpGet.setHeader(Constants.Utils.HTTP_CONTENT_TYPE, contentType); httpGet.setHeader(Constants.Utils.HTTP_RESPONSE_TYPE_ACCEPT, acceptType); httpGet.setHeader(Constants.Utils.HTTP_REQ_HEADER_AUTHZ, authHeader); response = httpClient.execute(httpGet); closeClientConnection(); } catch (IOException e) { String errorMessage = "Error occurred while executing the http Get connection."; log.error(errorMessage, e); throw new APIException(errorMessage, e); } return response; } /** * Execute http post request * * @param url url * @param contentType content type * @param acceptType accept type * @param authHeader authorization header * @param payload post payload * @return Closable http response * @throws APIException Api exception when an error occurred */ public String doPost(String url, String contentType, String acceptType, String authHeader, String payload) throws APIException { String returnObj = null; try { if (log.isDebugEnabled()) { log.debug("Post payload: " + payload); log.debug("Post auth header: " + authHeader); } StringEntity payloadEntity = new StringEntity(payload); HttpPost httpPost = new HttpPost(url); httpPost.setHeader(Constants.Utils.HTTP_CONTENT_TYPE, contentType); httpPost.setHeader(Constants.Utils.HTTP_RESPONSE_TYPE_ACCEPT, acceptType); httpPost.setHeader(Constants.Utils.HTTP_REQ_HEADER_AUTHZ, authHeader); httpPost.setEntity(payloadEntity); CloseableHttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); String responseStr = EntityUtils.toString(entity); int statusCode = response.getStatusLine().getStatusCode(); if (log.isDebugEnabled()) { log.debug("Response status code: " + statusCode); log.debug("Response string : " + responseStr); } if (responseValidate(statusCode, responseStr)) { returnObj = responseStr; } closeClientConnection(); } catch (IOException e) { String errorMessage = "Error occurred while executing the http Post connection."; log.error(errorMessage, e); throw new APIException(errorMessage, e); } return returnObj; } /** * Close http client connection * * @throws IOException throws an IO exception if an error occurred while closing the connection. */ private void closeClientConnection() throws IOException { if (httpClient != null) { try { httpClient.close(); } catch (IOException e) { log.error("Error while closing the http client connection", e); throw e; } } } /** * Validate the http response. * @param statusCode status code * @return boolean to validate response */ private boolean responseValidate(int statusCode, String response) throws IOException { boolean isValid = false; switch (statusCode) { case HttpURLConnection.HTTP_OK: isValid = true; break; case HttpURLConnection.HTTP_CREATED: isValid = true; break; case HttpURLConnection.HTTP_ACCEPTED: isValid = true; break; case HttpURLConnection.HTTP_BAD_REQUEST: if (response != null && !Constants.Utils.EMPTY_STRING.equals(response)) { if (response.contains(Constants.Utils.DIFFERENT_CONTEXT_ERROR) || response.contains(Constants.Utils.DUPLICATE_CONTEXT_ERROR)) { // skip the error when trying to add the same api with different context. isValid = true; } } break; case HttpURLConnection.HTTP_UNAUTHORIZED: isValid = false; break; case HttpURLConnection.HTTP_NOT_FOUND: isValid = false; break; case HttpURLConnection.HTTP_CONFLICT: if (response != null && !Constants.Utils.EMPTY_STRING.equals(response)) { if (response.contains(Constants.Utils.DUPLICATE_API_ERROR)) { // skip the error when trying to add the same api. isValid = true; } } break; case HttpURLConnection.HTTP_INTERNAL_ERROR: if (response != null && !Constants.Utils.EMPTY_STRING.equals(response)) { if (response.contains(Constants.Utils.DUPLICATE_LABEL_ERROR)) { // skip the error when trying to add the same label. isValid = true; } } break; default: isValid = false; } return isValid; } /** * Trust Manager which trusts all certificates. */ public static class TrustAllTrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } }