summaryrefslogtreecommitdiffstats
path: root/reference/logging-filter
diff options
context:
space:
mode:
authorBrittany Plummer (bp896r) <bp896r@att.com>2019-08-27 15:36:44 -0400
committerKevin Smokowski <kevin.smokowski@att.com>2019-08-29 20:37:00 +0000
commit5104a66d12a2ada0819d1cbcaf935785748f2b87 (patch)
tree1a48cbc173ff46060bbcf679f83a75a23d194df9 /reference/logging-filter
parented4107f4ff0aa1ad65a96371bf69242847daedaa (diff)
Add JAX-RS and Spring filters for setting up MDC
Issue-ID: LOG-1113 Change-Id: I7167943384e3983c7eced1c969ed51fcd8130c88 Signed-off-by: Brittany Plummer (bp896r) <bp896r@att.com>
Diffstat (limited to 'reference/logging-filter')
-rw-r--r--reference/logging-filter/README.md18
-rw-r--r--reference/logging-filter/logging-filter-base/pom.xml62
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AbstractAuditLogFilter.java83
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogContainerFilter.java75
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogServletFilter.java86
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/Constants.java45
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java212
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MetricLogClientFilter.java128
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponents.java80
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponentsList.java25
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingClientFilter.java164
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingServletFilter.java349
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PropertyUtil.java43
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleHashMap.java37
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMap.java37
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleMap.java25
-rw-r--r--reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleServletHeadersMap.java37
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogContainerFilterTest.java86
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogServletFilterTest.java88
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/LoggingContainerFilterTest.java41
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java306
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MetricLogClientFilterTest.java127
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PayloadLoggingClientFilterTest.java76
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PropertyUtilTest.java50
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMapTest.java42
-rw-r--r--reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleServletHeadersMapTest.java52
-rw-r--r--reference/logging-filter/logging-filter-spring/pom.xml71
-rw-r--r--reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/LoggingInterceptor.java96
-rw-r--r--reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/MDCTaskDecorator.java43
-rw-r--r--reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/SpringClientFilter.java157
-rw-r--r--reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/LoggingInterceptorTest.java65
-rw-r--r--reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/SpringClientFilterTest.java166
-rw-r--r--reference/logging-filter/pom.xml241
33 files changed, 3213 insertions, 0 deletions
diff --git a/reference/logging-filter/README.md b/reference/logging-filter/README.md
new file mode 100644
index 0000000..c861a54
--- /dev/null
+++ b/reference/logging-filter/README.md
@@ -0,0 +1,18 @@
+# Logging-Filter
+
+The base project is meant to have very minimal dependencies for maximum re-use. The spring artifact is provided for any clients already using spring.
+
+## Current Layout
+- logging-filter (houses the parent pom)
+ - **base** this artifact should only depend on javax.servlet-api, javax.ws.rs-api, slf4j-api and org.onap.logging-analytics:logging-slf4j
+ - **spring** this artifact depends on base as well as spring.
+
+## Design Principles
+- minimize dependencies for maximum re-use
+- code to APIs jaxrs vs jersey, slf4j vs logback, etc...
+- no application specific code in this library
+- write extensible code so applications can add on application specific code
+- target Casablanca logging spec
+
+## Code Formatting
+ONAP code formatting standards are validated on builds. If you find a build failing due to a formatting issue, format your code by running `mvn process-sources -P format` \ No newline at end of file
diff --git a/reference/logging-filter/logging-filter-base/pom.xml b/reference/logging-filter/logging-filter-base/pom.xml
new file mode 100644
index 0000000..297d54d
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-filter-parent</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>logging-filter-base</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>javax.annotation-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-slf4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-client</artifactId>
+ <version>2.25.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.10.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AbstractAuditLogFilter.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AbstractAuditLogFilter.java
new file mode 100644
index 0000000..71d4e31
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AbstractAuditLogFilter.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import javax.servlet.http.HttpServletRequest;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+public abstract class AbstractAuditLogFilter<GenericRequest, GenericResponse> {
+ protected static final Logger logger = LoggerFactory.getLogger(AbstractAuditLogFilter.class);
+
+ protected void pre(MDCSetup mdcSetup, SimpleMap headers, GenericRequest request,
+ HttpServletRequest httpServletRequest) {
+ try {
+ String requestId = mdcSetup.getRequestId(headers);
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
+ mdcSetup.setInvocationId(headers);
+ setServiceName(request);
+ mdcSetup.setMDCPartnerName(headers);
+ mdcSetup.setServerFQDN();
+ mdcSetup.setClientIPAddress(httpServletRequest);
+ mdcSetup.setInstanceID();
+ mdcSetup.setEntryTimeStamp();
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, ONAPLogConstants.ResponseStatus.INPROGRESS.toString());
+ additionalPreHandling(request);
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTime();
+ logger.info(ONAPLogConstants.Markers.ENTRY, "Entering");
+ } catch (Exception e) {
+ logger.warn("Error in AbstractInboundFilter pre", e);
+ }
+ }
+
+ protected void post(MDCSetup mdcSetup, GenericResponse response) {
+ try {
+ int responseCode = getResponseCode(response);
+ mdcSetup.setResponseStatusCode(responseCode);
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, String.valueOf(responseCode));
+ mdcSetup.setResponseDescription(responseCode);
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTime();
+ logger.info(ONAPLogConstants.Markers.EXIT, "Exiting.");
+ additionalPostHandling(response);
+ } catch (Exception e) {
+ logger.warn("Error in AbstractInboundFilter post", e);
+ } finally {
+ MDC.clear();
+ }
+ }
+
+ protected abstract int getResponseCode(GenericResponse response);
+
+ protected abstract void setServiceName(GenericRequest request);
+
+ protected void additionalPreHandling(GenericRequest request) {
+ // override to add additional pre handling
+ }
+
+ protected void additionalPostHandling(GenericResponse response) {
+ // override to add additional post handling
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogContainerFilter.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogContainerFilter.java
new file mode 100644
index 0000000..3d04b62
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogContainerFilter.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.io.IOException;
+import javax.annotation.Priority;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Provider;
+import javax.ws.rs.ext.Providers;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+@Priority(1)
+@Provider
+public class AuditLogContainerFilter extends AbstractAuditLogFilter<ContainerRequestContext, ContainerResponseContext>
+ implements ContainerRequestFilter, ContainerResponseFilter {
+
+ protected static Logger logger = LoggerFactory.getLogger(AuditLogContainerFilter.class);
+
+ @Context
+ private HttpServletRequest httpServletRequest;
+
+ @Context
+ private Providers providers;
+
+ private MDCSetup mdcSetup = new MDCSetup();
+
+ @Override
+ public void filter(ContainerRequestContext containerRequest) {
+ SimpleMap headers = new SimpleJaxrsHeadersMap(containerRequest.getHeaders());
+ pre(mdcSetup, headers, containerRequest, httpServletRequest);
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
+ throws IOException {
+ post(mdcSetup, responseContext);
+ }
+
+ @Override
+ protected void setServiceName(ContainerRequestContext containerRequest) {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, containerRequest.getUriInfo().getPath());
+ }
+
+ @Override
+ protected int getResponseCode(ContainerResponseContext response) {
+ return response.getStatus();
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogServletFilter.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogServletFilter.java
new file mode 100644
index 0000000..ac7529f
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/AuditLogServletFilter.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+public class AuditLogServletFilter extends AbstractAuditLogFilter<HttpServletRequest, HttpServletResponse>
+ implements Filter {
+
+ @Override
+ public void destroy() {
+ // this method does nothing
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
+ throws IOException, ServletException {
+ MDCSetup mdcSetup = new MDCSetup();
+ try {
+ if (request != null && request instanceof HttpServletRequest) {
+ pre((HttpServletRequest) request, mdcSetup);
+ }
+ filterChain.doFilter(request, response);
+ } finally {
+ if (request != null && request instanceof HttpServletRequest) {
+ post((HttpServletRequest) request, (HttpServletResponse) response, mdcSetup);
+ }
+ MDC.clear();
+ }
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ // this method does nothing
+ }
+
+ protected void pre(HttpServletRequest request, MDCSetup mdcSetup) {
+ SimpleMap headers = new SimpleServletHeadersMap(request);
+ pre(mdcSetup, headers, request, request);
+ }
+
+ @Override
+ protected void setServiceName(HttpServletRequest request) {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, request.getRequestURI());
+ }
+
+ private void post(HttpServletRequest request, HttpServletResponse response, MDCSetup mdcSetup) {
+ post(mdcSetup, response);
+ }
+
+ @Override
+ protected int getResponseCode(HttpServletResponse response) {
+ return response.getStatus();
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/Constants.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/Constants.java
new file mode 100644
index 0000000..1549be1
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/Constants.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+public class Constants {
+
+ public static final class DefaultValues {
+ public static final String UNKNOWN = "UNKNOWN";
+ public static final String UNKNOWN_TARGET_ENTITY = "Unknown-Target-Entity";
+ }
+
+ public static final class HttpHeaders {
+ public static final String HEADER_FROM_APP_ID = "X-FromAppId";
+ public static final String ONAP_PARTNER_NAME = "X-ONAP-PartnerName";
+ public static final String HEADER_REQUEST_ID = "X-RequestID";
+ public static final String TRANSACTION_ID = "X-TransactionID";
+ public static final String ECOMP_REQUEST_ID = "X-ECOMP-RequestID";
+ public static final String ONAP_REQUEST_ID = "X-ONAP-RequestID";
+ public static final String CLIENT_ID = "X-ClientID";
+ public static final String INVOCATION_ID_HEADER = "X-InvocationID";
+ public static final String TARGET_ENTITY_HEADER = "X-Target-Entity";
+ }
+
+ public static final class Property {
+ public static final String PARTNER_NAME = "partnerName";
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java
new file mode 100644
index 0000000..16fa210
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java
@@ -0,0 +1,212 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.UUID;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+public class MDCSetup {
+
+ protected static Logger logger = LoggerFactory.getLogger(MDCSetup.class);
+
+ private static final String INSTANCE_UUID = UUID.randomUUID().toString();
+
+ public void setInstanceID() {
+ MDC.put(ONAPLogConstants.MDCs.INSTANCE_UUID, INSTANCE_UUID);
+ }
+
+ public void setServerFQDN() {
+ String serverFQDN = "";
+ InetAddress addr = null;
+ try {
+ addr = InetAddress.getLocalHost();
+ serverFQDN = addr.getCanonicalHostName();
+ MDC.put(ONAPLogConstants.MDCs.SERVER_IP_ADDRESS, addr.getHostAddress());
+ } catch (UnknownHostException e) {
+ logger.warn("Cannot Resolve Host Name");
+ serverFQDN = "";
+ }
+ MDC.put(ONAPLogConstants.MDCs.SERVER_FQDN, serverFQDN);
+ }
+
+ public void setClientIPAddress(HttpServletRequest httpServletRequest) {
+ String clientIpAddress = "";
+ if (httpServletRequest != null) {
+ // This logic is to avoid setting the client ip address to that of the load
+ // balancer in front of the application
+ String getForwadedFor = httpServletRequest.getHeader("X-Forwarded-For");
+ if (getForwadedFor != null) {
+ clientIpAddress = getForwadedFor;
+ } else {
+ clientIpAddress = httpServletRequest.getRemoteAddr();
+ }
+ }
+ MDC.put(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS, clientIpAddress);
+ }
+
+ public void setEntryTimeStamp() {
+ MDC.put(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP,
+ ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT));
+ }
+
+ public void setServiceName(HttpServletRequest request) {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, request.getRequestURI());
+ }
+
+ public String getRequestId(SimpleMap headers) {
+ logger.trace("Checking X-ONAP-RequestID header for requestId.");
+ String requestId = headers.get(ONAPLogConstants.Headers.REQUEST_ID);
+ if (requestId != null && !requestId.isEmpty()) {
+ return requestId;
+ }
+
+ logger.trace("No valid X-ONAP-RequestID header value. Checking X-RequestID header for requestId.");
+ requestId = headers.get(Constants.HttpHeaders.HEADER_REQUEST_ID);
+ if (requestId != null && !requestId.isEmpty()) {
+ return requestId;
+ }
+
+ logger.trace("No valid X-RequestID header value. Checking X-TransactionID header for requestId.");
+ requestId = headers.get(Constants.HttpHeaders.TRANSACTION_ID);
+ if (requestId != null && !requestId.isEmpty()) {
+ return requestId;
+ }
+
+ logger.trace("No valid X-TransactionID header value. Checking X-ECOMP-RequestID header for requestId.");
+ requestId = headers.get(Constants.HttpHeaders.ECOMP_REQUEST_ID);
+ if (requestId != null && !requestId.isEmpty()) {
+ return requestId;
+ }
+
+ logger.trace("No valid requestId headers. Generating requestId: {}", requestId);
+ return UUID.randomUUID().toString();
+ }
+
+ public void setInvocationId(SimpleMap headers) {
+ String invocationId = headers.get(ONAPLogConstants.Headers.INVOCATION_ID);
+ if (invocationId == null || invocationId.isEmpty())
+ invocationId = UUID.randomUUID().toString();
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, invocationId);
+ }
+
+ public void setInvocationIdFromMDC() {
+ String invocationId = MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID);
+ if (invocationId == null || invocationId.isEmpty())
+ invocationId = UUID.randomUUID().toString();
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, invocationId);
+ }
+
+ public void setMDCPartnerName(SimpleMap headers) {
+ logger.trace("Checking X-ONAP-PartnerName header for partnerName.");
+ String partnerName = headers.get(ONAPLogConstants.Headers.PARTNER_NAME);
+ if (partnerName == null || partnerName.isEmpty()) {
+ logger.trace("No valid X-ONAP-PartnerName header value. Checking User-Agent header for partnerName.");
+ partnerName = headers.get(HttpHeaders.USER_AGENT);
+ if (partnerName == null || partnerName.isEmpty()) {
+ logger.trace("No valid User-Agent header value. Checking X-ClientID header for partnerName.");
+ partnerName = headers.get(Constants.HttpHeaders.CLIENT_ID);
+ if (partnerName == null || partnerName.isEmpty()) {
+ logger.trace("No valid partnerName headers. Defaulting partnerName to UNKNOWN.");
+ partnerName = Constants.DefaultValues.UNKNOWN;
+ }
+ }
+ }
+ MDC.put(ONAPLogConstants.MDCs.PARTNER_NAME, partnerName);
+ }
+
+ public void setLogTimestamp() {
+ MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP,
+ ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT));
+ }
+
+ public void setElapsedTime() {
+ DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
+ ZonedDateTime entryTimestamp =
+ ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP), timeFormatter);
+ ZonedDateTime endTimestamp = ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter);
+
+ MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME,
+ Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp)));
+ }
+
+ public void setElapsedTimeInvokeTimestamp() {
+ DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
+ ZonedDateTime entryTimestamp =
+ ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP), timeFormatter);
+ ZonedDateTime endTimestamp = ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter);
+
+ MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME,
+ Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp)));
+ }
+
+ public void setResponseStatusCode(int code) {
+ String statusCode;
+ if (Response.Status.Family.familyOf(code).equals(Response.Status.Family.SUCCESSFUL)) {
+ statusCode = ONAPLogConstants.ResponseStatus.COMPLETE.toString();
+ } else {
+ statusCode = ONAPLogConstants.ResponseStatus.ERROR.toString();
+ setErrorCode(code);
+ setErrorDesc(code);
+ }
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, statusCode);
+ }
+
+ public void setTargetEntity(ONAPComponentsList targetEntity) {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, targetEntity.toString());
+ }
+
+ public void clearClientMDCs() {
+ MDC.remove(ONAPLogConstants.MDCs.INVOCATION_ID);
+ MDC.remove(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION);
+ MDC.remove(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE);
+ MDC.remove(ONAPLogConstants.MDCs.RESPONSE_CODE);
+ MDC.remove(ONAPLogConstants.MDCs.TARGET_ENTITY);
+ MDC.remove(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME);
+ MDC.remove(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP);
+ MDC.remove(ONAPLogConstants.MDCs.ERROR_CODE);
+ MDC.remove(ONAPLogConstants.MDCs.ERROR_DESC);
+ }
+
+ public void setResponseDescription(int statusCode) {
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, Response.Status.fromStatusCode(statusCode).toString());
+ }
+
+ public void setErrorCode(int statusCode) {
+ MDC.put(ONAPLogConstants.MDCs.ERROR_CODE, String.valueOf(statusCode));
+ }
+
+ public void setErrorDesc(int statusCode) {
+ MDC.put(ONAPLogConstants.MDCs.ERROR_DESC, Response.Status.fromStatusCode(statusCode).toString());
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MetricLogClientFilter.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MetricLogClientFilter.java
new file mode 100644
index 0000000..8533456
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MetricLogClientFilter.java
@@ -0,0 +1,128 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+import javax.annotation.Priority;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Providers;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+@Priority(0)
+public class MetricLogClientFilter implements ClientRequestFilter, ClientResponseFilter {
+
+ @Context
+ private Providers providers;
+ private MDCSetup mdcSetup = new MDCSetup();
+ private static final String TRACE = "trace-#";
+ private static Logger logger = LoggerFactory.getLogger(MetricLogClientFilter.class);
+ private final String partnerName;
+ private static final Marker INVOKE_RETURN = MarkerFactory.getMarker("INVOKE-RETURN");
+
+ public MetricLogClientFilter() {
+ partnerName = getPartnerName();
+ }
+
+ @Override
+ public void filter(ClientRequestContext clientRequest) {
+ try {
+ setupMDC(clientRequest);
+ setupHeaders(clientRequest);
+ logger.info(ONAPLogConstants.Markers.INVOKE, "Invoke");
+ } catch (Exception e) {
+ logger.warn("Error in JAX-RS client request filter", e);
+ }
+ }
+
+ protected void setupHeaders(ClientRequestContext clientRequest) {
+ MultivaluedMap<String, Object> headers = clientRequest.getHeaders();
+ String requestId = extractRequestID(clientRequest);
+ headers.add(ONAPLogConstants.Headers.REQUEST_ID, requestId);
+ headers.add(Constants.HttpHeaders.HEADER_REQUEST_ID, requestId);
+ headers.add(Constants.HttpHeaders.TRANSACTION_ID, requestId);
+ headers.add(Constants.HttpHeaders.ECOMP_REQUEST_ID, requestId);
+ headers.add(ONAPLogConstants.Headers.INVOCATION_ID, MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ headers.add(ONAPLogConstants.Headers.PARTNER_NAME, partnerName);
+ }
+
+ protected void setupMDC(ClientRequestContext clientRequest) {
+ MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP,
+ ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT));
+ MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, clientRequest.getUri().toString());
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, ONAPLogConstants.ResponseStatus.INPROGRESS.toString());
+ mdcSetup.setInvocationIdFromMDC();
+ String targetEntity = MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY);
+ if (targetEntity != null) {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, targetEntity);
+ } else {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, Constants.DefaultValues.UNKNOWN_TARGET_ENTITY);
+ }
+ if (MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME) == null) {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, clientRequest.getUri().getPath());
+ }
+ mdcSetup.setServerFQDN();
+ }
+
+ protected String extractRequestID(ClientRequestContext clientRequest) {
+ String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
+ if (requestId == null || requestId.isEmpty() || requestId.equals(TRACE)) {
+ requestId = UUID.randomUUID().toString();
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTimeInvokeTimestamp();
+ logger.warn("Could not Find Request ID Generating New One: {}", clientRequest.getUri().getPath());
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
+ }
+ return requestId;
+ }
+
+ @Override
+ public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) {
+ try {
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTimeInvokeTimestamp();
+ mdcSetup.setResponseStatusCode(responseContext.getStatus());
+ mdcSetup.setResponseDescription(responseContext.getStatus());
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, String.valueOf(responseContext.getStatus()));
+ logger.info(INVOKE_RETURN, "InvokeReturn");
+ mdcSetup.clearClientMDCs();
+ } catch (Exception e) {
+ logger.warn("Error in JAX-RS request,response client filter", e);
+ }
+ }
+
+ protected String getPartnerName() {
+ PropertyUtil p = new PropertyUtil();
+ return p.getProperty(Constants.Property.PARTNER_NAME);
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponents.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponents.java
new file mode 100644
index 0000000..1b9c1cd
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponents.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+public enum ONAPComponents implements ONAPComponentsList {
+ OPENSTACK_ADAPTER,
+ BPMN,
+ GRM,
+ AAI,
+ DMAAP,
+ POLICY,
+ CATALOG_DB,
+ REQUEST_DB,
+ SNIRO,
+ SDC,
+ EXTERNAL,
+ VNF_ADAPTER,
+ SDNC_ADAPTER,
+ MULTICLOUD,
+ CLAMP,
+ PORTAL,
+ VID,
+ APPC,
+ DCAE,
+ HOLMES,
+ SDNC,
+ SO,
+ VFC,
+ ESR,
+ DBC,
+ DR,
+ MR,
+ OPTF;
+
+
+ public static Set<ONAPComponents> getSOInternalComponents() {
+ return EnumSet.of(OPENSTACK_ADAPTER, BPMN, CATALOG_DB, REQUEST_DB, VNF_ADAPTER, SDNC_ADAPTER);
+ }
+
+ public static Set<ONAPComponents> getDMAAPInternalComponents() {
+ return EnumSet.of(DBC, DR, MR);
+ }
+
+ public static Set<ONAPComponents> getAAIInternalComponents() {
+ return EnumSet.of(ESR);
+ }
+
+ @Override
+ public String toString() {
+ if (getSOInternalComponents().contains(this))
+ return SO + "." + this.name();
+ else if (getDMAAPInternalComponents().contains(this))
+ return DMAAP + "." + this.name();
+ else if (getAAIInternalComponents().contains(this))
+ return AAI + "." + this.name();
+ else
+ return this.name();
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponentsList.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponentsList.java
new file mode 100644
index 0000000..f117ab7
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/ONAPComponentsList.java
@@ -0,0 +1,25 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+public interface ONAPComponentsList {
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingClientFilter.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingClientFilter.java
new file mode 100644
index 0000000..045a729
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingClientFilter.java
@@ -0,0 +1,164 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.WriterInterceptor;
+import javax.ws.rs.ext.WriterInterceptorContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PayloadLoggingClientFilter implements ClientRequestFilter, ClientResponseFilter, WriterInterceptor {
+
+ private static final Logger logger = LoggerFactory.getLogger(PayloadLoggingClientFilter.class);
+ private static final String ENTITY_STREAM_PROPERTY = "LoggingFilter.entityStream";
+ private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+ private final int maxEntitySize;
+
+ public PayloadLoggingClientFilter() {
+ maxEntitySize = 1024 * 1024;
+ }
+
+ public PayloadLoggingClientFilter(int maxPayloadSize) {
+ this.maxEntitySize = Integer.min(maxPayloadSize, 1024 * 1024);
+ }
+
+ private void log(StringBuilder sb) {
+ logger.debug(sb.toString());
+ }
+
+ protected InputStream logInboundEntity(final StringBuilder b, InputStream stream, final Charset charset)
+ throws IOException {
+ if (!stream.markSupported()) {
+ stream = new BufferedInputStream(stream);
+ }
+ stream.mark(maxEntitySize + 1);
+ final byte[] entity = new byte[maxEntitySize + 1];
+ final int entitySize = stream.read(entity);
+ if (entitySize != -1) {
+ b.append(new String(entity, 0, Math.min(entitySize, maxEntitySize), charset));
+ }
+ if (entitySize > maxEntitySize) {
+ b.append("...more...");
+ }
+ b.append('\n');
+ stream.reset();
+ return stream;
+ }
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ if (requestContext.hasEntity()) {
+ final OutputStream stream = new LoggingStream(requestContext.getEntityStream());
+ requestContext.setEntityStream(stream);
+ requestContext.setProperty(ENTITY_STREAM_PROPERTY, stream);
+ }
+ String method = formatMethod(requestContext);
+ log(new StringBuilder("Making " + method + " request to: " + requestContext.getUri() + "\nRequest Headers: "
+ + getHeaders(requestContext.getHeaders())));
+
+ }
+
+ protected String getHeaders(MultivaluedMap<String, Object> headers) {
+ MultivaluedMap<String, Object> printHeaders = new MultivaluedHashMap<>();
+ for (String header : headers.keySet()) {
+ if (!header.equals(HttpHeaders.AUTHORIZATION)) {
+ printHeaders.add(header, headers.getFirst(header));
+ }
+ }
+ return printHeaders.toString();
+ }
+
+ @Override
+ public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+ final StringBuilder sb = new StringBuilder();
+ if (responseContext.hasEntity()) {
+ responseContext.setEntityStream(logInboundEntity(sb, responseContext.getEntityStream(), DEFAULT_CHARSET));
+ String method = formatMethod(requestContext);
+ log(sb.insert(0, "Response from " + method + ": " + requestContext.getUri() + "\nResponse Headers: "
+ + responseContext.getHeaders().toString()));
+ }
+ }
+
+ @Override
+ public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
+ final LoggingStream stream = (LoggingStream) context.getProperty(ENTITY_STREAM_PROPERTY);
+ context.proceed();
+ if (stream != null) {
+ log(stream.getStringBuilder(DEFAULT_CHARSET));
+ }
+ }
+
+ private class LoggingStream extends FilterOutputStream {
+
+ private final StringBuilder sb = new StringBuilder();
+ private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ LoggingStream(OutputStream out) {
+ super(out);
+ }
+
+ StringBuilder getStringBuilder(Charset charset) {
+ // write entity to the builder
+ final byte[] entity = baos.toByteArray();
+
+ sb.append(new String(entity, 0, entity.length, charset));
+ if (entity.length > maxEntitySize) {
+ sb.append("...more...");
+ }
+ sb.append('\n');
+
+ return sb;
+ }
+
+ @Override
+ public void write(final int i) throws IOException {
+ if (baos.size() <= maxEntitySize) {
+ baos.write(i);
+ }
+ out.write(i);
+ }
+ }
+
+ protected String formatMethod(ClientRequestContext requestContext) {
+ String httpMethodOverride = requestContext.getHeaderString("X-HTTP-Method-Override");
+ if (httpMethodOverride == null) {
+ return requestContext.getMethod();
+ } else {
+ return requestContext.getMethod() + " (overridden to " + httpMethodOverride + ")";
+ }
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingServletFilter.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingServletFilter.java
new file mode 100644
index 0000000..3e85b9d
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PayloadLoggingServletFilter.java
@@ -0,0 +1,349 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.zip.GZIPInputStream;
+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 javax.ws.rs.core.HttpHeaders;
+
+public class PayloadLoggingServletFilter implements Filter {
+
+ private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PayloadLoggingServletFilter.class);
+ private static final String REDACTED = "***REDACTED***";
+
+ private static class ByteArrayServletStream extends ServletOutputStream {
+ ByteArrayOutputStream baos;
+
+ ByteArrayServletStream(ByteArrayOutputStream baos) {
+ this.baos = baos;
+ }
+
+ @Override
+ public void write(int param) throws IOException {
+ baos.write(param);
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setWriteListener(WriteListener arg0) {
+ // this method does nothing
+ }
+ }
+
+ private static class ByteArrayPrintWriter extends PrintWriter {
+ private ByteArrayOutputStream baos;
+ private int errorCode = -1;
+ private String errorMsg = "";
+ private boolean errored = false;
+
+ public ByteArrayPrintWriter(ByteArrayOutputStream out) {
+ super(out);
+ this.baos = out;
+ }
+
+ public ServletOutputStream getStream() {
+ return new ByteArrayServletStream(baos);
+ }
+
+ public Boolean hasErrored() {
+ return errored;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public String getErrorMsg() {
+ return errorMsg;
+ }
+
+ public void setError(int code) {
+ errorCode = code;
+ errored = true;
+ }
+
+ public void setError(int code, String msg) {
+ errorMsg = msg;
+ errorCode = code;
+ errored = true;
+ }
+
+ }
+
+ private class BufferedServletInputStream extends ServletInputStream {
+ ByteArrayInputStream bais;
+
+ public BufferedServletInputStream(ByteArrayInputStream bais) {
+ this.bais = bais;
+ }
+
+ @Override
+ public int available() {
+ return bais.available();
+ }
+
+ @Override
+ public int read() {
+ return bais.read();
+ }
+
+ @Override
+ public int read(byte[] buf, int off, int len) {
+ return bais.read(buf, off, len);
+ }
+
+ @Override
+ public boolean isFinished() {
+ return available() < 1;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(ReadListener arg0) {
+ // this method does nothing
+ }
+
+ }
+
+ private class BufferedRequestWrapper extends HttpServletRequestWrapper {
+ ByteArrayInputStream bais;
+ ByteArrayOutputStream baos;
+ BufferedServletInputStream bsis;
+ byte[] buffer;
+
+ public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
+ super(req);
+
+ InputStream is = req.getInputStream();
+ baos = new ByteArrayOutputStream();
+ byte[] buf = new byte[1024];
+ int letti;
+ while ((letti = is.read(buf)) > 0) {
+ baos.write(buf, 0, letti);
+ }
+ buffer = baos.toByteArray();
+ }
+
+ @Override
+ public ServletInputStream getInputStream() {
+ try {
+ bais = new ByteArrayInputStream(buffer);
+ bsis = new BufferedServletInputStream(bais);
+ } catch (Exception ex) {
+ log.error("Exception in getInputStream", ex);
+ }
+ return bsis;
+ }
+
+ public byte[] getBuffer() {
+ return buffer;
+ }
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ // this method does nothing
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
+ BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpRequest);
+
+ StringBuilder requestHeaders = new StringBuilder("REQUEST|");
+ requestHeaders.append(httpRequest.getMethod());
+ requestHeaders.append(":");
+ requestHeaders.append(httpRequest.getRequestURL().toString());
+ requestHeaders.append("|");
+ String header;
+ for (Enumeration<String> e = httpRequest.getHeaderNames(); e.hasMoreElements();) {
+ header = e.nextElement();
+ requestHeaders.append(header);
+ requestHeaders.append(":");
+ if (header.equalsIgnoreCase(HttpHeaders.AUTHORIZATION)) {
+ requestHeaders.append(REDACTED);
+ } else {
+ requestHeaders.append(httpRequest.getHeader(header));
+ }
+ requestHeaders.append(";");
+ }
+ log.info(requestHeaders.toString());
+
+ log.info("REQUEST BODY|" + new String(bufferedRequest.getBuffer()));
+
+ final HttpServletResponse response = (HttpServletResponse) servletResponse;
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final ByteArrayPrintWriter pw = new ByteArrayPrintWriter(baos);
+
+ HttpServletResponse wrappedResp = new HttpServletResponseWrapper(response) {
+ @Override
+ public PrintWriter getWriter() {
+ return pw;
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() {
+ return pw.getStream();
+ }
+
+ @Override
+ public void sendError(int sc) throws IOException {
+ super.sendError(sc);
+ pw.setError(sc);
+
+ }
+
+ @Override
+ public void sendError(int sc, String msg) throws IOException {
+ super.sendError(sc, msg);
+ pw.setError(sc, msg);
+ }
+ };
+
+ try {
+ filterChain.doFilter(bufferedRequest, wrappedResp);
+ } catch (Exception e) {
+ log.error("Chain Exception", e);
+ throw e;
+ } finally {
+ try {
+ byte[] bytes = baos.toByteArray();
+ StringBuilder responseHeaders = new StringBuilder("RESPONSE HEADERS|");
+
+ for (String headerName : response.getHeaderNames()) {
+ responseHeaders.append(headerName);
+ responseHeaders.append(":");
+ responseHeaders.append(response.getHeader(headerName));
+ responseHeaders.append(";");
+ }
+ responseHeaders.append("Status:");
+ responseHeaders.append(response.getStatus());
+ responseHeaders.append(";IsCommited:" + wrappedResp.isCommitted());
+
+ log.info(responseHeaders.toString());
+
+ if ("gzip".equals(response.getHeader("Content-Encoding"))) {
+ log.info("UNGZIPED RESPONSE BODY|" + decompressGZIPByteArray(bytes));
+ } else {
+ log.info("RESPONSE BODY|" + new String(bytes));
+ }
+
+ if (pw.hasErrored()) {
+ log.info("ERROR RESPONSE|" + pw.getErrorCode() + ":" + pw.getErrorMsg());
+ } else {
+ if (!wrappedResp.isCommitted()) {
+ response.getOutputStream().write(bytes);
+ response.getOutputStream().flush();
+ }
+ }
+ } catch (Exception e) {
+ log.error("Exception in response filter", e);
+ }
+ }
+ }
+
+ @Override
+ public void destroy() {
+ // this method does nothing
+ }
+
+ private String decompressGZIPByteArray(byte[] bytes) {
+ BufferedReader in = null;
+ InputStreamReader inR = null;
+ ByteArrayInputStream byteS = null;
+ GZIPInputStream gzS = null;
+ StringBuilder str = new StringBuilder();
+ try {
+ byteS = new ByteArrayInputStream(bytes);
+ gzS = new GZIPInputStream(byteS);
+ inR = new InputStreamReader(gzS);
+ in = new BufferedReader(inR);
+
+ if (in != null) {
+ String content;
+ while ((content = in.readLine()) != null) {
+ str.append(content);
+ }
+ }
+
+ } catch (Exception e) {
+ log.error("Failed get read GZIPInputStream", e);
+ } finally {
+ if (byteS != null)
+ try {
+ byteS.close();
+ } catch (IOException e1) {
+ log.error("Failed to close ByteStream", e1);
+ }
+ if (gzS != null)
+ try {
+ gzS.close();
+ } catch (IOException e2) {
+ log.error("Failed to close GZStream", e2);
+ }
+ if (inR != null)
+ try {
+ inR.close();
+ } catch (IOException e3) {
+ log.error("Failed to close InputReader", e3);
+ }
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ log.error("Failed to close BufferedReader", e);
+ }
+ }
+ return str.toString();
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PropertyUtil.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PropertyUtil.java
new file mode 100644
index 0000000..5a094eb
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/PropertyUtil.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PropertyUtil {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ public String getProperty(String property) {
+ logger.info("Checking for system property [{}]", property);
+ String propertyValue = System.getProperty(property);
+ if (propertyValue == null || propertyValue.isEmpty()) {
+ logger.info("System property was null or empty. Checking environment variable for: {}", property);
+ propertyValue = System.getenv(property);
+ if (propertyValue == null || propertyValue.isEmpty()) {
+ logger.info("Environment variable: {} was null or empty. Returning value: {}", property,
+ Constants.DefaultValues.UNKNOWN);
+ propertyValue = Constants.DefaultValues.UNKNOWN;
+ }
+ }
+ return propertyValue;
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleHashMap.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleHashMap.java
new file mode 100644
index 0000000..1e9cedb
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleHashMap.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import java.util.HashMap;
+
+public class SimpleHashMap implements SimpleMap {
+ private HashMap<String, String> map;
+
+ public SimpleHashMap(HashMap<String, String> map) {
+ this.map = map;
+ }
+
+ @Override
+ public String get(String key) {
+ return map.get(key);
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMap.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMap.java
new file mode 100644
index 0000000..5007478
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMap.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+public class SimpleJaxrsHeadersMap implements SimpleMap {
+ MultivaluedMap<String, String> map;
+
+ public SimpleJaxrsHeadersMap(MultivaluedMap<String, String> map) {
+ this.map = map;
+ }
+
+ @Override
+ public String get(String key) {
+ return map.getFirst(key);
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleMap.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleMap.java
new file mode 100644
index 0000000..9543721
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleMap.java
@@ -0,0 +1,25 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+public interface SimpleMap {
+ String get(String key);
+}
diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleServletHeadersMap.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleServletHeadersMap.java
new file mode 100644
index 0000000..e6a91fb
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/SimpleServletHeadersMap.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class SimpleServletHeadersMap implements SimpleMap {
+ private HttpServletRequest request;
+
+ public SimpleServletHeadersMap(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public String get(String key) {
+ return request.getHeader(key);
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogContainerFilterTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogContainerFilterTest.java
new file mode 100644
index 0000000..af80b19
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogContainerFilterTest.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.core.UriInfo;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.AuditLogContainerFilter;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuditLogContainerFilterTest {
+
+ @Mock
+ private ContainerRequestContext containerRequest;
+
+ @Mock
+ private ContainerResponseContext containerResponse;
+
+ @Mock
+ private MDCSetup mdcSetup;
+
+ @Mock
+ private UriInfo uriInfo;
+
+ @Spy
+ @InjectMocks
+ private AuditLogContainerFilter auditLogContainerFilter;
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ @Test
+ public void filterTest() {
+ when(mdcSetup.getRequestId(any(SimpleMap.class))).thenReturn("e3b08fa3-535f-4c1b-8228-91318d2bb4ee");
+ when(uriInfo.getPath()).thenReturn("onap/so/serviceInstances");
+ doReturn(uriInfo).when(containerRequest).getUriInfo();
+ auditLogContainerFilter.filter(containerRequest);
+
+ assertEquals("e3b08fa3-535f-4c1b-8228-91318d2bb4ee", MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+ assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME));
+ assertEquals("INPROGRESS", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ }
+
+ @Test
+ public void getResponseCodeTest() {
+ when(containerResponse.getStatus()).thenReturn(200);
+ int responseCode = auditLogContainerFilter.getResponseCode(containerResponse);
+
+ assertEquals(200, responseCode);
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogServletFilterTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogServletFilterTest.java
new file mode 100644
index 0000000..1a0d0ef
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/AuditLogServletFilterTest.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.AuditLogServletFilter;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuditLogServletFilterTest {
+
+ @Mock
+ private ServletRequest request;
+
+ @Mock
+ private ServletResponse response;
+
+ @Mock
+ private MDCSetup mdcSetup;
+
+ @Mock
+ private HttpServletRequest servletRequest;
+
+ @Mock
+ private HttpServletResponse servletResponse;
+
+ @Spy
+ @InjectMocks
+ private AuditLogServletFilter auditLogServletFilter;
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ @Test
+ public void preTest() {
+ when(mdcSetup.getRequestId(any(SimpleMap.class))).thenReturn("e3b08fa3-535f-4c1b-8228-91318d2bb4ee");
+ when(servletRequest.getRequestURI()).thenReturn("onap/so/serviceInstances");
+ auditLogServletFilter.pre(servletRequest, mdcSetup);
+
+ assertEquals("e3b08fa3-535f-4c1b-8228-91318d2bb4ee", MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+ assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME));
+ assertEquals("INPROGRESS", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ }
+
+ @Test
+ public void getResponseCodeTest() {
+ when(servletResponse.getStatus()).thenReturn(200);
+ int responseCode = auditLogServletFilter.getResponseCode(servletResponse);
+
+ assertEquals(200, responseCode);
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/LoggingContainerFilterTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/LoggingContainerFilterTest.java
new file mode 100644
index 0000000..4f8d16d
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/LoggingContainerFilterTest.java
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import org.junit.Test;
+import org.onap.logging.filter.base.SimpleJaxrsHeadersMap;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+
+public class LoggingContainerFilterTest {
+ private String invocationId = "4d31fe02-4918-4975-942f-fe51a44e6a9b";
+
+ @Test
+ public void convertMultivaluedMapToHashMap() {
+ MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
+ headers.add(ONAPLogConstants.Headers.INVOCATION_ID, invocationId);
+ SimpleMap result = new SimpleJaxrsHeadersMap(headers);
+ assertEquals(invocationId, result.get(ONAPLogConstants.Headers.INVOCATION_ID));
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java
new file mode 100644
index 0000000..1687c19
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java
@@ -0,0 +1,306 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.when;
+import java.util.HashMap;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.ONAPComponents;
+import org.onap.logging.filter.base.SimpleHashMap;
+import org.onap.logging.filter.base.SimpleJaxrsHeadersMap;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MDCSetupTest {
+
+ @Mock
+ private HttpServletRequest httpServletRequest;
+
+ @Spy
+ @InjectMocks
+ private MDCSetup mdcSetup = new MDCSetup();
+
+ private String requestId = "4d31fe02-4918-4975-942f-fe51a44e6a9b";
+ private String invocationId = "4d31fe02-4918-4975-942f-fe51a44e6a9a";
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ @Test
+ public void setElapsedTimeTest() {
+ String expected = "318";
+ MDC.put(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP, "2019-06-18T02:09:06.024Z");
+ MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, "2019-06-18T02:09:06.342Z");
+
+ mdcSetup.setElapsedTime();
+ assertEquals(expected, MDC.get(ONAPLogConstants.MDCs.ELAPSED_TIME));
+ }
+
+ @Test
+ public void setElapsedTimeInvokeTimestampTest() {
+ String expected = "318";
+ MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, "2019-06-18T02:09:06.024Z");
+ MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, "2019-06-18T02:09:06.342Z");
+
+ mdcSetup.setElapsedTimeInvokeTimestamp();
+ assertEquals(expected, MDC.get(ONAPLogConstants.MDCs.ELAPSED_TIME));
+ }
+
+ @Test
+ public void setRequestIdTest() {
+ HashMap<String, String> headers = new HashMap<>();
+ headers.put(ONAPLogConstants.Headers.REQUEST_ID, requestId);
+ String fetchedRequestId = mdcSetup.getRequestId(new SimpleHashMap(headers));
+ assertEquals(requestId, fetchedRequestId);
+ }
+
+ @Test
+ public void setRequestIdRequestIdHeaderTest() {
+ HashMap<String, String> headers = new HashMap<>();
+ headers.put(Constants.HttpHeaders.HEADER_REQUEST_ID, requestId);
+ String fetchedRequestId = mdcSetup.getRequestId(new SimpleHashMap(headers));
+ assertEquals(requestId, fetchedRequestId);
+ }
+
+ @Test
+ public void setRequestIdTransactionIdHeaderTest() {
+ HashMap<String, String> headers = new HashMap<>();
+ headers.put(Constants.HttpHeaders.TRANSACTION_ID, requestId);
+ String fetchedRequestId = mdcSetup.getRequestId(new SimpleHashMap(headers));
+ assertEquals(requestId, fetchedRequestId);
+ }
+
+ @Test
+ public void setRequestIdEcompRequestIdHeaderTest() {
+ HashMap<String, String> headers = new HashMap<>();
+ headers.put(Constants.HttpHeaders.ECOMP_REQUEST_ID, requestId);
+ String fetchedRequestId = mdcSetup.getRequestId(new SimpleHashMap(headers));
+ assertEquals(requestId, fetchedRequestId);
+ }
+
+ @Test
+ public void setRequestIdNoHeaderTest() {
+ HashMap<String, String> headers = new HashMap<>();
+ String fetchedRequestId = mdcSetup.getRequestId(new SimpleHashMap(headers));
+ assertNotNull(fetchedRequestId);
+ }
+
+ @Test
+ public void setInvocationIdTest() {
+ HashMap<String, String> headers = new HashMap<>();
+ headers.put(ONAPLogConstants.Headers.INVOCATION_ID, invocationId);
+ mdcSetup.setInvocationId(new SimpleHashMap(headers));
+ assertEquals(invocationId, MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ }
+
+ @Test
+ public void setInvocationIdNoHeaderTest() {
+ HashMap<String, String> headers = new HashMap<>();
+ mdcSetup.setInvocationId(new SimpleHashMap(headers));
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ }
+
+ @Test
+ public void setInvovationIdFromMDCTest() {
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, "7b77143c-9b50-410c-ac2f-05758a68e3e8");
+ mdcSetup.setInvocationIdFromMDC();
+ assertEquals("7b77143c-9b50-410c-ac2f-05758a68e3e8", MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ }
+
+ @Test
+ public void setInvocationIdFromMDCNoInvocationIdTest() {
+ mdcSetup.setInvocationIdFromMDC();
+ // InvocationId is set to a random UUID
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ }
+
+ @Test
+ public void setResponseStatusCodeTest() {
+ mdcSetup.setResponseStatusCode(200);
+ assertEquals("COMPLETE", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ }
+
+ @Test
+ public void setResponseStatusCodeErrorTest() {
+ mdcSetup.setResponseStatusCode(400);
+ assertEquals("ERROR", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ assertEquals("400", MDC.get(ONAPLogConstants.MDCs.ERROR_CODE));
+ assertEquals("Bad Request", MDC.get(ONAPLogConstants.MDCs.ERROR_DESC));
+ }
+
+ @Test
+ public void clearClientMDCsTest() {
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, "7b77143c-9b50-410c-ac2f-05758a68e3e9");
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, "Bad Gateway");
+ MDC.put(ONAPLogConstants.MDCs.ERROR_DESC, "Bad Gateway");
+ MDC.put(ONAPLogConstants.MDCs.ERROR_CODE, "502");
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, "502");
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, "502");
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, "SO");
+ MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, "SDNC");
+ MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, "2019-06-18T02:09:06.024Z");
+
+ mdcSetup.clearClientMDCs();
+ assertNull(MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.ERROR_CODE));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.ERROR_DESC));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.RESPONSE_CODE));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME));
+ assertNull(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP));
+ }
+
+ @Test
+ public void setTargetEntityTest() {
+ mdcSetup.setTargetEntity(ONAPComponents.SO);
+ assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY));
+ }
+
+ @Test
+ public void setResponseDescriptionTest() {
+ mdcSetup.setResponseDescription(502);
+ assertEquals("Bad Gateway", MDC.get(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION));
+ }
+
+ @Test
+ public void setMDCPartnerNameTest() {
+ MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+ headerMap.putSingle(ONAPLogConstants.Headers.PARTNER_NAME, "SO");
+ SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+ mdcSetup.setMDCPartnerName(headers);
+
+ assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+ }
+
+ @Test
+ public void setMDCPartnerNameUserAgentHeaderTest() {
+ MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+ headerMap.putSingle(HttpHeaders.USER_AGENT, "Apache-HttpClient/4.5.8 (Java/1.8.0_191)");
+ SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+ mdcSetup.setMDCPartnerName(headers);
+
+ assertEquals("Apache-HttpClient/4.5.8 (Java/1.8.0_191)", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+ }
+
+ @Test
+ public void setMDCPartnerNameClientIdHeaderTest() {
+ MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+ headerMap.putSingle(Constants.HttpHeaders.CLIENT_ID, "SO");
+ SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+ mdcSetup.setMDCPartnerName(headers);
+
+ assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+ }
+
+ @Test
+ public void setMDCPartnerNameNoHeaderTest() {
+ MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+ SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+ mdcSetup.setMDCPartnerName(headers);
+
+ assertEquals("UNKNOWN", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+ }
+
+ @Test
+ public void setServerFQDNTest() {
+ mdcSetup.setServerFQDN();
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.SERVER_IP_ADDRESS));
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.SERVER_FQDN));
+ }
+
+ @Test
+ public void setClientIPAddressTest() {
+ when(httpServletRequest.getHeader("X-Forwarded-For")).thenReturn("127.0.0.2");
+ mdcSetup.setClientIPAddress(httpServletRequest);
+
+ assertEquals("127.0.0.2", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS));
+ }
+
+ @Test
+ public void setClientIPAddressNoHeaderTest() {
+ when(httpServletRequest.getRemoteAddr()).thenReturn("127.0.0.1");
+ mdcSetup.setClientIPAddress(httpServletRequest);
+
+ assertEquals("127.0.0.1", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS));
+ }
+
+ @Test
+ public void setClientIPAddressNullTest() {
+ mdcSetup.setClientIPAddress(null);
+
+ assertEquals("", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS));
+ }
+
+ @Test
+ public void setEntryTimeStampTest() {
+ mdcSetup.setEntryTimeStamp();
+
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP));
+ }
+
+ @Test
+ public void setLogTimestampTest() {
+ mdcSetup.setLogTimestamp();
+
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP));
+ }
+
+ @Test
+ public void setInstanceIDTest() {
+ mdcSetup.setInstanceID();
+
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.INSTANCE_UUID));
+ }
+
+ @Test
+ public void setServiceNameTest() {
+ String requestUri = "onap/so/serviceInstances";
+ when(httpServletRequest.getRequestURI()).thenReturn(requestUri);
+ mdcSetup.setServiceName(httpServletRequest);
+
+ assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME));
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MetricLogClientFilterTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MetricLogClientFilterTest.java
new file mode 100644
index 0000000..9a9f883
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MetricLogClientFilterTest.java
@@ -0,0 +1,127 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.MetricLogClientFilter;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MetricLogClientFilterTest {
+
+ @Mock
+ private MDCSetup mdcSetup;
+
+ @Mock
+ private ClientRequestContext clientRequest;
+
+ @Spy
+ @InjectMocks
+ private MetricLogClientFilter metricLogClientFilter;
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ @Test
+ public void setupHeadersTest() {
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, "8819bfb4-69d2-43fc-b0d6-81d2690533ea");
+ MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
+ when(clientRequest.getHeaders()).thenReturn(headers);
+ doReturn("0a908a5d-e774-4558-96ff-6edcbba65483").when(metricLogClientFilter).extractRequestID(clientRequest);
+
+ metricLogClientFilter.setupHeaders(clientRequest);
+
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(ONAPLogConstants.Headers.REQUEST_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.HEADER_REQUEST_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.TRANSACTION_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.TRANSACTION_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.ECOMP_REQUEST_ID));
+ assertEquals("8819bfb4-69d2-43fc-b0d6-81d2690533ea", headers.getFirst(ONAPLogConstants.Headers.INVOCATION_ID));
+ assertEquals("UNKNOWN", headers.getFirst(ONAPLogConstants.Headers.PARTNER_NAME));
+ }
+
+ @Test
+ public void setupMDCTest() throws URISyntaxException {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, "SO");
+ URI uri = new URI("onap/so/serviceInstances");
+ doReturn(uri).when(clientRequest).getUri();
+
+ metricLogClientFilter.setupMDC(clientRequest);
+
+ assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME));
+ assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY));
+ assertEquals("INPROGRESS", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ assertNotNull(ONAPLogConstants.MDCs.SERVICE_NAME);
+ assertNotNull(ONAPLogConstants.MDCs.SERVER_FQDN);
+ assertNotNull(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE);
+ }
+
+ @Test
+ public void setupMDCNoTargetEntityTest() throws URISyntaxException {
+ URI uri = new URI("onap/so/serviceInstances");
+ doReturn(uri).when(clientRequest).getUri();
+
+ metricLogClientFilter.setupMDC(clientRequest);
+
+ assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME));
+ assertEquals("Unknown-Target-Entity", MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY));
+ assertEquals("INPROGRESS", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ assertNotNull(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE);
+ }
+
+ @Test
+ public void extractRequestIDTest() {
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, "0a908a5d-e774-4558-96ff-6edcbba65483");
+ String requestId = metricLogClientFilter.extractRequestID(clientRequest);
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", requestId);
+ }
+
+ @Test
+ public void extractRequestIDNullTest() throws URISyntaxException {
+ URI uri = new URI("onap/so/serviceInstances");
+ doReturn(uri).when(clientRequest).getUri();
+ String requestId = metricLogClientFilter.extractRequestID(clientRequest);
+ assertNotNull(requestId);
+ assertNotNull(ONAPLogConstants.MDCs.LOG_TIMESTAMP);
+ assertNotNull(ONAPLogConstants.MDCs.ELAPSED_TIME);
+
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PayloadLoggingClientFilterTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PayloadLoggingClientFilterTest.java
new file mode 100644
index 0000000..5156516
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PayloadLoggingClientFilterTest.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.filter.base.PayloadLoggingClientFilter;
+
+@RunWith(MockitoJUnitRunner.class)
+public class PayloadLoggingClientFilterTest {
+
+ @Mock
+ private ClientRequestContext requestContext;
+
+ @Spy
+ @InjectMocks
+ private PayloadLoggingClientFilter payloadLoggingClientFilter;
+
+ @Test
+ public void formatMethodTest() throws IOException, URISyntaxException {
+ when(requestContext.getHeaderString("X-HTTP-Method-Override")).thenReturn("filter");
+ when(requestContext.getMethod()).thenReturn("filtered");
+ String method = payloadLoggingClientFilter.formatMethod(requestContext);
+
+ assertEquals("filtered (overridden to filter)", method);
+ }
+
+ @Test
+ public void formatMethodNullHeaderTest() throws IOException, URISyntaxException {
+ when(requestContext.getMethod()).thenReturn("filtered");
+ String method = payloadLoggingClientFilter.formatMethod(requestContext);
+
+ assertEquals("filtered", method);
+ }
+
+ @Test
+ public void getHeadersTest() {
+ MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
+ headers.add(Constants.HttpHeaders.ONAP_PARTNER_NAME, "SO");
+ headers.add("Authorization", "Test");
+
+ String printHeaders = payloadLoggingClientFilter.getHeaders(headers);
+
+ assertEquals("{X-ONAP-PartnerName=[SO]}", printHeaders);
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PropertyUtilTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PropertyUtilTest.java
new file mode 100644
index 0000000..4ec14bc
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/PropertyUtilTest.java
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.After;
+import org.junit.Test;
+import org.onap.logging.filter.base.PropertyUtil;
+
+public class PropertyUtilTest {
+
+ private PropertyUtil propertyUtil = new PropertyUtil();
+
+ @After
+ public void tearDown() {
+ System.clearProperty("partnerName");
+ }
+
+ @Test
+ public void getPropertyTest() {
+ System.setProperty("partnerName", "partnerName");
+
+ String partnerName = propertyUtil.getProperty("partnerName");
+ assertEquals("partnerName", partnerName);
+ }
+
+ @Test
+ public void getPropertyNullTest() {
+ String partnerName = propertyUtil.getProperty("partner");
+ assertEquals("UNKNOWN", partnerName);
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMapTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMapTest.java
new file mode 100644
index 0000000..a1c5f9b
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleJaxrsHeadersMapTest.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import org.junit.Test;
+import org.onap.logging.filter.base.SimpleJaxrsHeadersMap;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+
+public class SimpleJaxrsHeadersMapTest {
+
+ private String invocationId = "4d31fe02-4918-4975-942f-fe51a44e6a9b";
+
+ @Test
+ public void convertMultivaluedMapToHashMap() {
+ MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
+ headers.add(ONAPLogConstants.Headers.INVOCATION_ID, invocationId);
+ SimpleMap result = new SimpleJaxrsHeadersMap(headers);
+ assertEquals(invocationId, result.get(ONAPLogConstants.Headers.INVOCATION_ID));
+ }
+}
diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleServletHeadersMapTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleServletHeadersMapTest.java
new file mode 100644
index 0000000..f1e6af8
--- /dev/null
+++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/SimpleServletHeadersMapTest.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.SimpleServletHeadersMap;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SimpleServletHeadersMapTest {
+
+ @Mock
+ private HttpServletRequest request;
+
+ @Spy
+ @InjectMocks
+ private SimpleServletHeadersMap map;
+
+ @Test
+ public void getTest() {
+ when(request.getHeader("testHeader")).thenReturn("testResult");
+ String result = map.get("testHeader");
+
+ assertEquals("testResult", result);
+ }
+
+}
diff --git a/reference/logging-filter/logging-filter-spring/pom.xml b/reference/logging-filter/logging-filter-spring/pom.xml
new file mode 100644
index 0000000..42f5fe8
--- /dev/null
+++ b/reference/logging-filter/logging-filter-spring/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-filter-parent</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>logging-filter-spring</artifactId>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>2.0.5.RELEASE</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-filter-base</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-slf4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-client</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/LoggingInterceptor.java b/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/LoggingInterceptor.java
new file mode 100644
index 0000000..d8d6bf4
--- /dev/null
+++ b/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/LoggingInterceptor.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.spring;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Providers;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.filter.base.SimpleServletHeadersMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+@Component
+public class LoggingInterceptor extends HandlerInterceptorAdapter {
+
+ private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
+
+ private MDCSetup mdcSetup = new MDCSetup();
+
+ @Context
+ private Providers providers;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+ throws Exception {
+ SimpleMap headers = new SimpleServletHeadersMap(request);
+ String requestId = mdcSetup.getRequestId(headers);
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
+ mdcSetup.setInvocationId(headers);
+ mdcSetup.setServiceName(request);
+ mdcSetup.setMDCPartnerName(headers);
+ mdcSetup.setClientIPAddress(request);
+ mdcSetup.setEntryTimeStamp();
+ mdcSetup.setInstanceID();
+ mdcSetup.setServerFQDN();
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, ONAPLogConstants.ResponseStatus.INPROGRESS.toString());
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTime();
+ logger.info(ONAPLogConstants.Markers.ENTRY, "Entering");
+ if (logger.isDebugEnabled())
+ logRequestInformation(request);
+ return true;
+ }
+
+ protected void logRequestInformation(HttpServletRequest request) {
+ Map<String, String> headers = Collections.list((request).getHeaderNames()).stream()
+ .collect(Collectors.toMap(h -> h, request::getHeader));
+
+ logger.debug("===========================request begin================================================");
+ logger.debug("URI : {}", request.getRequestURI());
+ logger.debug("Method : {}", request.getMethod());
+ logger.debug("Headers : {}", headers);
+ logger.debug("==========================request end================================================");
+
+ }
+
+ @Override
+ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+ ModelAndView modelAndView) throws Exception {
+ mdcSetup.setResponseStatusCode(response.getStatus());
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTime();
+ mdcSetup.setResponseDescription(response.getStatus());
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, String.valueOf(response.getStatus()));
+ logger.info(ONAPLogConstants.Markers.EXIT, "Exiting.");
+ MDC.clear();
+ }
+}
diff --git a/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/MDCTaskDecorator.java b/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/MDCTaskDecorator.java
new file mode 100644
index 0000000..b641b5f
--- /dev/null
+++ b/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/MDCTaskDecorator.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.spring;
+
+import java.util.Map;
+import org.slf4j.MDC;
+import org.springframework.core.task.TaskDecorator;
+
+public class MDCTaskDecorator implements TaskDecorator {
+
+ @Override
+ public Runnable decorate(Runnable runnable) {
+ Map<String, String> contextMap = MDC.getCopyOfContextMap();
+ return () -> {
+ try {
+ if (contextMap != null) {
+ MDC.setContextMap(contextMap);
+ runnable.run();
+ }
+ } finally {
+ MDC.clear();
+ }
+ };
+ }
+}
diff --git a/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/SpringClientFilter.java b/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/SpringClientFilter.java
new file mode 100644
index 0000000..6eeee1a
--- /dev/null
+++ b/reference/logging-filter/logging-filter-spring/src/main/java/org/onap/logging/filter/spring/SpringClientFilter.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.spring;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.UUID;
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.PropertyUtil;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.util.StreamUtils;
+
+public class SpringClientFilter implements ClientHttpRequestInterceptor {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private static final String TRACE = "trace-#";
+ private MDCSetup mdcSetup = new MDCSetup();
+ private final String partnerName;
+ private static final Marker INVOKE_RETURN = MarkerFactory.getMarker("INVOKE-RETURN");
+
+ public SpringClientFilter() {
+ this.partnerName = getPartnerName();
+ }
+
+ @Override
+ public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
+ throws IOException {
+ processRequest(request, body);
+ ClientHttpResponse response = execution.execute(request, body);
+ processResponse(response);
+ return response;
+ }
+
+ protected void processRequest(HttpRequest request, byte[] body) throws IOException {
+ mdcSetup.setInvocationIdFromMDC();
+ setupMDC(request);
+ setupHeaders(request);
+ if (logger.isDebugEnabled()) {
+ logger.debug("===========================request begin================================================");
+ logger.debug("URI : {}", request.getURI());
+ logger.debug("Method : {}", request.getMethod());
+ logger.debug("Headers : {}", request.getHeaders());
+ logger.debug("Request body: {}", new String(body, StandardCharsets.UTF_8));
+ logger.debug("==========================request end================================================");
+ }
+ }
+
+ protected void setupHeaders(HttpRequest clientRequest) {
+ HttpHeaders headers = clientRequest.getHeaders();
+ String requestId = extractRequestID(clientRequest);
+ headers.add(ONAPLogConstants.Headers.REQUEST_ID, requestId);
+ headers.add(Constants.HttpHeaders.HEADER_REQUEST_ID, requestId);
+ headers.add(Constants.HttpHeaders.TRANSACTION_ID, requestId);
+ headers.add(Constants.HttpHeaders.ECOMP_REQUEST_ID, requestId);
+ headers.add(ONAPLogConstants.Headers.INVOCATION_ID, MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ headers.add(ONAPLogConstants.Headers.PARTNER_NAME, partnerName);
+ }
+
+ protected String extractRequestID(HttpRequest clientRequest) {
+ String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
+ if (requestId == null || requestId.isEmpty() || requestId.equals(TRACE)) {
+ requestId = UUID.randomUUID().toString();
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTimeInvokeTimestamp();
+ logger.warn("Could not Find Request ID Generating New One: {}", clientRequest.getURI());
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
+ }
+ return requestId;
+ }
+
+ protected void setupMDC(HttpRequest clientRequest) {
+ MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP,
+ ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT));
+ MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, clientRequest.getURI().toString());
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, ONAPLogConstants.ResponseStatus.INPROGRESS.toString());
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, extractTargetEntity(clientRequest));
+ if (MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME) == null) {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, clientRequest.getURI().getPath());
+ }
+ mdcSetup.setServerFQDN();
+ }
+
+ protected String extractTargetEntity(HttpRequest clientRequest) {
+ HttpHeaders headers = clientRequest.getHeaders();
+ String headerTargetEntity = null;
+ List<String> headerTargetEntityList = headers.get(Constants.HttpHeaders.TARGET_ENTITY_HEADER);
+ if (headerTargetEntityList != null && !headerTargetEntityList.isEmpty())
+ headerTargetEntity = headerTargetEntityList.get(0);
+ String targetEntity = MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY);
+ if (targetEntity != null && !targetEntity.isEmpty()) {
+ return targetEntity;
+ } else if (headerTargetEntity != null && !headerTargetEntity.isEmpty()) {
+ targetEntity = headerTargetEntity;
+ } else {
+ targetEntity = Constants.DefaultValues.UNKNOWN_TARGET_ENTITY;
+ logger.warn("Could not Target Entity: {}", clientRequest.getURI());
+ }
+ return targetEntity;
+ }
+
+ protected void processResponse(ClientHttpResponse response) throws IOException {
+ if (logger.isDebugEnabled()) {
+ logger.debug("============================response begin==========================================");
+ logger.debug("Status code : {}", response.getStatusCode());
+ logger.debug("Status text : {}", response.getStatusText());
+ logger.debug("Headers : {}", response.getHeaders());
+ logger.debug("Response body: {}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
+ logger.debug("=======================response end=================================================");
+ }
+ mdcSetup.setLogTimestamp();
+ mdcSetup.setElapsedTimeInvokeTimestamp();
+ mdcSetup.setResponseStatusCode(response.getRawStatusCode());
+ int statusCode = response.getRawStatusCode();
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, String.valueOf(statusCode));
+ mdcSetup.setResponseDescription(statusCode);
+ logger.info(INVOKE_RETURN, "InvokeReturn");
+ mdcSetup.clearClientMDCs();
+ }
+
+ protected String getPartnerName() {
+ PropertyUtil p = new PropertyUtil();
+ return p.getProperty(Constants.Property.PARTNER_NAME);
+ }
+}
diff --git a/reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/LoggingInterceptorTest.java b/reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/LoggingInterceptorTest.java
new file mode 100644
index 0000000..1a6d701
--- /dev/null
+++ b/reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/LoggingInterceptorTest.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.spring;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LoggingInterceptorTest {
+
+ @Mock
+ private HttpServletRequest request;
+
+ @Mock
+ private HttpServletResponse response;
+
+ @Mock
+ private Object handler;
+
+ @Mock
+ private MDCSetup mdcSetup;
+
+ @Spy
+ @InjectMocks
+ private LoggingInterceptor loggingInterceptor;
+
+ @Test
+ public void preHandleTest() throws Exception {
+ when(mdcSetup.getRequestId(any(SimpleMap.class))).thenReturn("428443e6-eeb2-4e4a-9a8c-2ca9e2bc8067");
+ loggingInterceptor.preHandle(request, response, handler);
+ assertEquals(MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE), "INPROGRESS");
+ assertEquals("428443e6-eeb2-4e4a-9a8c-2ca9e2bc8067", MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+ }
+}
diff --git a/reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/SpringClientFilterTest.java b/reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/SpringClientFilterTest.java
new file mode 100644
index 0000000..9de5d68
--- /dev/null
+++ b/reference/logging-filter/logging-filter-spring/src/test/java/org/onap/logging/filter/spring/SpringClientFilterTest.java
@@ -0,0 +1,166 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.logging.filter.spring;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpResponse;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SpringClientFilterTest {
+
+ @Mock
+ private MDCSetup mdcSetup;
+
+ @Mock
+ private ClientHttpResponse response;
+
+ @Mock
+ private HttpRequest clientRequest;
+
+ @Mock
+ private ClientHttpRequestExecution execution;
+
+ @Spy
+ @InjectMocks
+ private SpringClientFilter springClientFilter;
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ @Test
+ public void processResponseTest() throws IOException {
+ String partnerName = springClientFilter.getPartnerName();
+
+ assertEquals("UNKNOWN", partnerName);
+ }
+
+ @Test
+ public void extractTargetEntityTest() {
+ HttpHeaders headers = new HttpHeaders();
+ headers.add(Constants.HttpHeaders.TARGET_ENTITY_HEADER, "SO");
+ when(clientRequest.getHeaders()).thenReturn(headers);
+
+ String targetEntity = springClientFilter.extractTargetEntity(clientRequest);
+ assertEquals("SO", targetEntity);
+ }
+
+ @Test
+ public void extractTargetEntityMDCTest() {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, "SO");
+ HttpHeaders headers = new HttpHeaders();
+ when(clientRequest.getHeaders()).thenReturn(headers);
+
+ String targetEntity = springClientFilter.extractTargetEntity(clientRequest);
+ assertEquals("SO", targetEntity);
+ }
+
+ @Test
+ public void extractTargetEntityNoHeaderTest() {
+ HttpHeaders headers = new HttpHeaders();
+ when(clientRequest.getHeaders()).thenReturn(headers);
+
+ String targetEntity = springClientFilter.extractTargetEntity(clientRequest);
+ assertEquals("Unknown-Target-Entity", targetEntity);
+ }
+
+ @Test
+ public void setupMDCTest() throws URISyntaxException {
+ doReturn("SO").when(springClientFilter).extractTargetEntity(clientRequest);
+ URI uri = new URI("onap/so/serviceInstances");
+ when(clientRequest.getURI()).thenReturn(uri);
+
+ springClientFilter.setupMDC(clientRequest);
+
+ assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME));
+ assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY));
+ assertEquals("INPROGRESS", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+ assertNotNull(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE);
+ assertNotNull(ONAPLogConstants.MDCs.SERVICE_NAME);
+ assertNotNull(ONAPLogConstants.MDCs.SERVER_FQDN);
+ }
+
+ @Test
+ public void setupHeadersTest() {
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, "8819bfb4-69d2-43fc-b0d6-81d2690533ea");
+ HttpHeaders headers = new HttpHeaders();
+ when(clientRequest.getHeaders()).thenReturn(headers);
+ doReturn("0a908a5d-e774-4558-96ff-6edcbba65483").when(springClientFilter).extractRequestID(clientRequest);
+
+ springClientFilter.setupHeaders(clientRequest);
+
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(ONAPLogConstants.Headers.REQUEST_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.HEADER_REQUEST_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.TRANSACTION_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.TRANSACTION_ID));
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.ECOMP_REQUEST_ID));
+ assertEquals("8819bfb4-69d2-43fc-b0d6-81d2690533ea", headers.getFirst(ONAPLogConstants.Headers.INVOCATION_ID));
+ assertEquals("UNKNOWN", headers.getFirst(ONAPLogConstants.Headers.PARTNER_NAME));
+ }
+
+ @Test
+ public void extractRequestIDTest() {
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, "0a908a5d-e774-4558-96ff-6edcbba65483");
+ String requestId = springClientFilter.extractRequestID(clientRequest);
+ assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", requestId);
+ }
+
+ @Test
+ public void extractRequestIDNullTest() {
+ String requestId = springClientFilter.extractRequestID(clientRequest);
+ assertNotNull(requestId);
+ assertNotNull(ONAPLogConstants.MDCs.LOG_TIMESTAMP);
+ assertNotNull(ONAPLogConstants.MDCs.ELAPSED_TIME);
+ }
+
+ @Test
+ public void interceptTest() throws IOException {
+ byte[] body = new byte[3];
+ doNothing().when(springClientFilter).processRequest(clientRequest, body);
+ doReturn(response).when(execution).execute(clientRequest, body);
+ doNothing().when(springClientFilter).processResponse(response);
+
+ ClientHttpResponse httpResponse = springClientFilter.intercept(clientRequest, body, execution);
+ assertEquals(response, httpResponse);
+ }
+}
diff --git a/reference/logging-filter/pom.xml b/reference/logging-filter/pom.xml
new file mode 100644
index 0000000..6038024
--- /dev/null
+++ b/reference/logging-filter/pom.xml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-reference</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>logging-filter-parent</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>logging-filter-base</module>
+ <module>logging-filter-spring</module>
+ </modules>
+
+ <properties>
+ <format.skipValidate>false</format.skipValidate>
+ <format.skipExecute>true</format.skipExecute>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId> javax.annotation-api</artifactId>
+ <version>1.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-slf4j</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <version>2.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.25</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>2.11.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>2.15.0</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.5.1</version>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <showWarnings>true</showWarnings>
+ <compilerArgs>
+ <arg>-parameters</arg>
+ <arg>-Xlint:deprecation</arg>
+ </compilerArgs>
+ </configuration>
+ </execution>
+ <execution>
+ <id>default-testCompile</id>
+ <phase>test-compile</phase>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <showWarnings>true</showWarnings>
+ <compilerArgs>
+ <arg>-parameters</arg>
+ <arg>-Xlint:deprecation</arg>
+ </compilerArgs>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <showWarnings>true</showWarnings>
+ <compilerArgs>
+ <arg>-parameters</arg>
+ <arg>-Xlint:deprecation</arg>
+ </compilerArgs>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.gmaven</groupId>
+ <artifactId>groovy-maven-plugin</artifactId>
+ <version>2.0</version>
+ <executions>
+ <!-- set absolute base path from super pom -->
+ <execution>
+ <id>find-basepath</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>
+ <![CDATA[
+ import java.io.File;
+ log.info('## define projects super pom absolute path through basepath_marker')
+ String p = "basepath_marker";
+ File f = null;
+ if( p != null ) {
+ def _max_child_poms = 0
+ while( _max_child_poms++ < 5 ) {
+ f = new File( p );
+ if( f.exists() ) {
+ break;
+ }
+ p = "../" + p;
+ }
+ }
+ if( f != null ) {
+ String basePath = f.getCanonicalPath();
+ basePath = basePath.substring( 0, basePath.lastIndexOf( File.separator ) );
+ project.properties['base-path'] = basePath.replace( '\\' , '/');
+ log.info(' - used base path = ' + project.properties['base-path'] );
+ } else {
+ log.error( 'Could not find basepath_marker marker file!' );
+ System.stop( 0 );
+ }
+ ]]>
+ </source>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>net.revelc.code.formatter</groupId>
+ <artifactId>formatter-maven-plugin</artifactId>
+ <version>2.9.0</version>
+ <executions>
+ <execution>
+ <id>format-java</id>
+ <goals>
+ <goal>format</goal>
+ </goals>
+ <configuration>
+ <skip>${format.skipExecute}</skip>
+ <configFile>${base-path}/project-configs/code-tools/onap-eclipse-format.xml</configFile>
+ </configuration>
+ </execution>
+ <execution>
+ <id>format-xml</id>
+ <goals>
+ <goal>format</goal>
+ </goals>
+ <configuration>
+ <skip>${format.skipExecute}</skip>
+ <sourceDirectory>${project.basedir}</sourceDirectory>
+ <configXmlFile>${base-path}/project-configs/code-tools/pom-format.properties</configXmlFile>
+ <includes>
+ <include>${project.basedir}/pom.xml</include>
+ </includes>
+ </configuration>
+ </execution>
+ <execution>
+ <id>validate-java</id>
+ <goals>
+ <goal>validate</goal>
+ </goals>
+ <configuration>
+ <skip>${format.skipValidate}</skip>
+ <configFile>${base-path}/project-configs/code-tools/onap-eclipse-format.xml</configFile>
+ </configuration>
+ </execution>
+ <execution>
+ <id>validate-poms</id>
+ <goals>
+ <goal>validate</goal>
+ </goals>
+ <configuration>
+ <skip>${format.skipValidate}</skip>
+ <configFile>${base-path}/project-configs/code-tools/pom-format.properties</configFile>
+ <includes>
+ <include>${project.basedir}/pom.xml</include>
+ </includes>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>2.9.8</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>format</id>
+ <properties>
+ <format.skipValidate>true</format.skipValidate>
+ <format.skipExecute>false</format.skipExecute>
+ </properties>
+ </profile>
+ </profiles>
+</project>