0e70449302b9adb7620ae07f315326c7371f5979
[appc.git] / appc-event-listener / appc-event-listener-bundle / src / main / java / org / onap / appc / listener / LCM / operation / ProviderOperations.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.listener.LCM.operation;
26
27 import com.fasterxml.jackson.databind.JsonNode;
28 import org.apache.commons.codec.binary.Base64;
29 import org.apache.commons.io.IOUtils;
30 import org.apache.http.HttpHeaders;
31 import org.apache.http.HttpResponse;
32 import org.apache.http.HttpVersion;
33 import org.apache.http.client.HttpClient;
34 import org.apache.http.client.methods.HttpPost;
35 import org.apache.http.conn.ClientConnectionManager;
36 import org.apache.http.conn.scheme.PlainSocketFactory;
37 import org.apache.http.conn.scheme.Scheme;
38 import org.apache.http.conn.scheme.SchemeRegistry;
39 import org.apache.http.conn.ssl.SSLSocketFactory;
40 import org.apache.http.entity.StringEntity;
41 import org.apache.http.impl.client.DefaultHttpClient;
42 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
43 import org.apache.http.params.BasicHttpParams;
44 import org.apache.http.params.HttpParams;
45 import org.apache.http.params.HttpProtocolParams;
46 import org.apache.http.protocol.HTTP;
47 import org.onap.appc.exceptions.APPCException;
48 import org.onap.appc.listener.LCM.model.ResponseStatus;
49 import org.onap.appc.listener.util.Mapper;
50
51 import com.att.eelf.configuration.EELFLogger;
52 import com.att.eelf.configuration.EELFManager;
53
54 import javax.net.ssl.SSLContext;
55 import javax.net.ssl.TrustManager;
56 import javax.net.ssl.X509TrustManager;
57 import java.io.IOException;
58 import java.io.UnsupportedEncodingException;
59 import java.net.MalformedURLException;
60 import java.net.Socket;
61 import java.net.URL;
62 import java.net.UnknownHostException;
63 import java.security.*;
64 import java.security.cert.CertificateException;
65 import java.security.cert.X509Certificate;
66
67 public class ProviderOperations {
68
69     private final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class);
70
71     private URL url;
72     private String basic_auth;
73
74     private static ProviderOperationRequestFormatter requestFormatter = new GenericProviderOperationRequestFormatter();
75
76     /**
77      * Calls the AppcProvider to run a topology directed graph
78      *
79      * @param msg The incoming message to be run
80      * @return True if the result is success. Never returns false and throws an exception instead.
81      * @throws UnsupportedEncodingException
82      * @throws Exception                    if there was a failure processing the request. The exception message is the failure reason.
83      */
84     @SuppressWarnings("nls")
85     public JsonNode topologyDG(String rpcName, JsonNode msg) throws APPCException {
86         if (msg == null) {
87             throw new APPCException("Provided message was null");
88         }
89
90         HttpPost post = null;
91         try {
92
93             // Concatenate the "action" on the end of the URL
94             String path = requestFormatter.buildPath(url, rpcName);
95             URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
96
97             post = new HttpPost(serviceUrl.toExternalForm());
98             post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
99             post.setHeader(HttpHeaders.ACCEPT, "application/json");
100
101             // Set Auth
102             if (basic_auth != null) {
103                 post.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + basic_auth);
104             }
105
106             String body = Mapper.toJsonString(msg);
107             StringEntity entity = new StringEntity(body);
108             entity.setContentType("application/json");
109             post.setEntity(new StringEntity(body));
110         } catch (UnsupportedEncodingException | MalformedURLException e) {
111             throw new APPCException(e);
112         }
113
114         HttpClient client = getHttpClient();
115
116         int httpCode = 0;
117         String respBody = null;
118         try {
119             HttpResponse response = client.execute(post);
120             httpCode = response.getStatusLine().getStatusCode();
121             respBody = IOUtils.toString(response.getEntity().getContent());
122         } catch (IOException e) {
123             throw new APPCException(e);
124         }
125
126         if (httpCode >= 200 && httpCode < 300 && respBody != null) {
127             JsonNode json;
128             try {
129                 json = Mapper.toJsonNodeFromJsonString(respBody);
130             } catch (Exception e) {
131                 LOG.error("Error processing response from provider. Could not map response to json", e);
132                 throw new APPCException("APPC has an unknown RPC error");
133             }
134
135             ResponseStatus responseStatus = requestFormatter.getResponseStatus(json);
136
137             if (!isSucceeded(responseStatus.getCode())) {
138                 LOG.warn(String.format("Operation failed [%s]", msg.toString()));
139             }
140
141             return json;
142         }
143
144         throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody));
145     }
146
147     /**
148      * Updates the static var URL and returns the value;
149      *
150      * @return The new value of URL
151      */
152     public String getUrl() {
153         return url.toExternalForm();
154     }
155
156     public void setUrl(String newUrl) {
157         try {
158             url = new URL(newUrl);
159         } catch (MalformedURLException e) {
160             e.printStackTrace();
161         }
162     }
163
164     /**
165      * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth
166      * to null
167      *
168      * @param user     The user with optional domain name
169      * @param password The password for the user
170      * @return The new value of the basic auth string that will be used in the request headers
171      */
172     public String setAuthentication(String user, String password) {
173         if (user != null && password != null) {
174             String authStr = user + ":" + password;
175             basic_auth = new String(Base64.encodeBase64(authStr.getBytes()));
176         } else {
177             basic_auth = null;
178         }
179         return basic_auth;
180     }
181
182     @SuppressWarnings("deprecation")
183     private HttpClient getHttpClient() throws APPCException {
184         HttpClient client;
185         switch (url.getProtocol()) {
186             case "https":
187                 try {
188                     KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
189                     trustStore.load(null, null);
190                     MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
191                     sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
192
193                     HttpParams params = new BasicHttpParams();
194                     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
195                     HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
196
197                     SchemeRegistry registry = new SchemeRegistry();
198                     registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
199                     registry.register(new Scheme("https", sf, 443));
200                     registry.register(new Scheme("https", sf, 8443));
201                     registry.register(new Scheme("http", sf, 8181));
202
203                     ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
204                     client = new DefaultHttpClient(ccm, params);
205                 } catch (Exception e) {
206                     client = new DefaultHttpClient();
207                 }
208                 break;
209             case "http":
210                 client = new DefaultHttpClient();
211                 break;
212             default:
213                 throw new APPCException(
214                     "The provider.topology.url property is invalid. The url did not start with http[s]");
215         }
216         return client;
217     }
218
219     @SuppressWarnings("deprecation")
220     public static class MySSLSocketFactory extends SSLSocketFactory {
221         private SSLContext sslContext = SSLContext.getInstance("TLS");
222
223         public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException,
224                 KeyStoreException, UnrecoverableKeyException {
225             super(truststore);
226
227             TrustManager tm = new X509TrustManager() {
228                 @Override
229                 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
230                 }
231
232                 @Override
233                 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
234                 }
235
236                 @Override
237                 public X509Certificate[] getAcceptedIssuers() {
238                     return null;
239                 }
240             };
241
242             sslContext.init(null, new TrustManager[]{
243                     tm
244             }, null);
245         }
246
247         @Override
248         public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
249                 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     public static boolean isSucceeded(Integer code) {
260         return code != null && ((code == 100) || (code == 400));
261     }
262
263 }