a7173df28bbc7430c22125b4c5206310dec02bf4
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK.apps.sdnr.wt.apigateway
4  * ================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
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  */
21 package org.onap.ccsdk.features.sdnr.wt.apigateway;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.net.HttpURLConnection;
27 import java.net.URL;
28 import java.net.URLConnection;
29 import java.nio.charset.StandardCharsets;
30 import java.security.KeyManagementException;
31 import java.security.NoSuchAlgorithmException;
32 import java.util.Enumeration;
33 import java.util.List;
34 import java.util.Map;
35
36 import javax.net.ssl.HostnameVerifier;
37 import javax.net.ssl.HttpsURLConnection;
38 import javax.net.ssl.SSLContext;
39 import javax.net.ssl.TrustManager;
40 import javax.servlet.ServletException;
41 import javax.servlet.http.HttpServlet;
42 import javax.servlet.http.HttpServletRequest;
43 import javax.servlet.http.HttpServletResponse;
44
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public abstract class BaseServlet extends HttpServlet {
49
50     /**
51      *
52      */
53     private static final long serialVersionUID = 7403047480257892794L;
54     private static Logger LOG = LoggerFactory.getLogger(BaseServlet.class);
55     private static SSLContext sc;
56     private static TrustManager[] trustCerts = null;
57     private static final int BUFSIZE = 2048;
58
59     protected abstract String getOfflineResponse();
60
61     protected abstract boolean isOff();
62
63     protected abstract boolean doTrustAll();
64     protected abstract void trustAll(boolean trust);
65     protected abstract String getRemoteUrl(String uri);
66
67     /**
68      *
69      * @throws NoSuchAlgorithmException
70      * @throws KeyManagementException
71      */
72     private static void setupSslTrustAll(boolean trustall) throws NoSuchAlgorithmException, KeyManagementException {
73
74         sc = SSLContext.getInstance("TLSv1.2");
75         if (trustall) {
76             if (trustCerts == null) {
77                 trustCerts = new TrustManager[] { new javax.net.ssl.X509TrustManager() {
78                     @Override
79                     public java.security.cert.X509Certificate[] getAcceptedIssuers() {
80                         return new java.security.cert.X509Certificate[] {};
81                     }
82
83                     @Override
84                     public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
85                         // do not check anything when trust all
86                     }
87
88                     @Override
89                     public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
90                         // do not check anything when trust all
91                     }
92                 } };
93             }
94         } else {
95             if (trustCerts != null) {
96                 trustCerts = null;
97             }
98         }
99         // Init the SSLContext with a TrustManager[] and SecureRandom()
100         sc.init(null, trustCerts, new java.security.SecureRandom());
101     }
102
103     public BaseServlet() {
104         try {
105             MyProperties.Instantiate();
106         } catch (Exception e) {
107             LOG.error(e.getMessage());
108         }
109         this.trysslSetup(true);
110     }
111
112     private void trysslSetup() {
113         this.trysslSetup(false);
114     }
115
116     /**
117      * init or deinit ssl insecure mode regarding to property
118      *
119      * @param force init independent from property
120      */
121     private void trysslSetup(boolean force) {
122         // if trustall config has changed
123         boolean trustAll = MyProperties.getInstance().trustInsecure();
124         if (force || this.doTrustAll() != trustAll) {
125             this.trustAll(trustAll);
126             // resetup ssl config
127             try {
128                 setupSslTrustAll(trustAll);
129             } catch (Exception e) {
130                 LOG.error("problem setting up SSL: {}", e.getMessage());
131             }
132         }
133     }
134
135     protected void sendOffResponse(HttpServletResponse response) {
136         response.setStatus(200);// HTML/OK
137         response.setHeader("Content-Type", "text/html; charset=utf-8");
138         try {
139             response.getOutputStream().write(this.getOfflineResponse().getBytes(StandardCharsets.UTF_8));
140         } catch (IOException e) {
141             LOG.debug("problem writing offline response");
142         }
143
144     }
145
146     @Override
147     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
148         if (this.isOff()) {
149             this.sendOffResponse(resp);
150         } else {
151             this.trysslSetup();
152             HttpURLConnection http = null;
153             try {
154                 http = (HttpURLConnection) this.getConnection(req, "GET");
155             } catch (IOException e) {
156                 LOG.warn(e.getMessage());
157             }
158             if (http != null) {
159                 try {
160                     this.handleRequest(http, req, resp, "GET");
161                 } catch (IOException e) {
162                     LOG.warn(e.getMessage());
163                 }
164                 http.disconnect();
165             }
166             else {
167                 this.set404Response(resp);
168             }
169         }
170     }
171
172     @Override
173     protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
174         if (this.isOff()) {
175             this.sendOffResponse(resp);
176         } else {
177             this.trysslSetup();
178             HttpURLConnection http = null;
179             try {
180                 http = (HttpURLConnection) this.getConnection(req, "PUT");
181             } catch (IOException e) {
182                 LOG.warn(e.getMessage());
183             }
184             if (http != null) {
185                 try {
186                     this.handleRequest(http, req, resp, "PUT");
187                 } catch (IOException e) {
188                     LOG.warn(e.getMessage());
189                 }
190                 http.disconnect();
191             }
192             else {
193                 this.set404Response(resp);
194             }
195         }
196     }
197
198     @Override
199     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
200         if (this.isOff()) {
201             this.sendOffResponse(resp);
202         } else {
203             this.trysslSetup();
204             HttpURLConnection http = null;
205             try {
206                 http = (HttpURLConnection) this.getConnection(req, "POST");
207             } catch (IOException e) {
208                 LOG.warn(e.getMessage());
209             }
210             if (http != null) {
211                 try {
212                     this.handleRequest(http, req, resp, "POST");
213                 } catch (IOException e) {
214                     LOG.warn(e.getMessage());
215                 }
216                 http.disconnect();
217             }
218             else {
219                 this.set404Response(resp);
220             }
221         }
222     }
223
224     @Override
225     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
226         if (this.isOff()) {
227             this.sendOffResponse(resp);
228         } else {
229             this.trysslSetup();
230             HttpURLConnection http = null;
231             try {
232                 http = (HttpURLConnection) this.getConnection(req, "DELETE");
233             } catch (IOException e) {
234                 LOG.warn(e.getMessage());
235             }
236             if (http != null) {
237                 try {
238                     this.handleRequest(http, req, resp, "DELETE");
239                 } catch (IOException e) {
240                     LOG.warn(e.getMessage());
241                 }
242                 http.disconnect();
243             }
244             else {
245                 this.set404Response(resp);
246             }
247         }
248     }
249
250     private void set404Response(HttpServletResponse resp) {
251         resp.setStatus(404);
252     }
253
254     private URLConnection getConnection(HttpServletRequest req, final String method) throws IOException {
255
256         LOG.debug("{} Request to {}", method,req.getRequestURL());
257         String surl = this.getRemoteUrl(req.getRequestURI());
258         if("GET".equals(method)) {
259             Enumeration<?> params = req.getParameterNames();
260             if(params!=null) {
261                 String param;
262                 if(params.hasMoreElements()) {
263                     param=(String)params.nextElement();
264                     surl+="?"+param+"="+req.getParameter(param);
265                 }
266                 while(params.hasMoreElements()) {
267                     param=(String)params.nextElement();
268                     surl+="&"+param+"="+req.getParameter(param);
269                 }
270             }
271         }
272         LOG.debug("RemoteURL: {}", surl);
273         if(surl==null) {
274             return null;
275         }
276         URL url = new URL(surl);
277         URLConnection http = url.openConnection();
278         ((HttpURLConnection) http).setRequestMethod(method);
279         if (url.toString().startsWith("https")) {
280             ((HttpsURLConnection) http).setSSLSocketFactory(sc.getSocketFactory());
281             if (this.doTrustAll()) {
282                 HostnameVerifier allHostsValid = (hostname, session) -> true;
283                 ((HttpsURLConnection) http).setHostnameVerifier(allHostsValid);
284             }
285         }
286         http.setDoOutput(true);
287         // copy request headers
288         String s = "";
289         Enumeration<?> headers = req.getHeaderNames();
290         while (headers.hasMoreElements()) {
291             String h = (String)headers.nextElement();
292             String v = req.getHeader(h);
293             if (h != null && h.equals("Host")) {
294                 v = url.getAuthority();
295             }
296             s += String.format("%s:%s;", h, v);
297             http.setRequestProperty(h, v);
298         }
299         LOG.debug("Request Headers: {}", s);
300         return http;
301     }
302
303     private void handleRequest(HttpURLConnection http, HttpServletRequest req, HttpServletResponse resp, String method)
304             throws IOException {
305         byte[] buffer = new byte[BUFSIZE];
306         int len = 0, lensum = 0;
307         // send request
308         // Send the message to destination
309         OutputStream output = null;
310         if (!method.equals("GET")) {
311             try {
312                 output = http.getOutputStream();
313             } catch (Exception e) {
314                 LOG.debug("problem reading output stream: {}", e.getMessage());
315             }
316         }
317         if (output != null) {
318             while (true) {
319                 len = req.getInputStream().read(buffer, 0, BUFSIZE);
320                 if (len <= 0) {
321                     break;
322                 }
323                 lensum += len;
324                 output.write(buffer, 0, len);
325             }
326         }
327         LOG.debug("written {} data out", lensum);
328         int responseCode = http.getResponseCode();
329         // Receive answer
330         InputStream response;
331         if (responseCode >= 200 && responseCode < 300) {
332             response = http.getInputStream();
333         } else {
334             response = http.getErrorStream();
335             if (response == null) {
336                 http.getInputStream();
337             }
338         }
339
340         LOG.debug("ResponseCode: {}", responseCode);
341         resp.setStatus(responseCode);
342         Map<String, List<String>> set = http.getHeaderFields();
343         String s = "";
344         if (set != null) {
345             for (Map.Entry<String, List<String>> entry : set.entrySet()) {
346                 if (entry.getKey() == null) {
347                     continue;
348                 }
349                 for (String v : entry.getValue()) {
350                     resp.setHeader(entry.getKey(), v);
351                     s += String.format("%s:%s;", entry.getKey(), v);
352                 }
353                 if (MyProperties.getInstance().corsEnabled()) {
354                     resp.setHeader("Access-Control-Allow-Origin", "*");
355                     // resp.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
356                     resp.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
357                 }
358
359             }
360         }
361         LOG.debug("Received Headers: {}", s);
362         lensum = 0;
363         if (response != null) {
364             while (true) {
365                 len = response.read(buffer, 0, BUFSIZE);
366                 if (len <= 0) {
367                     break;
368                 }
369                 lensum += len;
370                 resp.getOutputStream().write(buffer, 0, len);
371             }
372         } else {
373             LOG.debug("response is null");
374         }
375         LOG.debug("Received {} bytes", lensum);
376     }
377
378 }