6d1ae9527a756105e656e3b6045d45cccf4db0f9
[appc.git] / appc-event-listener / appc-event-listener-bundle / src / main / java / org / openecomp / appc / listener / demo / impl / 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.openecomp.appc.listener.demo.impl;
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.net.UnknownHostException;
33 import java.security.KeyManagementException;
34 import java.security.KeyStore;
35 import java.security.KeyStoreException;
36 import java.security.NoSuchAlgorithmException;
37 import java.security.UnrecoverableKeyException;
38 import java.security.cert.CertificateException;
39 import java.security.cert.X509Certificate;
40
41 import javax.net.ssl.SSLContext;
42 import javax.net.ssl.TrustManager;
43 import javax.net.ssl.X509TrustManager;
44
45 import org.apache.commons.codec.binary.Base64;
46 import org.apache.commons.io.IOUtils;
47 import org.apache.http.HttpResponse;
48 import org.apache.http.HttpVersion;
49 import org.apache.http.client.HttpClient;
50 import org.apache.http.client.methods.HttpPost;
51 import org.apache.http.conn.ClientConnectionManager;
52 import org.apache.http.conn.scheme.PlainSocketFactory;
53 import org.apache.http.conn.scheme.Scheme;
54 import org.apache.http.conn.scheme.SchemeRegistry;
55 import org.apache.http.conn.ssl.SSLSocketFactory;
56 import org.apache.http.entity.StringEntity;
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.json.JSONObject;
64 import org.openecomp.appc.exceptions.APPCException;
65 import org.openecomp.appc.listener.demo.model.IncomingMessage;
66 import org.openecomp.appc.listener.util.Mapper;
67
68 import com.att.eelf.configuration.EELFLogger;
69 import com.att.eelf.configuration.EELFManager;
70
71 public class ProviderOperations {
72
73     private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class);
74
75     private static URL url;
76
77     private static String basic_auth;
78
79     //@formatter:off
80     @SuppressWarnings("nls")
81     private final static String TEMPLATE = "{\"input\": {\"common-request-header\": {\"service-request-id\": \"%s\"},\"config-payload\": {\"config-url\": \"%s\",\"config-json\":\"%s\"}}}";
82     //@formatter:on 
83
84     /**
85      * Calls the AppcProvider to run a topology directed graph
86      * 
87      * @param msg
88      *            The incoming message to be run
89      * @return True if the result is success. Never returns false and throws an exception instead.
90      * @throws UnsupportedEncodingException
91      * @throws Exception
92      *             if there was a failure processing the request. The exception message is the failure reason.
93      */
94     @SuppressWarnings("nls")
95     public static boolean topologyDG(IncomingMessage msg) throws APPCException {
96         if (msg == null) {
97             throw new APPCException("Provided message was null");
98         }
99
100         HttpPost post = null;
101         try {
102             // Concatenate the "action" on the end of the URL
103             String path = url.getPath() + ":" + msg.getAction().getValue();
104             URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
105
106             post = new HttpPost(serviceUrl.toExternalForm());
107             post.setHeader("Content-Type", "application/json");
108             post.setHeader("Accept", "application/json");
109
110             // Set Auth
111             if (basic_auth != null) {
112                 post.setHeader("Authorization", "Basic " + basic_auth);
113             }
114
115             //String body = buildReqest(msg.getId(), msg.getUrl(), msg.getIdentityUrl());
116             String body = buildReqest(msg.getHeader().getRequestID(), msg.getPayload().getGenericVnfId(), msg.getPayload().getPgStreams());
117             StringEntity entity = new StringEntity(body);
118             entity.setContentType("application/json");
119             post.setEntity(new StringEntity(body));
120         } catch (UnsupportedEncodingException | MalformedURLException e) {
121             throw new APPCException(e);
122         }
123
124         HttpClient client = getHttpClient();
125
126         int httpCode = 0;
127         String respBody = null;
128         try {
129             HttpResponse response = client.execute(post);
130             httpCode = response.getStatusLine().getStatusCode();
131             respBody = IOUtils.toString(response.getEntity().getContent());
132         } catch (IOException e) {
133             throw new APPCException(e);
134         }
135
136         if (httpCode == 200 && respBody != null) {
137             JSONObject json;
138             try {
139                 json = Mapper.toJsonObject(respBody);
140             } catch (Exception e) {
141                 LOG.error("Error prcoessing response from provider. Could not map response to json", e);
142                 throw new APPCException("APPC has an unknown RPC error");
143             }
144             boolean success;
145             String reason;
146             try {
147                 JSONObject header = json.getJSONObject("output").getJSONObject("common-response-header");
148                 success = header.getBoolean("success");
149                 reason = header.getString("reason");
150             } catch (Exception e) {
151                 LOG.error("Unknown error prcoessing failed response from provider. Json not in expected format", e);
152                 throw new APPCException("APPC has an unknown RPC error");
153             }
154             if (success) {
155                 return true;
156             }
157             String reasonStr = reason == null ? "Unknown" : reason;
158             LOG.warn(String.format("Topology Operation [%s] failed. Reason: %s", msg.getHeader().getRequestID(), reasonStr));
159             throw new APPCException(reasonStr);
160
161         }
162         throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody));
163     }
164
165     /**
166      * Updates the static var URL and returns the value;
167      * 
168      * @return The new value of URL
169      */
170     public static String getUrl() {
171         return url.toExternalForm();
172     }
173
174     public static void setUrl(String newUrl) {
175         try {
176             url = new URL(newUrl);
177         } catch (MalformedURLException e) {
178             e.printStackTrace();
179         }
180     }
181
182     /**
183      * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth
184      * to null
185      *
186      * @param user
187      *            The user with optional domain name
188      * @param password
189      *            The password for the user
190      * @return The new value of the basic auth string that will be used in the request headers
191      */
192     public static String setAuthentication(String user, String password) {
193         if (user != null && password != null) {
194             String authStr = user + ":" + password;
195             basic_auth = new String(Base64.encodeBase64(authStr.getBytes()));
196         } else {
197             basic_auth = null;
198         }
199         return basic_auth;
200     }
201
202     /**
203      * Builds the request body for a topology operation
204      * 
205      * @param id
206      *            The request id
207      * @param url
208      *            The vm's url
209      *            
210      * @param pgstreams 
211      *           The streams to send to the traffic generator
212      *
213      * @return A String containing the request body
214      */
215     private static String buildReqest(String id, String url, String pgstreams) {
216
217         return String.format(TEMPLATE, id, url, pgstreams);
218     }
219
220     @SuppressWarnings("deprecation")
221     private static HttpClient getHttpClient() throws APPCException {
222         HttpClient client;
223         if (url.getProtocol().equals("https")) {
224             try {
225                 KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
226                 trustStore.load(null, null);
227                 MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
228                 sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
229
230                 HttpParams params = new BasicHttpParams();
231                 HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
232                 HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
233
234                 SchemeRegistry registry = new SchemeRegistry();
235                 registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
236                 registry.register(new Scheme("https", sf, 443));
237                 registry.register(new Scheme("https", sf, 8443));
238                 registry.register(new Scheme("http", sf, 8181));
239
240                 ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
241                 client = new DefaultHttpClient(ccm, params);
242             } catch (Exception e) {
243                 client = new DefaultHttpClient();
244             }
245         } else if (url.getProtocol().equals("http")) {
246             client = new DefaultHttpClient();
247         } else {
248             throw new APPCException(
249                 "The provider.topology.url property is invalid. The url did not start with http[s]");
250         }
251         return client;
252     }
253
254     @SuppressWarnings("deprecation")
255     public static class MySSLSocketFactory extends SSLSocketFactory {
256         private SSLContext sslContext = SSLContext.getInstance("TLS");
257
258         public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException,
259                         KeyStoreException, UnrecoverableKeyException {
260             super(truststore);
261
262             TrustManager tm = new X509TrustManager() {
263                 @Override
264                 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
265                 }
266
267                 @Override
268                 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
269                 }
270
271                 @Override
272                 public X509Certificate[] getAcceptedIssuers() {
273                     return null;
274                 }
275             };
276
277             sslContext.init(null, new TrustManager[] {
278                 tm
279             }, null);
280         }
281
282         @Override
283         public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
284             throws IOException, UnknownHostException {
285             return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
286         }
287
288         @Override
289         public Socket createSocket() throws IOException {
290             return sslContext.getSocketFactory().createSocket();
291         }
292     }
293
294 }