2 * ============LICENSE_START=======================================================
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
23 package org.onap.logging.filter.base;
25 import javax.servlet.*;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletRequestWrapper;
28 import javax.servlet.http.HttpServletResponse;
29 import javax.servlet.http.HttpServletResponseWrapper;
31 import java.util.zip.GZIPInputStream;
33 public class PayloadLoggingServletFilter extends AbstractServletFilter implements Filter {
35 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PayloadLoggingServletFilter.class);
38 private static class ByteArrayServletStream extends ServletOutputStream {
39 ByteArrayOutputStream baos;
41 ByteArrayServletStream(ByteArrayOutputStream baos) {
46 public void write(int param) throws IOException {
51 public boolean isReady() {
56 public void setWriteListener(WriteListener arg0) {
57 // this method does nothing
62 private static class ByteArrayPrintWriter extends PrintWriter {
63 private ByteArrayOutputStream baos;
64 private int errorCode = -1;
65 private String errorMsg = "";
66 private boolean errored = false;
68 public ByteArrayPrintWriter(ByteArrayOutputStream out) {
73 public ServletOutputStream getStream() {
74 return new ByteArrayServletStream(baos);
77 public Boolean hasErrored() {
81 public int getErrorCode() {
85 public String getErrorMsg() {
89 public void setError(int code) {
94 public void setError(int code, String msg) {
103 private class BufferedServletInputStream extends ServletInputStream {
104 ByteArrayInputStream bais;
106 public BufferedServletInputStream(ByteArrayInputStream bais) {
111 public int available() {
112 return bais.available();
121 public int read(byte[] buf, int off, int len) {
122 return bais.read(buf, off, len);
126 public boolean isFinished() {
127 return available() < 1;
131 public boolean isReady() {
136 public void setReadListener(ReadListener arg0) {
137 // this method does nothing
143 private class BufferedRequestWrapper extends HttpServletRequestWrapper {
144 ByteArrayInputStream bais;
145 ByteArrayOutputStream baos;
146 BufferedServletInputStream bsis;
149 public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
152 InputStream is = req.getInputStream();
153 baos = new ByteArrayOutputStream();
154 byte[] buf = new byte[1024];
156 while ((letti = is.read(buf)) > 0) {
157 baos.write(buf, 0, letti);
159 buffer = baos.toByteArray();
163 public ServletInputStream getInputStream() {
165 bais = new ByteArrayInputStream(buffer);
166 bsis = new BufferedServletInputStream(bais);
167 } catch (Exception ex) {
168 log.error("Exception in getInputStream", ex);
173 public byte[] getBuffer() {
179 public void init(FilterConfig filterConfig) throws ServletException {
180 // this method does nothing
184 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
185 throws IOException, ServletException {
186 final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
187 BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpRequest);
189 StringBuilder requestHeaders = new StringBuilder("REQUEST|");
190 requestHeaders.append(httpRequest.getMethod());
191 requestHeaders.append(":");
192 requestHeaders.append(httpRequest.getRequestURL().toString());
193 requestHeaders.append("|");
194 requestHeaders.append(getSecureRequestHeaders(httpRequest));
196 log.info(requestHeaders.toString());
197 log.info("REQUEST BODY|{}", new String(bufferedRequest.getBuffer()));
199 final HttpServletResponse response = (HttpServletResponse) servletResponse;
200 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
201 final ByteArrayPrintWriter pw = new ByteArrayPrintWriter(baos);
203 HttpServletResponse wrappedResp = new HttpServletResponseWrapper(response) {
205 public PrintWriter getWriter() {
210 public ServletOutputStream getOutputStream() {
211 return pw.getStream();
215 public void sendError(int sc) throws IOException {
221 public void sendError(int sc, String msg) throws IOException {
222 super.sendError(sc, msg);
223 pw.setError(sc, msg);
228 filterChain.doFilter(bufferedRequest, wrappedResp);
229 } catch (Exception e) {
230 log.error("Chain Exception", e);
234 byte[] bytes = baos.toByteArray();
235 StringBuilder responseHeaders = new StringBuilder();
236 responseHeaders.append("RESPONSE HEADERS|").append(formatResponseHeaders(response));
237 responseHeaders.append("Status:").append(response.getStatus());
238 responseHeaders.append(";IsCommitted:").append(wrappedResp.isCommitted());
240 log.info(responseHeaders.toString());
242 if ("gzip".equals(response.getHeader("Content-Encoding"))) {
243 log.info("UNGZIPED RESPONSE BODY|{}", decompressGZIPByteArray(bytes));
245 log.info("RESPONSE BODY|{}", new String(bytes));
248 if (pw.hasErrored()) {
249 log.info("ERROR RESPONSE|{}:{}", pw.getErrorCode(), pw.getErrorMsg());
250 } else if (!wrappedResp.isCommitted()) {
251 response.getOutputStream().write(bytes);
252 response.getOutputStream().flush();
254 } catch (Exception e) {
255 log.error("Exception in response filter", e);
261 public void destroy() {
262 // this method does nothing
265 private String decompressGZIPByteArray(byte[] bytes) {
266 StringBuilder str = new StringBuilder();
267 try (BufferedReader in =
268 new BufferedReader(new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(bytes))))) {
270 while ((content = in.readLine()) != null) {
273 } catch (Exception e) {
274 log.error("Failed get read GZIPInputStream", e);
276 return str.toString();