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