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 e84a85a..d2efc6a 100644 (file)
  * ============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.
  * 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.
- * 
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *
  * ============LICENSE_END=========================================================
  */
 
 package org.onap.appc.adapter.ansible.impl;
 
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-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.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.entity.StringEntity;
-
+import java.io.Closeable;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.KeyManagementException;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
-import java.security.KeyManagementException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.security.NoSuchAlgorithmException;
-import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLContext;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-
-
+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;
-
-
-import org.onap.appc.exceptions.APPCException;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+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 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 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 implements Closeable {
+    private static final String STATUS_CODE_KEY = "StatusCode";
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(ConnectionBuilder.class);
 
+    private CloseableHttpClient httpClient = null;
+    private HttpClientContext httpContext = new HttpClientContext();
 
-public class ConnectionBuilder {
-
+    /**
+     * Constructor that initializes an http client based on certificate
+     **/
 
 
-    private   CloseableHttpClient http_client = null;
-    private HttpClientContext http_context  = new HttpClientContext();
+    public ConnectionBuilder(String certFile, int timeout) throws KeyStoreException, CertificateException, IOException,
+            KeyManagementException, NoSuchAlgorithmException{
 
+        /* Point to the certificate */
+        try(FileInputStream fs = new FileInputStream(certFile)) {
 
+            /* 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);
 
-    // Various constructors depending on how we want to instantiate the http ConnectionBuilder instance
+            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();
+        }
+    }
 
     /**
-     * Constructor that initializes an http client based on certificate
+     * Constructor which trusts all certificates in a specific java keystore file
+     * (assumes a JKS file)
      **/
-    public ConnectionBuilder(String CertFile) throws KeyStoreException, CertificateException, IOException, KeyManagementException, NoSuchAlgorithmException, APPCException{
-       
-       
-       /* Point to the certificate */
-       FileInputStream fs = new FileInputStream(CertFile);
-       
-       /* 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);
-       
-       
-       SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
-       SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
-       
-       http_client  = HttpClients.custom().setSSLSocketFactory(factory).build();
-    };
+    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());
+
+            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();
+        }
 
+    }
 
     /**
-     * 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 {
-       
-       
-       /* Load the specified trustStore */
-       KeyStore keystore = KeyStore.getInstance("JKS");
-       FileInputStream readStream = new FileInputStream(trustStoreFile);
-       keystore.load(readStream,trustStorePasswd);
-       
-       SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
-       SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
-       
-       http_client  = HttpClients.custom().setSSLSocketFactory(factory).build();
-    };
+     * Constructor that trusts ALL SSl certificates (NOTE : ONLY FOR DEV TESTING) if
+     * Mode == 1 or Default if Mode == 0
+     */
+
+    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().setDefaultRequestConfig(config).setSSLSocketFactory(factory).build();
+        } else {
+            httpClient = HttpClients.custom().setDefaultRequestConfig(config).build();
+        }
+    }
 
-    /**
-     * 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{
-       if (Mode == 1){
-           SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null,  new TrustSelfSignedStrategy()).build();
-           SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
-           
-           http_client = HttpClients.custom().setSSLSocketFactory(factory).build();                
-       }
-
-       else{
-           http_client = HttpClients.createDefault();
-       }
-       
-    };
-
-   
     // Use to create an http context with auth headers
-    public  void  setHttpContext(String User, String MyPassword){
-       
-       // Are credential provided ? If so, set the context to be used 
-       if (User != null && ! User.isEmpty() && MyPassword != null && ! MyPassword.isEmpty()){  
-           UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(User, MyPassword);
-           AuthScope authscope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT);
-           BasicCredentialsProvider credsprovider = new BasicCredentialsProvider();
-           credsprovider.setCredentials(authscope, credentials);
-           http_context.setCredentialsProvider(credsprovider);
-       }
-
-       
-    };
-
-
-    // Method posts to the ansible server and writes out response to 
-    // Ansible result object 
-    public AnsibleResult Post(String AgentUrl, String Payload){
-
-       AnsibleResult result = new AnsibleResult();
-       try{
-           
-           HttpPost postObj = new HttpPost(AgentUrl);
-           StringEntity bodyParams = new StringEntity(Payload, "UTF-8");
-           postObj.setEntity(bodyParams);
-           postObj.addHeader("Content-type", "application/json");
-           
-           HttpResponse response = http_client.execute(postObj, http_context);
-           
-           HttpEntity entity = response.getEntity();
-           String responseOutput =  entity != null ? EntityUtils.toString(entity) : null;
-           int responseCode = response.getStatusLine().getStatusCode();
-           result.setStatusCode(responseCode);
-           result.setStatusMessage(responseOutput);
-       }
-       
-       catch(IOException io){
-           result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue());
-           result.setStatusMessage(io.getMessage());
-       }
-       
-       
-
-       return result;
+    public void setHttpContext(String user, String myPassword) {
+
+        // Are credential provided ? If so, set the context to be used
+        if (user != null && !user.isEmpty() && myPassword != null && !myPassword.isEmpty()) {
+            UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, myPassword);
+            AuthScope authscope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT);
+            BasicCredentialsProvider credsprovider = new BasicCredentialsProvider();
+            credsprovider.setCredentials(authscope, credentials);
+            httpContext.setCredentialsProvider(credsprovider);
+        }
+    }
 
+    // Method posts to the ansible server and writes out response to
+    // Ansible result object
+    public AnsibleResult post(String agentUrl, String payload) {
+
+        AnsibleResult result = new AnsibleResult();
+        try {
+
+            HttpPost postObj = new HttpPost(agentUrl);
+            StringEntity bodyParams = new StringEntity(payload, "UTF-8");
+            postObj.setEntity(bodyParams);
+            postObj.addHeader("Content-type", "application/json");
+
+            HttpResponse response = httpClient.execute(postObj, httpContext);
+
+            HttpEntity entity = response.getEntity();
+            String responseOutput = entity != null ? EntityUtils.toString(entity) : null;
+            int responseCode = response.getStatusLine().getStatusCode();
+            result.setStatusCode(responseCode);
+            result.setStatusMessage(responseOutput);
+        } catch (IOException io) {
+            logger.error("Caught IOException", io);
+            result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue());
+            result.setStatusMessage(io.getMessage());
+        }
+        return result;
     }
-    
+
     // Method gets information from an Ansible server and writes out response to
     // Ansible result object
 
-    public AnsibleResult Get(String AgentUrl){
-
-       AnsibleResult result = new AnsibleResult();
-
-       try{
-           HttpGet getObj = new HttpGet(AgentUrl );
-           HttpResponse response =  http_client.execute(getObj, http_context);
-           
-           
-           HttpEntity entity = response.getEntity();
-           String responseOutput =  entity != null ? EntityUtils.toString(entity) : null;
-           int responseCode = response.getStatusLine().getStatusCode();
-           result.setStatusCode(responseCode);
-           result.setStatusMessage(responseOutput);
-
-       }
-       catch(IOException io){
-           result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue());
-           result.setStatusMessage(io.getMessage());
-       }
-       
-       return result;
-    };
+    public AnsibleResult get(String agentUrl) {
+
+        AnsibleResult result = new AnsibleResult();
+
+        try {
+            HttpGet getObj = new HttpGet(agentUrl);
+            HttpResponse response = httpClient.execute(getObj, httpContext);
+
+            HttpEntity entity = response.getEntity();
+            String responseOutput = entity != null ? EntityUtils.toString(entity) : null;
+            int responseCode = response.getStatusLine().getStatusCode();
+            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());
+            result.setStatusMessage(io.getMessage());
+            logger.error("Caught IOException", io);
+        }
+        return result;
+    }
+
+    @Override
+    public void close() {
+        if (httpClient != null) {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                logger.error("Caught IOException during httpClient close", e);
+            }
+        }
+    }
 
 }