b2bc30c0e5580e9d725f511a4326bae23e4d401d
[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.SSLSession;
40 import javax.net.ssl.TrustManager;
41 import javax.servlet.ServletException;
42 import javax.servlet.http.HttpServlet;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 public abstract class BaseServlet extends HttpServlet {
50
51         /**
52          * 
53          */
54         private static final long serialVersionUID = 7403047480257892794L;
55         private static Logger LOG = LoggerFactory.getLogger(BaseServlet.class);
56         private static SSLContext sc;
57         private boolean trustAll = false;
58         private static TrustManager[] trustCerts = null;
59         private static final int BUFSIZE = 2048;
60
61         protected abstract String getOfflineResponse();
62
63         protected abstract boolean isOff();
64
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                 // Init the SSLContext with a TrustManager[] and SecureRandom()
99                 sc.init(null, trustCerts, new java.security.SecureRandom());
100         }
101
102         public BaseServlet() {
103                 try {
104                         MyProperties.Instantiate();
105                 } catch (Exception e) {
106                         LOG.error(e.getMessage());
107                 }
108                 this.trysslSetup(true);
109         }
110
111         private void trysslSetup() {
112                 this.trysslSetup(false);
113         }
114
115         /**
116          * init or deinit ssl insecure mode regarding to property
117          * 
118          * @param force init independent from property
119          */
120         private void trysslSetup(boolean force) {
121                 // if trustall config has changed
122                 if (force || trustAll != MyProperties.getInstance().trustInsecure()) {
123                         // resetup ssl config
124                         trustAll = MyProperties.getInstance().trustInsecure();
125                         try {
126                                 setupSslTrustAll(trustAll);
127                         } catch (Exception e) {
128                                 LOG.error("problem setting up SSL: {}", e.getMessage());
129                         }
130                 }
131         }
132
133         protected void sendOffResponse(HttpServletResponse response) {
134                 response.setStatus(200);// HTML/OK
135                 response.setHeader("Content-Type", "text/html; charset=utf-8");
136                 try {
137                         response.getOutputStream().write(this.getOfflineResponse().getBytes(StandardCharsets.UTF_8));
138                 } catch (IOException e) {
139                         LOG.debug("problem writing offline response");
140                 }
141
142         }
143
144         @Override
145         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
146                 if (this.isOff()) {
147                         this.sendOffResponse(resp);
148                 } else {
149                         this.trysslSetup();
150                         HttpURLConnection http = null;
151                         try {
152                                 http = (HttpURLConnection) this.getConnection(req, "GET");
153                         } catch (IOException e) {
154                                 LOG.warn(e.getMessage());
155                         }
156                         if (http != null) {
157                                 try {
158                                         this.handleRequest(http, req, resp, "GET");
159                                 } catch (IOException e) {
160                                         LOG.warn(e.getMessage());
161                                 }
162                                 http.disconnect();
163                         }
164                 }
165         }
166
167         @Override
168         protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
169                 if (this.isOff()) {
170                         this.sendOffResponse(resp);
171                 } else {
172                         this.trysslSetup();
173                         HttpURLConnection http = null;
174                         try {
175                                 http = (HttpURLConnection) this.getConnection(req, "PUT");
176                         } catch (IOException e) {
177                                 LOG.warn(e.getMessage());
178                         }
179                         if (http != null) {
180                                 try {
181                                         this.handleRequest(http, req, resp, "PUT");
182                                 } catch (IOException e) {
183                                         LOG.warn(e.getMessage());
184                                 }
185                                 http.disconnect();
186                         }
187                 }
188         }
189
190         @Override
191         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
192                 if (this.isOff()) {
193                         this.sendOffResponse(resp);
194                 } else {
195                         this.trysslSetup();
196                         HttpURLConnection http = null;
197                         try {
198                                 http = (HttpURLConnection) this.getConnection(req, "POST");
199                         } catch (IOException e) {
200                                 LOG.warn(e.getMessage());
201                         }
202                         if (http != null) {
203                                 try {
204                                         this.handleRequest(http, req, resp, "POST");
205                                 } catch (IOException e) {
206                                         LOG.warn(e.getMessage());
207                                 }
208                                 http.disconnect();
209                         }
210                 }
211         }
212
213         @Override
214         protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
215                 if (this.isOff()) {
216                         this.sendOffResponse(resp);
217                 } else {
218                         this.trysslSetup();
219                         HttpURLConnection http = null;
220                         try {
221                                 http = (HttpURLConnection) this.getConnection(req, "DELETE");
222                         } catch (IOException e) {
223                                 LOG.warn(e.getMessage());
224                         }
225                         if (http != null) {
226                                 try {
227                                         this.handleRequest(http, req, resp, "DELETE");
228                                 } catch (IOException e) {
229                                         LOG.warn(e.getMessage());
230                                 }
231                                 http.disconnect();
232                         }
233                 }
234         }
235
236         private URLConnection getConnection(HttpServletRequest req, final String method) throws IOException {
237
238                 LOG.debug("{} Request", method);
239                 String surl = this.getRemoteUrl(req.getRequestURI());
240                 LOG.debug("RemoteURL: {}", surl);
241                 URL url = new URL(surl);
242                 URLConnection http = url.openConnection();
243                 ((HttpURLConnection) http).setRequestMethod(method);
244                 if (url.toString().startsWith("https")) {
245                         ((HttpsURLConnection) http).setSSLSocketFactory(sc.getSocketFactory());
246                         if (trustAll) {
247                                 HostnameVerifier allHostsValid = new HostnameVerifier() {
248
249                                         @Override
250                                         public boolean verify(String hostname, SSLSession session) {
251                                                 // do not verify host if trust all
252                                                 return true;
253                                         }
254                                 };
255                                 ((HttpsURLConnection) http).setHostnameVerifier(allHostsValid);
256                         }
257                 }
258                 http.setDoOutput(true);
259                 // copy request headers
260                 String s = "";
261                 Enumeration<String> headers = req.getHeaderNames();
262                 while (headers.hasMoreElements()) {
263                         String h = headers.nextElement();
264                         String v = req.getHeader(h);
265                         if (h != null && h.equals("Host")) {
266                                 v = url.getAuthority();
267                         }
268                         s += String.format("%s:%s;", h, v);
269                         http.setRequestProperty(h, v);
270                 }
271                 LOG.debug("Request Headers: {}", s);
272                 return http;
273         }
274
275         private void handleRequest(HttpURLConnection http, HttpServletRequest req, HttpServletResponse resp, String method)
276                         throws IOException {
277                 byte[] buffer = new byte[BUFSIZE];
278                 int len = 0, lensum = 0;
279                 // send request
280                 // Send the message to destination
281                 OutputStream output = null;
282                 if (!method.equals("GET")) {
283                         try {
284                                 output = http.getOutputStream();
285                         } catch (Exception e) {
286                                 LOG.debug("problem reading output stream: {}", e.getMessage());
287                         }
288                 }
289                 if (output != null) {
290                         while (true) {
291                                 len = req.getInputStream().read(buffer, 0, BUFSIZE);
292                                 if (len <= 0) {
293                                         break;
294                                 }
295                                 lensum += len;
296                                 output.write(buffer, 0, len);
297                         }
298                 }
299                 LOG.debug("written {} data out", lensum);
300                 int responseCode = http.getResponseCode();
301                 // Receive answer
302                 InputStream response;
303                 if (responseCode >= 200 && responseCode < 300) {
304                         response = http.getInputStream();
305                 } else {
306                         response = http.getErrorStream();
307                         if (response == null) {
308                                 http.getInputStream();
309                         }
310                 }
311
312                 LOG.debug("ResponseCode: {}", responseCode);
313                 resp.setStatus(responseCode);
314                 Map<String, List<String>> set = http.getHeaderFields();
315                 String s = "";
316                 if (set != null) {
317                         for (Map.Entry<String, List<String>> entry : set.entrySet()) {
318                                 if (entry.getKey() == null) {
319                                         continue;
320                                 }
321                                 for (String v : entry.getValue()) {
322                                         resp.setHeader(entry.getKey(), v);
323                                         s += String.format("%s:%s;", entry.getKey(), v);
324                                 }
325                                 if (MyProperties.getInstance().corsEnabled()) {
326                                         resp.setHeader("Access-Control-Allow-Origin", "*");
327                                         // resp.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
328                                         resp.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
329                                 }
330
331                         }
332                 }
333                 LOG.debug("Received Headers: {}", s);
334                 lensum = 0;
335                 if (response != null) {
336                         while (true) {
337                                 len = response.read(buffer, 0, BUFSIZE);
338                                 if (len <= 0) {
339                                         break;
340                                 }
341                                 lensum += len;
342                                 resp.getOutputStream().write(buffer, 0, len);
343                         }
344                 } else {
345                         LOG.debug("response is null");
346                 }
347                 LOG.debug("Received {} bytes", lensum);
348         }
349
350 }