Update groupId to org.onap.ccsdk.sli
[ccsdk/sli/core.git] / filters / provider / src / main / java / org / onap / ccsdk / sli / core / filters / RequestResponseDbLoggingFilter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK
4  * ================================================================================
5  * Copyright (C) 2017 ONAP
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.ccsdk.sli.core.filters;
22
23 import java.io.BufferedReader;
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.io.PrintWriter;
30 import java.util.zip.GZIPInputStream;
31
32 import javax.servlet.Filter;
33 import javax.servlet.FilterChain;
34 import javax.servlet.FilterConfig;
35 import javax.servlet.ServletException;
36 import javax.servlet.ServletInputStream;
37 import javax.servlet.ServletOutputStream;
38 import javax.servlet.ServletRequest;
39 import javax.servlet.ServletResponse;
40 import javax.servlet.http.HttpServletRequest;
41 import javax.servlet.http.HttpServletRequestWrapper;
42 import javax.servlet.http.HttpServletResponse;
43 import javax.servlet.http.HttpServletResponseWrapper;
44
45 import org.onap.ccsdk.sli.core.sli.MessageWriter;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 public class RequestResponseDbLoggingFilter implements Filter {
50
51         private static Logger log = LoggerFactory.getLogger(RequestResponseDbLoggingFilter.class);
52
53         public static final String REQUEST_ID = "X-ECOMP-RequestID";
54
55         private static class ByteArrayServletStream extends ServletOutputStream {
56
57                 ByteArrayOutputStream baos;
58
59                 ByteArrayServletStream(ByteArrayOutputStream baos) {
60                         this.baos = baos;
61                 }
62
63                 @Override
64                 public void write(int param) throws IOException {
65                         baos.write(param);
66                 }
67         }
68
69         private static class ByteArrayPrintWriter {
70
71                 private ByteArrayOutputStream baos = new ByteArrayOutputStream();
72
73                 private PrintWriter pw = new PrintWriter(baos);
74
75                 private ServletOutputStream sos = new ByteArrayServletStream(baos);
76
77                 public PrintWriter getWriter() {
78                         return pw;
79                 }
80
81                 public ServletOutputStream getStream() {
82                         return sos;
83                 }
84
85                 byte[] toByteArray() {
86                         return baos.toByteArray();
87                 }
88         }
89
90         private class BufferedServletInputStream extends ServletInputStream {
91
92                 ByteArrayInputStream bais;
93
94                 public BufferedServletInputStream(ByteArrayInputStream bais) {
95                         this.bais = bais;
96                 }
97
98                 @Override
99                 public int available() {
100                         return bais.available();
101                 }
102
103                 @Override
104                 public int read() {
105                         return bais.read();
106                 }
107
108                 @Override
109                 public int read(byte[] buf, int off, int len) {
110                         return bais.read(buf, off, len);
111                 }
112
113         }
114
115         private class BufferedRequestWrapper extends HttpServletRequestWrapper {
116
117                 ByteArrayInputStream bais;
118
119                 ByteArrayOutputStream baos;
120
121                 BufferedServletInputStream bsis;
122
123                 byte[] buffer;
124
125                 public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
126                         super(req);
127
128                         InputStream is = req.getInputStream();
129                         baos = new ByteArrayOutputStream();
130                         byte buf[] = new byte[1024];
131                         int letti;
132                         while ((letti = is.read(buf)) > 0) {
133                                 baos.write(buf, 0, letti);
134                         }
135                         buffer = baos.toByteArray();
136
137                 }
138
139                 @Override
140                 public ServletInputStream getInputStream() {
141                         try {
142                                 bais = new ByteArrayInputStream(buffer);
143                                 bsis = new BufferedServletInputStream(bais);
144                         } catch (Exception ex) {
145                                 ex.printStackTrace();
146                         }
147
148                         return bsis;
149                 }
150
151                 public byte[] getBuffer() {
152                         return buffer;
153                 }
154
155         }
156
157         @Override
158         public void init(FilterConfig filterConfig) throws ServletException {
159         }
160
161         @Override
162         public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
163                 throws IOException, ServletException {
164
165                 if (request == null || !(request instanceof HttpServletRequest)) {
166                         filterChain.doFilter(request, response);
167                         return;
168                 }
169
170                 long t1 = System.currentTimeMillis();
171
172                 final HttpServletRequest httpRequest = (HttpServletRequest) request;
173                 BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpRequest);
174
175                 String requestId = httpRequest.getHeader(REQUEST_ID);
176                 if (requestId == null || requestId.trim().length() == 0) {
177                         log.warn("Could not write request in DB: " + REQUEST_ID + " is missing in the HTTP headers.");
178                         return;
179                 }
180
181                 String requestHost = request.getRemoteHost();
182                 if (requestHost == null)
183                         requestHost = request.getRemoteAddr();
184
185                 String requestStr = new String(bufferedRequest.getBuffer());
186
187                 MessageWriter.saveIncomingRequest(requestId, null, requestHost, requestStr);
188
189                 long t2 = System.currentTimeMillis();
190
191                 log.info("Request saved in DB for request-id: " + requestId + ". TIme: " + (t2 - t1));
192
193                 final HttpServletResponse httpResponse = (HttpServletResponse) response;
194
195                 final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
196                 HttpServletResponse wrappedResp = new HttpServletResponseWrapper(httpResponse) {
197
198                         @Override
199                         public PrintWriter getWriter() {
200                                 return pw.getWriter();
201                         }
202
203                         @Override
204                         public ServletOutputStream getOutputStream() {
205                                 return pw.getStream();
206                         }
207                 };
208
209                 try {
210
211                         filterChain.doFilter(bufferedRequest, wrappedResp);
212
213                 } finally {
214
215                         if (request != null && request instanceof HttpServletRequest) {
216
217                                 t1 = System.currentTimeMillis();
218
219                                 byte[] bytes = pw.toByteArray();
220                                 response.getOutputStream().write(bytes);
221                                 response.getOutputStream().flush();
222
223                                 String responseStr = null;
224                                 if ("gzip".equals(httpResponse.getHeader("Content-Encoding"))) {
225                                         responseStr = decompressGZIPByteArray(bytes);
226                                 } else {
227                                         responseStr = new String(bytes);
228                                 }
229
230                                 MessageWriter.saveIncomingResponse(requestId, httpResponse.getStatus(), responseStr);
231
232                                 t2 = System.currentTimeMillis();
233
234                                 log.info("Response saved in DB for request-id: " + requestId + ". TIme: " + (t2 - t1));
235                         }
236                 }
237
238         }
239
240         @Override
241         public void destroy() {
242         }
243
244         private String decompressGZIPByteArray(byte[] bytes) {
245
246                 BufferedReader in = null;
247                 InputStreamReader inR = null;
248                 ByteArrayInputStream byteS = null;
249                 GZIPInputStream gzS = null;
250                 StringBuilder str = new StringBuilder();
251                 try {
252                         byteS = new ByteArrayInputStream(bytes);
253                         gzS = new GZIPInputStream(byteS);
254                         inR = new InputStreamReader(gzS);
255                         in = new BufferedReader(inR);
256
257                         if (in != null) {
258
259                                 String content;
260
261                                 while ((content = in.readLine()) != null) {
262                                         str.append(content);
263                                 }
264                         }
265
266                 } catch (Exception e) {
267                         log.error("Failed get read GZIPInputStream", e);
268                 } finally {
269
270                         if (byteS != null)
271                                 try {
272                                         byteS.close();
273                                 } catch (IOException e1) {
274                                         log.error("Failed to close ByteStream", e1);
275                                 }
276                         if (gzS != null)
277                                 try {
278                                         gzS.close();
279                                 } catch (IOException e2) {
280                                         log.error("Failed to close GZStream", e2);
281                                 }
282                         if (inR != null)
283                                 try {
284                                         inR.close();
285                                 } catch (IOException e3) {
286                                         log.error("Failed to close InputReader", e3);
287                                 }
288                         if (in != null)
289                                 try {
290                                         in.close();
291                                 } catch (IOException e) {
292                                         log.error("Failed to close BufferedReader", e);
293                                 }
294                 }
295                 return str.toString();
296         }
297 }