missing logs 06/122506/1
authorTIMONEY, DANIEL <dtimoney@att.com>
Wed, 7 Jul 2021 17:54:07 +0000 (17:54 +0000)
committerlalena.aria <lalena.aria@att.com>
Wed, 7 Jul 2021 17:54:08 +0000 (17:54 +0000)
Add filters for audit and request/response log
Add filters for audit and request/response log

Issue-ID: CCSDK-3367
Signed-off-by: lalena.aria <lalena.aria@att.com>
Change-Id: Id292c1f5109f0c3846a0357d0618f607011825a4

ms/sliboot/pom.xml
services/pom.xml
services/src/main/java/org/onap/ccsdk/apps/filters/AuditLogFilter.java [new file with mode: 0644]
services/src/main/java/org/onap/ccsdk/apps/filters/PayloadLoggingFilter.java [new file with mode: 0644]

index 46e2c4f..d17d4e5 100644 (file)
             <artifactId>springfox-swagger-ui</artifactId>
             <version>2.9.2</version>
         </dependency>
+        <!-- Needed by logging-analytics payload logging filter -->
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
+            <version>3.4.4</version>
+        </dependency>
         <dependency>
             <groupId>org.onap.aaf.authz</groupId>
             <artifactId>aaf-cadi-client</artifactId>
index 36f0425..00aa8d4 100644 (file)
@@ -22,6 +22,7 @@
         <ccsdk.project.version>${project.version}</ccsdk.project.version>
         <ccsdk.build.timestamp>${maven.build.timestamp}</ccsdk.build.timestamp>
         <maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format>
+        <logging.analytics.version>1.6.9</logging.analytics.version>
     </properties>
 
     <dependencies>
@@ -95,7 +96,7 @@
         <dependency>
             <groupId>org.onap.logging-analytics</groupId>
             <artifactId>logging-filter-spring</artifactId>
