90c97eb42cac474816d8eb27d59d1855b669c6ec
[appc.git] / appc-common / src / main / java / org / onap / appc / rest / client / RestClientInvoker.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.appc.rest.client;
26
27 import java.io.IOException;
28 import java.io.UnsupportedEncodingException;
29 import java.net.MalformedURLException;
30 import java.net.Socket;
31 import java.net.URL;
32 import java.security.KeyManagementException;
33 import java.security.KeyStore;
34 import java.security.KeyStoreException;
35 import java.security.NoSuchAlgorithmException;
36 import java.security.UnrecoverableKeyException;
37 import java.security.cert.CertificateException;
38 import java.security.cert.X509Certificate;
39 import javax.net.ssl.SSLContext;
40 import javax.net.ssl.TrustManager;
41 import javax.net.ssl.X509TrustManager;
42 import org.apache.commons.codec.binary.Base64;
43 import org.apache.http.HttpHeaders;
44 import org.apache.http.HttpResponse;
45 import org.apache.http.HttpVersion;
46 import org.apache.http.client.HttpClient;
47 import org.apache.http.client.methods.HttpGet;
48 import org.apache.http.client.methods.HttpPost;
49 import org.apache.http.client.methods.HttpPut;
50 import org.apache.http.conn.ClientConnectionManager;
51 import org.apache.http.conn.scheme.PlainSocketFactory;
52 import org.apache.http.conn.scheme.Scheme;
53 import org.apache.http.conn.scheme.SchemeRegistry;
54 import org.apache.http.conn.ssl.SSLSocketFactory;
55 import org.apache.http.entity.StringEntity;
56 import org.apache.http.impl.client.CloseableHttpClient;
57 import org.apache.http.impl.client.DefaultHttpClient;
58 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
59 import org.apache.http.params.BasicHttpParams;
60 import org.apache.http.params.HttpParams;
61 import org.apache.http.params.HttpProtocolParams;
62 import org.apache.http.protocol.HTTP;
63 import org.onap.appc.exceptions.APPCException;
64 import com.att.eelf.configuration.EELFLogger;
65 import com.att.eelf.configuration.EELFManager;
66
67 @SuppressWarnings("deprecation")
68 public class RestClientInvoker {
69
70     private static final EELFLogger LOG = EELFManager.getInstance().getLogger(RestClientInvoker.class);
71     private static final String OPERATION_HTTPS = "https";
72     private static final String OPERATION_APPLICATION_JSON = " application/json";
73     private static final String BASIC = "Basic ";
74
75     private URL url = null;
76     private String basicAuth = null;
77
78     public RestClientInvoker(URL url) {
79         this.url = url;
80     }
81
82     /**
83      * Sets the basic authentication header for the given user and password. If either entry is null
84      * then does not set basic auth
85      *
86      * @param user The user with optional domain name (for AAF)
87      * @param password The password for the user
88      */
89     public void setAuthentication(String user, String password) {
90         if (user != null && password != null) {
91             String authStr = user + ":" + password;
92             basicAuth = new String(Base64.encodeBase64(authStr.getBytes()));
93         }
94     }
95
96     public HttpResponse doPost(String path, String body) throws APPCException {
97         HttpPost post;
98
99         try {
100
101             URL postUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
102             post = new HttpPost(postUrl.toExternalForm());
103             post.setHeader(HttpHeaders.CONTENT_TYPE, OPERATION_APPLICATION_JSON);
104             post.setHeader(HttpHeaders.ACCEPT, OPERATION_APPLICATION_JSON);
105
106             if (basicAuth != null) {
107                 post.setHeader(HttpHeaders.AUTHORIZATION, BASIC + basicAuth);
108             }
109
110             StringEntity entity = new StringEntity(body);
111             entity.setContentType(OPERATION_APPLICATION_JSON);
112             post.setEntity(new StringEntity(body));
113         } catch (MalformedURLException | UnsupportedEncodingException e) {
114             throw new APPCException(e);
115         }
116         HttpClient client = getHttpClient();
117
118         try {
119             return client.execute(post);
120         } catch (IOException e) {
121             throw new APPCException(e);
122         }
123     }
124
125     /**
126      * This is Generic method that can be used to perform REST Put operation
127      *
128      * @param path - path for put
129      * @param body - payload for put action which will be sent as request body.
130      * @return - HttpResponse object which is returned from put REST call.
131      * @throws APPCException when error occurs
132      */
133     public HttpResponse doPut(String path, String body) throws APPCException {
134         HttpPut put;
135         try {
136             URL putUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
137             put = new HttpPut(putUrl.toExternalForm());
138             put.setHeader(HttpHeaders.CONTENT_TYPE, OPERATION_APPLICATION_JSON);
139             put.setHeader(HttpHeaders.ACCEPT, OPERATION_APPLICATION_JSON);
140
141             if (basicAuth != null) {
142                 put.setHeader(HttpHeaders.AUTHORIZATION, BASIC + basicAuth);
143             }
144
145             StringEntity entity = new StringEntity(body);
146             entity.setContentType(OPERATION_APPLICATION_JSON);
147             put.setEntity(new StringEntity(body));
148         } catch (UnsupportedEncodingException | MalformedURLException e) {
149             throw new APPCException(e);
150         }
151
152         HttpClient client = getHttpClient();
153
154         try {
155             return client.execute(put);
156         } catch (IOException e) {
157             throw new APPCException(e);
158         }
159     }
160
161     public HttpResponse doGet(String path) throws APPCException {
162         HttpGet get;
163         try {
164             URL getUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
165             get = new HttpGet(getUrl.toExternalForm());
166             get.setHeader(HttpHeaders.CONTENT_TYPE, OPERATION_APPLICATION_JSON);
167             get.setHeader(HttpHeaders.ACCEPT, OPERATION_APPLICATION_JSON);
168
169             if (basicAuth != null) {
170                 get.setHeader(HttpHeaders.AUTHORIZATION, BASIC + basicAuth);
171             }
172
173         } catch (Exception e) {
174             throw new APPCException(e);
175         }
176
177         try (CloseableHttpClient client = getHttpClient()) {
178             return client.execute(get);
179         } catch (IOException e) {
180             throw new APPCException(e);
181         }
182     }
183
184     private CloseableHttpClient getHttpClient() throws APPCException {
185         switch (url.getProtocol()) {
186             case OPERATION_HTTPS:
187                 return createHttpsClient();
188             case "http":
189                 return new DefaultHttpClient();
190             default:
191                 throw new APPCException("The url did not start with http[s]");
192         }
193     }
194
195
196     private CloseableHttpClient createHttpsClient() {
197         try {
198             KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
199             trustStore.load(null, null);
200             MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
201             sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
202
203             HttpParams params = new BasicHttpParams();
204             HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
205             HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
206
207             SchemeRegistry registry = new SchemeRegistry();
208             registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
209             registry.register(new Scheme(OPERATION_HTTPS, sf, 443));
210             registry.register(new Scheme(OPERATION_HTTPS, sf, 8443));
211             registry.register(new Scheme("http", sf, 8181));
212
213             ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
214             return new DefaultHttpClient(ccm, params);
215         } catch (Exception e) {
216             LOG.error("Error creating HTTPs Client. Creating default client.", e);
217             return new DefaultHttpClient();
218         }
219     }
220
221     private static class MySSLSocketFactory extends SSLSocketFactory {
222         private SSLContext sslContext = SSLContext.getInstance("TLS");
223
224         private MySSLSocketFactory(KeyStore truststore)
225                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
226             super(truststore);
227
228             TrustManager tm = new X509TrustManager() {
229                 @Override
230                 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
231                     LOG.debug("Inside checkClientTrusted");
232                 }
233
234                 @Override
235                 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
236                     LOG.debug("Inside checkServerTrusted");
237                 }
238
239                 @Override
240                 public X509Certificate[] getAcceptedIssuers() {
241                     return new X509Certificate[1];
242                 }
243             };
244
245             sslContext.init(null, new TrustManager[] {tm}, null);
246         }
247
248         @Override
249         public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
250             return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
251         }
252
253         @Override
254         public Socket createSocket() throws IOException {
255             return sslContext.getSocketFactory().createSocket();
256         }
257     }
258
259 }