improved code structure
[appc.git] / appc-adapters / appc-ansible-adapter / appc-ansible-adapter-bundle / src / main / java / org / onap / appc / adapter / ansible / impl / ConnectionBuilder.java
index f7c282b..d2efc6a 100644 (file)
@@ -2,9 +2,11 @@
  * ============LICENSE_START=======================================================
  * ONAP : APPC
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright © 2018-2019 IBM.
  * =============================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
  * ============LICENSE_END=========================================================
  */
 
 package org.onap.appc.adapter.ansible.impl;
 
+import java.io.Closeable;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.security.KeyManagementException;
@@ -34,14 +36,15 @@ import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.conn.ssl.SSLContexts;
 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
@@ -52,21 +55,20 @@ import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 import org.onap.appc.adapter.ansible.model.AnsibleResult;
 import org.onap.appc.adapter.ansible.model.AnsibleResultCodes;
-import org.onap.appc.exceptions.APPCException;
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
+import org.json.JSONObject;
+import org.apache.commons.lang.StringUtils;
 
 /**
- * Returns a custom http client
- * - based on options
- * - can create one with ssl using an X509 certificate that does NOT have a known CA
- * - create one which trusts ALL SSL certificates
- * - return default httpclient (which only trusts known CAs from default cacerts file for process) this is the default
- * option
+ * Returns a custom http client - based on options - can create one with ssl
+ * using an X509 certificate that does NOT have a known CA - create one which
+ * trusts ALL SSL certificates - return default httpclient (which only trusts
+ * known CAs from default cacerts file for process) this is the default option
  **/
 
-public class ConnectionBuilder {
-
+public class ConnectionBuilder implements Closeable {
+    private static final String STATUS_CODE_KEY = "StatusCode";
     private static final EELFLogger logger = EELFManager.getInstance().getLogger(ConnectionBuilder.class);
 
     private CloseableHttpClient httpClient = null;
@@ -75,61 +77,76 @@ public class ConnectionBuilder {
     /**
      * Constructor that initializes an http client based on certificate
      **/
-    public ConnectionBuilder(String certFile) throws KeyStoreException, CertificateException, IOException,
-            KeyManagementException, NoSuchAlgorithmException, APPCException {
+
+
+    public ConnectionBuilder(String certFile, int timeout) throws KeyStoreException, CertificateException, IOException,
+            KeyManagementException, NoSuchAlgorithmException{
 
         /* Point to the certificate */
-        FileInputStream fs = new FileInputStream(certFile);
+        try(FileInputStream fs = new FileInputStream(certFile)) {
 
-        /* Generate a certificate from the X509 */
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        X509Certificate cert = (X509Certificate) cf.generateCertificate(fs);
+            /* Generate a certificate from the X509 */
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            X509Certificate cert = (X509Certificate) cf.generateCertificate(fs);
 
-        /* Create a keystore object and load the certificate there */
-        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
-        keystore.load(null, null);
-        keystore.setCertificateEntry("cacert", cert);
+            /* Create a keystore object and load the certificate there */
+            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+            keystore.load(null, null);
+            keystore.setCertificateEntry("cacert", cert);
 
-        SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
-        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
-                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
+            SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
+                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
 
-        httpClient = HttpClients.custom().setSSLSocketFactory(factory).build();
+            RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).build();
+            httpClient = HttpClients.custom().setDefaultRequestConfig(config).setSSLSocketFactory(factory).build();
+        }
     }
 
     /**
-     * Constructor which trusts all certificates in a specific java keystore file (assumes a JKS
-     * file)
+     * Constructor which trusts all certificates in a specific java keystore file
+     * (assumes a JKS file)
      **/
-    public ConnectionBuilder(String trustStoreFile, char[] trustStorePasswd) throws KeyStoreException, IOException,
-            KeyManagementException, NoSuchAlgorithmException, CertificateException {
+    public ConnectionBuilder(String trustStoreFile, char[] trustStorePasswd, int timeout, String serverIP)
+            throws KeyStoreException, IOException, KeyManagementException, NoSuchAlgorithmException,
+            CertificateException {
 
         /* Load the specified trustStore */
         KeyStore keystore = KeyStore.getInstance("JKS");
         FileInputStream readStream = new FileInputStream(trustStoreFile);
         keystore.load(readStream, trustStorePasswd);
+        if (StringUtils.isNotBlank(serverIP)) {
+            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
+            SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());
 
-        SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
-        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
-                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+            RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).build();
+            httpClient = HttpClients.custom().setDefaultRequestConfig(config).setSSLSocketFactory(factory).build();
+        } else {
+            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
+            SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
+                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+            RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).build();
+            httpClient = HttpClients.custom().setDefaultRequestConfig(config).setSSLSocketFactory(factory).build();
+        }
 
-        httpClient = HttpClients.custom().setSSLSocketFactory(factory).build();
     }
 
     /**
-     * Constructor that trusts ALL SSl certificates (NOTE : ONLY FOR DEV TESTING) if Mode == 1 or
-     * Default if Mode == 0
+     * Constructor that trusts ALL SSl certificates (NOTE : ONLY FOR DEV TESTING) if
+     * Mode == 1 or Default if Mode == 0
      */
-    public ConnectionBuilder(int mode)
-            throws SSLException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+
+    public ConnectionBuilder(int mode, int timeout)
+            throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+        RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).build();
         if (mode == 1) {
             SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
             SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
                     SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
 
-            httpClient = HttpClients.custom().setSSLSocketFactory(factory).build();
+            httpClient = HttpClients.custom().setDefaultRequestConfig(config).setSSLSocketFactory(factory).build();
         } else {
-            httpClient = HttpClients.createDefault();
+            httpClient = HttpClients.custom().setDefaultRequestConfig(config).build();
         }
     }
 
@@ -187,7 +204,16 @@ public class ConnectionBuilder {
             HttpEntity entity = response.getEntity();
             String responseOutput = entity != null ? EntityUtils.toString(entity) : null;
             int responseCode = response.getStatusLine().getStatusCode();
-            result.setStatusCode(responseCode);
+            logger.info("GetResult response for ansible GET URL" + agentUrl + " returned " + responseOutput);
+            JSONObject postResponse = new JSONObject(responseOutput);
+            if (postResponse.has(STATUS_CODE_KEY)) {
+                int codeStatus = postResponse.getInt(STATUS_CODE_KEY);
+                if (codeStatus == AnsibleResultCodes.PENDING.getValue())
+                    result.setStatusCode(codeStatus);
+                else
+                    result.setStatusCode(responseCode);
+            } else
+                result.setStatusCode(responseCode);
             result.setStatusMessage(responseOutput);
         } catch (IOException io) {
             result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue());
@@ -196,4 +222,16 @@ public class ConnectionBuilder {
         }
         return result;
     }
+
+    @Override
+    public void close() {
+        if (httpClient != null) {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                logger.error("Caught IOException during httpClient close", e);
+            }
+        }
+    }
+
 }