[feature/APPC-6]
[appc.git] / appc-adapters / appc-ansible-adapter / appc-ansible-adapter-bundle / src / main / java / org / openecomp / appc / adapter / ansible / impl / ConnectionBuilder.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  */
22
23 package org.openecomp.appc.adapter.ansible.impl;
24
25 import org.apache.http.HttpEntity;
26 import org.apache.http.HttpResponse;
27 import org.apache.http.client.ClientProtocolException;
28 import org.apache.http.client.ResponseHandler;
29 import org.apache.http.client.methods.HttpGet;
30 import org.apache.http.client.methods.HttpPost;
31 import org.apache.http.client.protocol.HttpClientContext;
32 import org.apache.http.impl.client.CloseableHttpClient;
33 import org.apache.http.impl.client.BasicCredentialsProvider;
34 import org.apache.http.impl.client.HttpClients;
35 import org.apache.http.util.EntityUtils;
36 import org.apache.http.auth.UsernamePasswordCredentials;
37 import org.apache.http.auth.AuthScope;
38 import org.apache.http.entity.StringEntity;
39
40 import java.security.KeyStore;
41 import java.security.KeyStoreException;
42 import java.security.cert.CertificateException;
43 import java.security.KeyManagementException;
44 import java.security.cert.CertificateFactory;
45 import java.security.cert.X509Certificate;
46 import java.security.NoSuchAlgorithmException;
47 import javax.net.ssl.SSLException;
48 import javax.net.ssl.SSLContext;
49 import javax.net.ssl.X509TrustManager;
50
51 import java.io.FileInputStream;
52 import java.io.IOException;
53
54
55 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
56 import org.apache.http.conn.ssl.SSLContexts;
57 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
58
59
60 import org.openecomp.appc.exceptions.APPCException;
61 import org.openecomp.appc.adapter.ansible.model.AnsibleResult;
62 import org.openecomp.appc.adapter.ansible.model.AnsibleResultCodes;
63
64
65 /** 
66      * Returns custom http client 
67      - based on options
68      - can create one with ssl using an X509 certificate that does NOT  have a known CA
69      - create one which trusts ALL SSL certificates
70      - return default httpclient (which only trusts known CAs from default cacerts file for process) -- this is the default option
71      
72 **/
73
74
75 public class ConnectionBuilder {
76
77
78
79     private   CloseableHttpClient http_client = null;
80     private HttpClientContext http_context  = new HttpClientContext();
81
82
83
84
85     // Various constructors depending on how we want to instantiate the http ConnectionBuilder instance
86
87
88     /**
89      * Constructor that initializes an http client based on certificate
90      **/
91     public ConnectionBuilder(String CertFile) throws KeyStoreException, CertificateException, IOException, KeyManagementException, NoSuchAlgorithmException, APPCException{
92         
93         
94         /* Point to the certificate */
95         FileInputStream fs = new FileInputStream(CertFile);
96         
97         /* Generate a certificate from the X509 */
98         CertificateFactory cf = CertificateFactory.getInstance("X.509");
99         X509Certificate cert = (X509Certificate)cf.generateCertificate(fs);
100         
101         /* Create a keystore object and load the certificate there */
102         KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
103         keystore.load(null, null);
104         keystore.setCertificateEntry("cacert", cert);
105         
106         
107         SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
108         SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
109         
110         http_client  = HttpClients.custom().setSSLSocketFactory(factory).build();
111     };
112
113
114     /**
115      * Constructor which trusts all certificates in a specific java keystore file (assumes a JKS file)
116      **/
117     public ConnectionBuilder(String trustStoreFile, char[] trustStorePasswd) throws KeyStoreException, IOException, KeyManagementException, NoSuchAlgorithmException, CertificateException {
118         
119         
120         /* Load the specified trustStore */
121         KeyStore keystore = KeyStore.getInstance("JKS");
122         FileInputStream readStream = new FileInputStream(trustStoreFile);
123         keystore.load(readStream,trustStorePasswd);
124         
125         SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build();
126         SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
127         
128         http_client  = HttpClients.custom().setSSLSocketFactory(factory).build();
129     };
130
131     /**
132      * Constructor that trusts ALL SSl certificates  (NOTE : ONLY FOR DEV TESTING) if Mode == 1
133      or Default if Mode == 0
134     */
135     public ConnectionBuilder(int Mode) throws SSLException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException{
136         if (Mode == 1){
137             SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null,  new TrustSelfSignedStrategy()).build();
138             SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
139             
140             http_client = HttpClients.custom().setSSLSocketFactory(factory).build();                
141         }
142
143         else{
144             http_client = HttpClients.createDefault();
145         }
146         
147     };
148
149    
150     // Use to create an http context with auth headers
151     public  void  setHttpContext(String User, String MyPassword){
152         
153         // Are credential provided ? If so, set the context to be used 
154         if (User != null && ! User.isEmpty() && MyPassword != null && ! MyPassword.isEmpty()){  
155             UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(User, MyPassword);
156             AuthScope authscope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT);
157             BasicCredentialsProvider credsprovider = new BasicCredentialsProvider();
158             credsprovider.setCredentials(authscope, credentials);
159             http_context.setCredentialsProvider(credsprovider);
160         }
161
162         
163     };
164
165
166     // Method posts to the ansible server and writes out response to 
167     // Ansible result object 
168     public AnsibleResult Post(String AgentUrl, String Payload){
169
170         AnsibleResult result = new AnsibleResult();
171         try{
172             
173             HttpPost postObj = new HttpPost(AgentUrl);
174             StringEntity bodyParams = new StringEntity(Payload, "UTF-8");
175             postObj.setEntity(bodyParams);
176             postObj.addHeader("Content-type", "application/json");
177             
178             HttpResponse response = http_client.execute(postObj, http_context);
179             
180             HttpEntity entity = response.getEntity();
181             String responseOutput =  entity != null ? EntityUtils.toString(entity) : null;
182             int responseCode = response.getStatusLine().getStatusCode();
183             result.setStatusCode(responseCode);
184             result.setStatusMessage(responseOutput);
185         }
186         
187         catch(IOException io){
188             result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue());
189             result.setStatusMessage(io.getMessage());
190         }
191         
192         
193
194         return result;
195
196     }
197     
198     // Method gets information from an Ansible server and writes out response to
199     // Ansible result object
200
201     public AnsibleResult Get(String AgentUrl){
202
203         AnsibleResult result = new AnsibleResult();
204
205         try{
206             HttpGet getObj = new HttpGet(AgentUrl );
207             HttpResponse response =  http_client.execute(getObj, http_context);
208             
209             
210             HttpEntity entity = response.getEntity();
211             String responseOutput =  entity != null ? EntityUtils.toString(entity) : null;
212             int responseCode = response.getStatusLine().getStatusCode();
213             result.setStatusCode(responseCode);
214             result.setStatusMessage(responseOutput);
215
216         }
217         catch(IOException io){
218             result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue());
219             result.setStatusMessage(io.getMessage());
220         }
221         
222         return result;
223     };
224
225 }