Reduce the number of problems in aai-common by removing unused imports
[aai/aai-common.git] / aai-els-onap-logging / src / main / java / org / onap / logging / filter / base / PayloadLoggingServletFilter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - Logging
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (C) 2018 IBM.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.logging.filter.base;
24
25 import java.io.BufferedReader;
26 import java.io.ByteArrayInputStream;
27 import java.io.ByteArrayOutputStream;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.io.PrintWriter;
32 import java.util.zip.GZIPInputStream;
33
34 import javax.servlet.Filter;
35 import javax.servlet.FilterChain;
36 import javax.servlet.FilterConfig;
37 import javax.servlet.ReadListener;
38 import javax.servlet.ServletException;
39 import javax.servlet.ServletInputStream;
40 import javax.servlet.ServletOutputStream;
41 import javax.servlet.ServletRequest;
42 import javax.servlet.ServletResponse;
43 import javax.servlet.WriteListener;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletRequestWrapper;
46 import javax.servlet.http.HttpServletResponse;
47 import javax.servlet.http.HttpServletResponseWrapper;
48
49 public class PayloadLoggingServletFilter extends AbstractServletFilter implements Filter {
50
51     private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PayloadLoggingServletFilter.class);
52
53     private static class ByteArrayServletStream extends ServletOutputStream {
54         ByteArrayOutputStream baos;
55
56         ByteArrayServletStream(ByteArrayOutputStream baos) {
57             this.baos = baos;
58         }
59
60         @Override
61         public void write(int param) throws IOException {
62             baos.write(param);
63         }
64
65         @Override
66         public boolean isReady() {
67             return true;
68         }
69
70         @Override
71         public void setWriteListener(WriteListener arg0) {
72             // this method does nothing
73         }
74     }
75
76     private static class ByteArrayPrintWriter extends PrintWriter {
77         private ByteArrayOutputStream baos;
78         private int errorCode = -1;
79         private String errorMsg = "";
80         private boolean errored = false;
81
82         public ByteArrayPrintWriter(ByteArrayOutputStream out) {
83             super(out);
84             this.baos = out;
85         }
86
87         public ServletOutputStream getStream() {
88             return new ByteArrayServletStream(baos);
89         }
90
91         public Boolean hasErrored() {
92             return errored;
93         }
94
95         public int getErrorCode() {
96             return errorCode;
97         }
98
99         public String getErrorMsg() {
100             return errorMsg;
101         }
102
103         public void setError(int code) {
104             errorCode = code;
105             errored = true;
106         }
107
108         public void setError(int code, String msg) {
109             errorMsg = msg;
110             errorCode = code;
111             errored = true;
112         }
113
114     }
115
116     private class BufferedServletInputStream extends ServletInputStream {
117         ByteArrayInputStream bais;
118
119         public BufferedServletInputStream(ByteArrayInputStream bais) {
120             this.bais = bais;
121         }
122
123         @Override
124         public int available() {
125             return bais.available();
126         }
127
128         @Override
129         public int read() {
130             return bais.read();
131         }
132
133         @Override
134         public int read(byte[] buf, int off, int len) {
135             return bais.read(buf, off, len);
136         }
137
138         @Override
139         public boolean isFinished() {
140             return available() < 1;
141         }
142
143         @Override
144         public boolean isReady() {
145             return true;
146         }
147
148         @Override
149         public void setReadListener(ReadListener arg0) {
150             // this method does nothing
151         }
152
153     }
154
155     private class BufferedRequestWrapper extends HttpServletRequestWrapper {
156         ByteArrayInputStream bais;
157         ByteArrayOutputStream baos;
158         BufferedServletInputStream bsis;
159         byte[] buffer;
160
161         public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
162             super(req);
163
164             InputStream is = req.getInputStream();
165             baos = new ByteArrayOutputStream();
166             byte[] buf = new byte[1024];
167             int letti;
168             while ((letti = is.read(buf)) > 0) {
169                 baos.write(buf, 0, letti);
170             }
171             buffer = baos.toByteArray();
172         }
173
174         @Override
175         public ServletInputStream getInputStream() {
176             try {
177                 bais = new ByteArrayInputStream(buffer);
178                 bsis = new BufferedServletInputStream(bais);
179             } catch (Exception ex) {
180                 log.error("Exception in getInputStream", ex);
181             }
182             return bsis;
183         }
184
185         public byte[] getBuffer() {
186             return buffer;
187         }
188     }
189
190     @Override
191     public void init(FilterConfig filterConfig) throws ServletException {
192         // this method does nothing
193     }
194
195     @Override
196     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
197             throws IOException, ServletException {
198         final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
199         BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpRequest);
200
201         StringBuilder requestHeaders = new StringBuilder("REQUEST|");
202         requestHeaders.append(httpRequest.getMethod());
203         requestHeaders.append(":");
204         requestHeaders.append(httpRequest.getRequestURL().toString());
205         requestHeaders.append("|");
206         requestHeaders.append(getSecureRequestHeaders(httpRequest));
207         log.info(requestHeaders.toString());
208
209         log.info("REQUEST BODY|" + new String(bufferedRequest.getBuffer()));
210
211         final HttpServletResponse response = (HttpServletResponse) servletResponse;
212         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
213         final ByteArrayPrintWriter pw = new ByteArrayPrintWriter(baos);
214
215         HttpServletResponse wrappedResp = new HttpServletResponseWrapper(response) {
216             @Override
217             public PrintWriter getWriter() {
218                 return pw;
219             }
220
221             @Override
222             public ServletOutputStream getOutputStream() {
223                 return pw.getStream();
224             }
225
226             @Override
227             public void sendError(int sc) throws IOException {
228                 super.sendError(sc);
229                 pw.setError(sc);
230
231             }
232
233             @Override
234             public void sendError(int sc, String msg) throws IOException {
235                 super.sendError(sc, msg);
236                 pw.setError(sc, msg);
237             }
238         };
239
240         try {
241             filterChain.doFilter(bufferedRequest, wrappedResp);
242         } catch (Exception e) {
243             log.error("Chain Exception", e);
244             throw e;
245         } finally {
246             try {
247                 byte[] bytes = baos.toByteArray();
248                 StringBuilder responseHeaders = new StringBuilder("RESPONSE HEADERS|");
249                 responseHeaders.append(formatResponseHeaders(response));
250                 responseHeaders.append("Status:");
251                 responseHeaders.append(response.getStatus());
252                 responseHeaders.append(";IsCommited:" + wrappedResp.isCommitted());
253
254                 log.info(responseHeaders.toString());
255
256                 if ("gzip".equals(response.getHeader("Content-Encoding"))) {
257                     log.info("UNGZIPED RESPONSE BODY|" + decompressGZIPByteArray(bytes));
258                 } else {
259                     log.info("RESPONSE BODY|" + new String(bytes));
260                 }
261
262                 if (pw.hasErrored()) {
263                     log.info("ERROR RESPONSE|" + pw.getErrorCode() + ":" + pw.getErrorMsg());
264                 } else {
265                     if (!wrappedResp.isCommitted()) {
266                         response.getOutputStream().write(bytes);
267                         response.getOutputStream().flush();
268                     }
269                 }
270             } catch (Exception e) {
271                 log.error("Exception in response filter", e);
272             }
273         }
274     }
275
276     @Override
277     public void destroy() {
278         // this method does nothing
279     }
280
281     private String decompressGZIPByteArray(byte[] bytes) {
282         BufferedReader in = null;
283         InputStreamReader inR = null;
284         ByteArrayInputStream byteS = null;
285         GZIPInputStream gzS = null;
286         StringBuilder str = new StringBuilder();
287         try {
288             byteS = new ByteArrayInputStream(bytes);
289             gzS = new GZIPInputStream(byteS);
290             inR = new InputStreamReader(gzS);
291             in = new BufferedReader(inR);
292
293             if (in != null) {
294                 String content;
295                 while ((content = in.readLine()) != null) {
296                     str.append(content);
297                 }
298             }
299
300         } catch (Exception e) {
301             log.error("Failed get read GZIPInputStream", e);
302         } finally {
303             if (byteS != null)
304                 try {
305                     byteS.close();
306                 } catch (IOException e1) {
307                     log.error("Failed to close ByteStream", e1);
308                 }
309             if (gzS != null)
310                 try {
311                     gzS.close();
312                 } catch (IOException e2) {
313                     log.error("Failed to close GZStream", e2);
314                 }
315             if (inR != null)
316                 try {
317                     inR.close();
318                 } catch (IOException e3) {
319                     log.error("Failed to close InputReader", e3);
320                 }
321             if (in != null)
322                 try {
323                     in.close();
324                 } catch (IOException e) {
325                     log.error("Failed to close BufferedReader", e);
326                 }
327         }
328         return str.toString();
329     }
330
331 }