-            <version>1.6.6</version>
+            <version>${logging.analytics.version}</version>
         </dependency>
         <dependency>
             <groupId>javax.ws.rs</groupId>
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/AuditLogFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/AuditLogFilter.java
new file mode 100644 (file)
index 0000000..b6d52c5
--- /dev/null
@@ -0,0 +1,43 @@
+package org.onap.ccsdk.apps.filters
+;
+
+import javax.servlet.http.HttpServletRequest;
+import org.onap.logging.filter.base.AuditLogServletFilter;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AuditLogFilter extends AuditLogServletFilter {
+    private static final String MDC_HTTP_METHOD_KEY = "HttpMethod";
+
+    @Override
+    protected void additionalPreHandling(HttpServletRequest httpServletRequest) {
+        // Don't overwrite service instance id if it was set outside of this automated method
+        if (MDC.get(ONAPLogConstants.MDCs.SERVICE_INSTANCE_ID) == null) {
+            String serviceInstanceId = getServiceInstanceId(httpServletRequest.getRequestURI());
+            if (serviceInstanceId != null) {
+                MDC.put(ONAPLogConstants.MDCs.SERVICE_INSTANCE_ID, serviceInstanceId);
+            }
+        }
+        MDC.put(MDC_HTTP_METHOD_KEY, httpServletRequest.getMethod());
+    }
+
+    // restconf URLs follow a pattern, this method attempts to extract the service instance id according to that pattern
+    protected String getServiceInstanceId(String path) {
+        int idx = path.indexOf("service-list");
+        if (idx != -1) {
+            // chomp off service-list/
+            String str = path.substring(idx + 13);
+            idx = str.indexOf("/");
+            //if there is another forward slash with more information chomp it off
+            if (idx != -1) {
+                return str.substring(0, idx);
+            } else {
+                return str;
+            }
+        }
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/PayloadLoggingFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/PayloadLoggingFilter.java
new file mode 100644 (file)
index 0000000..e53c50a
--- /dev/null
@@ -0,0 +1,322 @@
+package org.onap.ccsdk.apps.filters;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ReadListener;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.WriteListener;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.onap.logging.filter.base.AbstractServletFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PayloadLoggingFilter extends AbstractServletFilter implements Filter {
+
+       private static final Logger log = LoggerFactory.getLogger(PayloadLoggingFilter.class);
+
+       @Override
+       public void init(FilterConfig filterConfig) throws ServletException {
+       }
+
+       @Override
+       public void destroy() {
+       }
+
+       @Override
+       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+               RequestWrapper req = new RequestWrapper((HttpServletRequest) request);
+               Request requestData = req.getMessageRequest();
+               
+               StringBuilder requestHeaders = new StringBuilder("REQUEST|");
+           requestHeaders.append(requestData.method);
+           requestHeaders.append(":");
+           requestHeaders.append(requestData.uri);
+           requestHeaders.append("|");
+           mapstr(requestHeaders, requestData.headers);
+
+           log.info(requestHeaders.toString());
+           log.info("REQUEST BODY|{}", requestData.body);
+
+               ResponseWrapper res = new ResponseWrapper((HttpServletResponse) response);
+
+               chain.doFilter(req, res);
+
+               Response responseData = res.getMessageResponse();
+               
+               StringBuilder responseHeaders = new StringBuilder();
+        responseHeaders.append("RESPONSE HEADERS|");
+        mapstr(responseHeaders, responseData.headers);
+        responseHeaders.append("Status:").append(responseData.code);
+        responseHeaders.append(";IsCommitted:").append(res.isCommitted());
+
+        log.info(responseHeaders.toString());
+               log.info("RESPONSE BODY|{}", responseData.body);
+
+               res.writeBody();
+       }
+
+       private static class Request {
+
+               public String method;
+               public String uri;
+               public Map<String, Object> headers;
+               public Map<String, Object> param;
+               public String body;
+
+               @Override
+               public String toString() {
+                       StringBuilder ss = new StringBuilder();
+                       ss.append("REQUEST|").append(method).append(":").append(uri).append("|");
+                       ss.append("Headers: ");
+                       mapstr(ss, headers);
+                       if (param != null && !param.isEmpty()) {
+                               ss.append("Parameters: ");
+                               mapstr(ss, param);
+                       }
+                       ss.append("REQUEST BODY|\n");
+                       ss.append(body);
+                       return ss.toString();
+               }
+       }
+
+       private static class Response {
+
+               public int code;
+               public String message;
+               public Map<String, Object> headers;
+               public String body;
+
+               @Override
+               public String toString() {
+                       StringBuilder ss = new StringBuilder();
+                       ss.append("HTTP Response: ").append(code).append(" ").append(message).append("\n");
+                       ss.append("Headers:\n");
+                       mapstr(ss, headers);
+                       ss.append("Body:\n");
+                       ss.append(body);
+                       return ss.toString();
+               }
+       }
+
+       private static class RequestWrapper extends HttpServletRequestWrapper {
+
+               private final String body;
+
+               public RequestWrapper(HttpServletRequest request) throws IOException {
+                       super(request);
+
+                       StringBuilder stringBuilder = new StringBuilder();
+                       InputStream inputStream = request.getInputStream();
+                       if (inputStream != null) {
+                               try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
+                                       char[] charBuffer = new char[128];
+                                       int bytesRead = -1;
+                                       while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
+                                               stringBuilder.append(charBuffer, 0, bytesRead);
+                                       }
+                               }
+                       }
+                       body = stringBuilder.toString();
+               }
+
+               @Override
+               public ServletInputStream getInputStream() throws IOException {
+                       final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
+                       ServletInputStream servletInputStream = new ServletInputStream() {
+
+                               @Override
+                               public int read() throws IOException {
+                                       return byteArrayInputStream.read();
+                               }
+
+                               @Override
+                               public boolean isFinished() {
+                                       return byteArrayInputStream.available() == 0;
+                               }
+
+                               @Override
+                               public boolean isReady() {
+                                       return true;
+                               }
+
+                               @Override
+                               public void setReadListener(ReadListener listener) {
+                               }
+                       };
+                       return servletInputStream;
+               }
+
+               @Override
+               public BufferedReader getReader() throws IOException {
+                       return new BufferedReader(new InputStreamReader(getInputStream()));
+               }
+
+               public String getBody() {
+                       return body;
+               }
+
+               public Request getMessageRequest() {
+                       Request r = new Request();
+                       r.method = getMethod();
+                       r.uri = getRequestURI();
+                       r.param = getParamMap();
+
+                       r.headers = new HashMap<>();
+                       Enumeration<String> headerNames = getHeaderNames();
+                       while (headerNames.hasMoreElements()) {
+                               String name = headerNames.nextElement();
+
+                               if (name.equalsIgnoreCase("authorization")) {
+                                       r.headers.put(name, "***REDACTED***");
+                                       continue;
+                               }
+
+                               Enumeration<String> values = getHeaders(name);
+                               List<String> valueList = new ArrayList<>();
+                               while (values.hasMoreElements()) {
+                                       valueList.add(values.nextElement());
+                               }
+                               if (valueList.size() > 1) {
+                                       r.headers.put(name, valueList);
+                               } else if (valueList.size() > 0) {
+                                       r.headers.put(name, valueList.get(0));
+                               }
+                       }
+
+                       r.body = getBody();
+
+                       return r;
+               }
+
+               private Map<String, Object> getParamMap() {
+                       Map<String, String[]> parameterMap = getParameterMap();
+                       Map<String, Object> paramMap = new HashMap<>();
+                       if (parameterMap != null) {
+                               for (Entry<String, String[]> entry : parameterMap.entrySet()) {
+                                       String name = entry.getKey();
+                                       String[] values = entry.getValue();
+                                       if (values != null && values.length > 0) {
+                                               if (values.length == 1) {
+                                                       paramMap.put(name, values[0]);
+                                               } else {
+                                                       paramMap.put(name, Arrays.<String> asList(values));
+                                               }
+                                       }
+                               }
+                       }
+                       return paramMap;
+               }
+       }
+
+       public class ResponseWrapper extends HttpServletResponseWrapper {
+
+               private CharArrayWriter writer = new CharArrayWriter();
+
+               private String statusMessage;
+
+               public ResponseWrapper(HttpServletResponse response) {
+                       super(response);
+               }
+
+               @Override
+               public PrintWriter getWriter() {
+                       return new PrintWriter(writer);
+               }
+
+               @Override
+               public ServletOutputStream getOutputStream() {
+                       return new ServletOutputStream() {
+
+                               @Override
+                               public void write(int b) throws IOException {
+                                       writer.write(b);
+                               }
+
+                               @Override
+                               public void setWriteListener(WriteListener listener) {
+                               }
+
+                               @Override
+                               public boolean isReady() {
+                                       return true;
+                               }
+                       };
+               }
+
+               @SuppressWarnings("deprecation")
+               @Override
+               public void setStatus(int sc, String sm) {
+                       super.setStatus(sc, sm);
+                       statusMessage = sm;
+               }
+
+               public Response getMessageResponse() {
+                       Response r = new Response();
+                       r.code = getStatus();
+                       r.message = statusMessage == null ? "" : statusMessage;
+
+                       r.headers = new HashMap<>();
+                       Collection<String> headerNames = getHeaderNames();
+                       for (String name : headerNames) {
+
+                               if (name.equalsIgnoreCase("authorization")) {
+                                       r.headers.put(name, "***REDACTED***");
+                                       continue;
+                               }
+
+                               Collection<String> values = getHeaders(name);
+                               List<String> valueList = new ArrayList<>(values);
+                               if (valueList.size() > 1) {
+                                       r.headers.put(name, valueList);
+                               } else {
+                                       r.headers.put(name, valueList.get(0));
+                               }
+                       }
+
+                       r.body = writer.toString();
+
+                       return r;
+               }
+
+               public void writeBody() throws IOException {
+                       String body = writer.toString();
+                       setContentLength(body.length());
+                       super.getWriter().write(body);
+               }
+       }
+
+       private static void mapstr(StringBuilder ss, Map<String, Object> m) {
+               if (m != null) {
+                       for (Entry<String, Object> entry : m.entrySet()) {
+                               ss.append(entry.getKey()).append(": ").append(entry.getValue()).append(";");
+                       }
+               }
+       }
+}
\ No newline at end of file