06002a20011fe446a37efcc5995896cd3c615004
[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                         else {
165                                 this.set404Response(resp);
166                         }
167                 }
168         }
169
170         @Override
171         protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
172                 if (this.isOff()) {
173                         this.sendOffResponse(resp);
174                 } else {
175                         this.trysslSetup();
176                         HttpURLConnection http = null;
177                         try {
178                                 http = (HttpURLConnection) this.getConnection(req, "PUT");
179                         } catch (IOException e) {
180                                 LOG.warn(e.getMessage());
181                         }
182                         if (http != null) {
183                                 try {
184                                         this.handleRequest(http, req, resp, "PUT");
185                                 } catch (IOException e) {
186                                         LOG.warn(e.getMessage());
187                                 }
188                                 http.disconnect();
189                         }
190                         else {
191                                 this.set404Response(resp);
192                         }
193                 }
194         }
195
196         @Override
197         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
198                 if (this.isOff()) {
199                         this.sendOffResponse(resp);
200                 } else {
201                         this.trysslSetup();
202                         HttpURLConnection http = null;
203                         try {
204                                 http = (HttpURLConnection) this.getConnection(req, "POST");
205                         } catch (IOException e) {
206                                 LOG.warn(e.getMessage());
207                         }
208                         if (http != null) {
209                                 try {
210                                         this.handleRequest(http, req, resp, "POST");
211                                 } catch (IOException e) {
212                                         LOG.warn(e.getMessage());
213                                 }
214                                 http.disconnect();
215                         }
216                         else {
217                                 this.set404Response(resp);
218                         }
219                 }
220         }
221
222         @Override
223         protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
224                 if (this.isOff()) {
225                         this.sendOffResponse(resp);
226                 } else {
227                         this.trysslSetup();
228                         HttpURLConnection http = null;
229                         try {
230                                 http = (HttpURLConnection) this.getConnection(req, "DELETE");
231                         } catch (IOException e) {
232                                 LOG.warn(e.getMessage());
233                         }
234                         if (http != null) {
235                                 try {
236                                         this.handleRequest(http, req, resp, "DELETE");
237                                 } catch (IOException e) {
238                                         LOG.warn(e.getMessage());
239                                 }
240                                 http.disconnect();
241                         }
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(method=="GET") {
257                         Enumeration<String> params = req.getParameterNames();
258                         if(params!=null) {
259                                 String param;
260                                 if(params.hasMoreElements()) {
261                                         param=params.nextElement();
262                                         surl+="?"+param+"="+req.getParameter(param);
263                                 }
264                                 while(params.hasMoreElements()) {
265                                         param=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 (trustAll) {
280                                 HostnameVerifier allHostsValid = new HostnameVerifier() {
281
282                                         @Override
283                                         public boolean verify(String hostname, SSLSession session) {
284                                                 // do not verify host if trust all
285                                                 return true;
286                                         }
287                                 };
288                                 ((HttpsURLConnection) http).setHostnameVerifier(allHostsValid);
289                         }
290                 }
291                 http.setDoOutput(true);
292                 // copy request headers
293                 String s = "";
294                 Enumeration<String> headers = req.getHeaderNames();
295                 while (headers.hasMoreElements()) {
296                         String h = headers.nextElement();
297                         String v = req.getHeader(h);
298                         if (h != null && h.equals("Host")) {
299                                 v = url.getAuthority();
300                         }
301                         s += String.format("%s:%s;", h, v);
302                         http.setRequestProperty(h, v);
303                 }
304                 LOG.debug("Request Headers: {}", s);
305                 return http;
306         }
307
308         private void handleRequest(HttpURLConnection http, HttpServletRequest req, HttpServletResponse resp, String method)
309                         throws IOException {
310                 byte[] buffer = new byte[BUFSIZE];
311                 int len = 0, lensum = 0;
312                 // send request
313                 // Send the message to destination
314                 OutputStream output = null;
315                 if (!method.equals("GET")) {
316                         try {
317                                 output = http.getOutputStream();
318                         } catch (Exception e) {
319                                 LOG.debug("problem reading output stream: {}", e.getMessage());
320                         }
321                 }
322                 if (output != null) {
323                         while (true) {
324                                 len = req.getInputStream().read(buffer, 0, BUFSIZE);
325                                 if (len <= 0) {
326                                         break;
327                                 }
328                                 lensum += len;
329                                 output.write(buffer, 0, len);
330                         }
331                 }
332                 LOG.debug("written {} data out", lensum);
333                 int responseCode = http.getResponseCode();
334                 // Receive answer
335                 InputStream response;
336                 if (responseCode >= 200 && responseCode < 300) {
337                         response = http.getInputStream();
338                 } else {
339                         response = http.getErrorStream();
340                         if (response == null) {
341                                 http.getInputStream();
342                         }
343                 }
344
345                 LOG.debug("ResponseCode: {}", responseCode);
346                 resp.setStatus(responseCode);
347                 Map<String, List<String>> set = http.getHeaderFields();
348                 String s = "";
349                 if (set != null) {
350                         for (Map.Entry<String, List<String>> entry : set.entrySet()) {
351                                 if (entry.getKey() == null) {
352                                         continue;
353                                 }
354                                 for (String v : entry.getValue()) {
355                                         resp.setHeader(entry.getKey(), v);
356                                         s += String.format("%s:%s;", entry.getKey(), v);
357                                 }
358                                 if (MyProperties.getInstance().corsEnabled()) {
359                                         resp.setHeader("Access-Control-Allow-Origin", "*");
360                                         // resp.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
361                                         resp.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
362                                 }
363
364                         }
365                 }
366                 LOG.debug("Received Headers: {}", s);
367                 lensum = 0;
368                 if (response != null) {
369                         while (true) {
370                                 len = response.read(buffer, 0, BUFSIZE);
371                                 if (len <= 0) {
372                                         break;
373                                 }
374                                 lensum += len;
375                                 resp.getOutputStream().write(buffer, 0, len);
376                         }
377                 } else {
378                         LOG.debug("response is null");
379                 }
380                 LOG.debug("Received {} bytes", lensum);
381         }
382
383 }