Jakarta support for spring logging filters

Ported spring logging filters from unmaintained logging-analytics
project to ccsdk and updated to support jakarta.

Issue-ID: CCSDK-4053
Change-Id: I8343c744d88588897804dff9f6e58868bf837681
Signed-off-by: Dan Timoney <dtimoney@att.com>
diff --git a/pom.xml b/pom.xml
index a515c9e..02813d1 100755
--- a/pom.xml
+++ b/pom.xml
@@ -53,7 +53,8 @@
         <gson.version>2.9.0</gson.version>
 	    <springfox.version>3.0.0</springfox.version>
         <aaf.cadi.version>2.1.21</aaf.cadi.version>
-        <ccsdk.sli.core.version>1.7.1</ccsdk.sli.core.version>
+        <ccsdk.sli.version>1.9.0-SNAPSHOT</ccsdk.sli.version>
+        <ccsdk.sli.core.version>${ccsdk.sli.version}</ccsdk.sli.core.version>
         <maven.compiler.source>1.11</maven.compiler.source>
         <maven.compiler.target>1.11</maven.compiler.target>
     </properties>
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractServletFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractServletFilter.java
new file mode 100644
index 0000000..992345c
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractServletFilter.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.ccsdk.apps.filters;
+
+import java.util.Enumeration;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.ws.rs.core.HttpHeaders;
+
+public abstract class AbstractServletFilter {
+
+    protected String getSecureRequestHeaders(HttpServletRequest httpRequest) {
+        StringBuilder sb = new StringBuilder();
+        String header;
+        for (Enumeration<String> e = httpRequest.getHeaderNames(); e.hasMoreElements();) {
+            header = e.nextElement();
+            sb.append(header);
+            sb.append(":");
+            if (header.equalsIgnoreCase(HttpHeaders.AUTHORIZATION)) {
+                sb.append(Constants.REDACTED);
+            } else {
+                sb.append(httpRequest.getHeader(header));
+            }
+            sb.append(";");
+        }
+        return sb.toString();
+    }
+
+    protected String formatResponseHeaders(HttpServletResponse response) {
+        StringBuilder sb = new StringBuilder();
+        for (String headerName : response.getHeaderNames()) {
+            sb.append(headerName);
+            sb.append(":");
+            sb.append(response.getHeader(headerName));
+            sb.append(";");
+        }
+        return sb.toString();
+    }
+}
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/Constants.java b/services/src/main/java/org/onap/ccsdk/apps/filters/Constants.java
new file mode 100644
index 0000000..efbfe90
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/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.ccsdk.apps.filters;
+
+public class Constants {
+    protected static final String REDACTED = "***REDACTED***";
+
+    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 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/services/src/main/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptor.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptor.java
new file mode 100644
index 0000000..3f89ee1
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptor.java
@@ -0,0 +1,68 @@
+/*-
+ * ============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.ccsdk.apps.filters.spring;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Providers;
+import org.onap.ccsdk.apps.filters.AbstractAuditLogFilter;
+import org.onap.ccsdk.apps.filters.SimpleServletHeadersMap;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+@Component
+public class LoggingInterceptor extends AbstractAuditLogFilter<HttpServletRequest, HttpServletResponse>
+        implements HandlerInterceptor {
+
+    @Context
+    private Providers providers;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+        SimpleMap headers = new SimpleServletHeadersMap(request);
+        pre(headers, request, request);
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+            ModelAndView modelAndView) throws Exception {
+        post(response);
+    }
+
+    @Override
+    protected int getResponseCode(HttpServletResponse response) {
+        return response.getStatus();
+    }
+
+    @Override
+    protected void setServiceName(HttpServletRequest request) {
+        MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, request.getRequestURI());
+    }
+
+}
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/MDCTaskDecorator.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/MDCTaskDecorator.java
new file mode 100644
index 0000000..6969c3e
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/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.ccsdk.apps.filters.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/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilter.java
new file mode 100644
index 0000000..42002fe
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilter.java
@@ -0,0 +1,99 @@
+/*-
+ * ============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.ccsdk.apps.filters.spring;
+
+import java.io.IOException;
+import java.util.List;
+import org.onap.logging.filter.base.AbstractMetricLogFilter;
+import org.onap.logging.filter.base.Constants;
+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.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+
+public class SpringClientFilter extends AbstractMetricLogFilter<HttpRequest, ClientHttpResponse, HttpHeaders>
+        implements ClientHttpRequestInterceptor {
+
+    public SpringClientFilter() {
+
+    }
+
+    @Override
+    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
+            throws IOException {
+        pre(request, request.getHeaders());
+        ClientHttpResponse response = execution.execute(request, body);
+        post(request, response);
+        return response;
+    }
+
+    @Override
+    protected void addHeader(HttpHeaders requestHeaders, String headerName, String headerValue) {
+        requestHeaders.add(headerName, headerValue);
+    }
+
+    @Override
+    protected String getTargetServiceName(HttpRequest request) {
+        return request.getURI().toString();
+    }
+
+    @Override
+    protected int getHttpStatusCode(ClientHttpResponse response) {
+        try {
+            return response.getStatusCode().value();
+        } catch (IOException e) {
+            // TODO figure out the right thing to do here
+            return 500;
+        }
+    }
+
+    @Override
+    protected String getResponseCode(ClientHttpResponse response) {
+        try {
+            return response.getStatusCode().toString();
+        } catch (IOException e) {
+            return "500";
+        }
+    }
+
+    @Override
+    protected String getTargetEntity(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;
+    }
+
+}
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientPayloadFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientPayloadFilter.java
new file mode 100644
index 0000000..db14a7e
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientPayloadFilter.java
@@ -0,0 +1,69 @@
+/*-
+ * ============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.ccsdk.apps.filters.spring;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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 SpringClientPayloadFilter implements ClientHttpRequestInterceptor {
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Override
+    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
+            throws IOException {
+        logRequest(request, body);
+        ClientHttpResponse response = execution.execute(request, body);
+        logResponse(response);
+        return response;
+    }
+
+    protected void logRequest(HttpRequest request, byte[] body) throws IOException {
+        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 logResponse(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=================================================");
+        }
+    }
+
+}
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringScheduledTasksMDCSetupAspect.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringScheduledTasksMDCSetupAspect.java
new file mode 100644
index 0000000..7e8c749
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringScheduledTasksMDCSetupAspect.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2020 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.ccsdk.apps.filters.spring;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.onap.logging.filter.base.AbstractMDCSetupAspect;
+import org.onap.logging.filter.base.ScheduledTaskException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+public class SpringScheduledTasksMDCSetupAspect extends AbstractMDCSetupAspect {
+
+    protected static Logger logger = LoggerFactory.getLogger(SpringScheduledTasksMDCSetupAspect.class);
+
+    @Around("@annotation(org.onap.logging.filter.base.ScheduledLogging)")
+    public void logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
+        setupMDC(joinPoint.getSignature().getName());
+        try {
+            joinPoint.proceed();
+        } catch (ScheduledTaskException e) {
+            errorMDCSetup(e.getErrorCode(), e.getMessage());
+            logger.error("ScheduledTaskException: ", e);
+        }
+        exitAndClearMDC();
+    }
+}
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/StatusLoggingInterceptor.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/StatusLoggingInterceptor.java
new file mode 100644
index 0000000..931b2dd
--- /dev/null
+++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/StatusLoggingInterceptor.java
@@ -0,0 +1,73 @@
+/*-
+ * ============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.ccsdk.apps.filters.spring;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Providers;
+import org.onap.ccsdk.apps.filters.AbstractServletFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+@Component
+public class StatusLoggingInterceptor extends AbstractServletFilter implements HandlerInterceptor {
+
+    private static final Logger logger = LoggerFactory.getLogger(StatusLoggingInterceptor.class);
+
+    @Context
+    private Providers providers;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+        if (logger.isDebugEnabled()) {
+            logRequestInformation(request);
+        }
+        return true;
+    }
+
+    protected void logRequestInformation(HttpServletRequest request) {
+        logger.debug("===========================request begin================================================");
+        logger.debug("URI         : {}", request.getRequestURI());
+        logger.debug("Method      : {}", request.getMethod());
+        logger.debug("Headers     : {}", getSecureRequestHeaders(request));
+        logger.debug("===========================request end==================================================");
+    }
+
+    // TODO previously no response information was being logged, I followed the format in SpringClientPayloadFilter
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+            ModelAndView modelAndView) throws Exception {
+        if (logger.isDebugEnabled()) {
+            logger.debug("============================response begin==========================================");
+            logger.debug("Status code  : {}", response.getStatus());
+            logger.debug("Status text  : {}", Response.Status.fromStatusCode(response.getStatus()));
+            logger.debug("Headers      : {}", formatResponseHeaders(response));
+            logger.debug("============================response end============================================");
+        }
+    }
+}
diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/AuditLogServletFilterTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/AuditLogServletFilterTest.java
new file mode 100644
index 0000000..8a9a656
--- /dev/null
+++ b/services/src/test/java/org/onap/ccsdk/apps/filters/AuditLogServletFilterTest.java
@@ -0,0 +1,82 @@
+/*-
+ * ============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.ccsdk.apps.filters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.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.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuditLogServletFilterTest {
+
+    @Mock
+    private ServletRequest request;
+
+    @Mock
+    private ServletResponse response;
+
+    @Mock
+    private HttpServletRequest servletRequest;
+
+    @Mock
+    private HttpServletResponse servletResponse;
+
+    @Spy
+    @InjectMocks
+    private AuditLogServletFilter auditLogServletFilter;
+
+    @After
+    public void tearDown() {
+        MDC.clear();
+    }
+
+    @Test
+    public void preTest() {
+        when(servletRequest.getRequestURI()).thenReturn("onap/so/serviceInstances");
+        auditLogServletFilter.pre(servletRequest);
+
+        assertNotNull(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/services/src/test/java/org/onap/ccsdk/apps/filters/MDCSetupTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/MDCSetupTest.java
new file mode 100644
index 0000000..2f7f73d
--- /dev/null
+++ b/services/src/test/java/org/onap/ccsdk/apps/filters/MDCSetupTest.java
@@ -0,0 +1,335 @@
+/*-
+ * ============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.ccsdk.apps.filters;
+
+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.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.HashMap;
+import jakarta.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.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.logging.filter.base.ONAPComponents;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.filter.base.SimpleHashMap;
+import org.onap.logging.filter.base.SimpleJaxrsHeadersMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MDCSetupTest extends MDCSetup {
+
+    @Mock
+    private HttpServletRequest httpServletRequest;
+
+    private String requestId = "4d31fe02-4918-4975-942f-fe51a44e6a9b";
+    private String invocationId = "4d31fe02-4918-4975-942f-fe51a44e6a9a";
+
+    @After
+    public void tearDown() {
+        MDC.clear();
+        System.clearProperty("partnerName");
+    }
+
+    @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");
+
+        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");
+
+        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 = 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 = 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 = 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 = getRequestId(new SimpleHashMap(headers));
+        assertEquals(requestId, fetchedRequestId);
+    }
+
+    @Test
+    public void setRequestIdNoHeaderTest() {
+        HashMap<String, String> headers = new HashMap<>();
+        String fetchedRequestId = getRequestId(new SimpleHashMap(headers));
+        assertNotNull(fetchedRequestId);
+    }
+
+    @Test
+    public void setInvocationIdTest() {
+        HashMap<String, String> headers = new HashMap<>();
+        headers.put(ONAPLogConstants.Headers.INVOCATION_ID, invocationId);
+        setInvocationId(new SimpleHashMap(headers));
+        assertEquals(invocationId, MDC.get(ONAPLogConstants.MDCs.SERVER_INVOCATION_ID));
+        assertEquals(invocationId, MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+    }
+
+    @Test
+    public void setInvocationIdNoHeaderTest() {
+        HashMap<String, String> headers = new HashMap<>();
+        setInvocationId(new SimpleHashMap(headers));
+        assertNotNull(MDC.get(ONAPLogConstants.MDCs.SERVER_INVOCATION_ID));
+        assertNotNull(MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+    }
+
+    @Test
+    public void setResponseStatusCodeTest() {
+        setResponseStatusCode(200);
+        assertEquals("COMPLETE", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE));
+    }
+
+    @Test
+    public void setResponseStatusCodeErrorTest() {
+        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.CLIENT_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");
+
+        clearClientMDCs();
+        assertNull(MDC.get(ONAPLogConstants.MDCs.CLIENT_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() {
+        setTargetEntity(ONAPComponents.SO);
+        assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY));
+    }
+
+    @Test
+    public void setResponseDescriptionTest() {
+        setResponseDescription(502);
+        assertEquals("Bad Gateway", MDC.get(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION));
+    }
+
+    @Test
+    public void setMDCPartnerNameBearerToken() {
+        MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+        String value = "Bearer some-compex-token";
+        headerMap.putSingle(HttpHeaders.AUTHORIZATION, value);
+        SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+        setMDCPartnerName(headers);
+
+        assertEquals(Constants.DefaultValues.UNKNOWN, MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+    }
+
+    @Test
+    public void setMDCPartnerNameFromBasicAuth() {
+        MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+        String value = "Basic dXNlcjpwYXNz"; // decodes to user:pass
+        headerMap.putSingle(HttpHeaders.AUTHORIZATION, value);
+        SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+        setMDCPartnerName(headers);
+
+        assertEquals("user", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+    }
+
+    @Test
+    public void setMDCPartnerNameTest() {
+        MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+        headerMap.putSingle(ONAPLogConstants.Headers.PARTNER_NAME, "SO");
+        SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+        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);
+
+        setMDCPartnerName(headers);
+
+        assertEquals("Apache-HttpClient/4.5.8 (Java/1.8.0_191)", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+    }
+
+    @Test
+    public void setMDCPartnerNameNoHeaderTest() {
+        MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
+        SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap);
+
+        setMDCPartnerName(headers);
+
+        assertEquals("UNKNOWN", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME));
+    }
+
+    @Test
+    public void setServerFQDNTest() {
+        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");
+        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");
+        setClientIPAddress(httpServletRequest);
+
+        assertEquals("127.0.0.1", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS));
+    }
+
+    @Test
+    public void setClientIPAddressNullTest() {
+        setClientIPAddress(null);
+
+        assertEquals("", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS));
+    }
+
+    @Test
+    public void setEntryTimeStampTest() {
+        setEntryTimeStamp();
+
+        assertNotNull(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP));
+    }
+
+    @Test
+    public void setLogTimestampTest() {
+        setLogTimestamp();
+
+        assertNotNull(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP));
+    }
+
+    @Test
+    public void setInstanceIDTest() {
+        setInstanceID();
+
+        assertNotNull(MDC.get(ONAPLogConstants.MDCs.INSTANCE_UUID));
+    }
+
+    @Test
+    public void getPropertyTest() {
+        System.setProperty("partnerName", "partnerName");
+
+        String partnerName = getProperty("partnerName");
+        assertEquals("partnerName", partnerName);
+    }
+
+    @Test
+    public void getPropertyNullTest() {
+        String partnerName = getProperty("partner");
+        assertEquals("UNKNOWN", partnerName);
+    }
+
+    @Test
+    public void overrideServerIp() {
+        String ip = "127.0.0.1";
+        System.setProperty(serverIpAddressOverride, ip);
+        MDCSetup m = new MDCSetup();
+        assertEquals(ip, m.serverIpAddress);
+    }
+
+    @Test
+    public void overrideServerFqdn() {
+        String nodeName = "node300";
+        System.setProperty(serverFqdnOverride, nodeName);
+        MDCSetup m = new MDCSetup();
+        assertEquals(nodeName, m.serverFqdn);
+    }
+
+    @Test
+    public void testPrecision() {
+        System.setProperty(MDCSetup.INSTANT_PRECISION_OVERRIDE, "3");
+        ZonedDateTime zdt = ZonedDateTime.now(ZoneOffset.UTC);
+        zdt = zdt.withNano(333666999);
+        MDCSetup m = new MDCSetup();
+        String currentTimestamp = m.getCurrentTimeStamp();
+        assertEquals(24, currentTimestamp.length());
+    }
+
+}
diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMapTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMapTest.java
new file mode 100644
index 0000000..72beacd
--- /dev/null
+++ b/services/src/test/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMapTest.java
@@ -0,0 +1,51 @@
+/*-
+ * ============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.ccsdk.apps.filters;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+import jakarta.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;
+
+@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/services/src/test/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptorTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptorTest.java
new file mode 100644
index 0000000..a059912
--- /dev/null
+++ b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptorTest.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.ccsdk.apps.filters.spring;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.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.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;
+
+    @Spy
+    @InjectMocks
+    private LoggingInterceptor loggingInterceptor;
+
+    @Test
+    public void preHandleTest() throws Exception {
+        loggingInterceptor.preHandle(request, response, handler);
+        assertEquals(MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE), "INPROGRESS");
+        assertNotNull(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+    }
+}
diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilterTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilterTest.java
new file mode 100644
index 0000000..040f6e5
--- /dev/null
+++ b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilterTest.java
@@ -0,0 +1,161 @@
+/*-
+ * ============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.ccsdk.apps.filters.spring;
+
+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.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+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.ccsdk.apps.filters.MDCSetup;
+import org.onap.logging.filter.base.Constants;
+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 extends SpringClientFilter {
+
+    @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 = 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.getTargetEntity(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.getTargetEntity(clientRequest);
+        assertEquals("SO", targetEntity);
+    }
+
+    @Test
+    public void extractTargetEntityNoHeaderTest() {
+        HttpHeaders headers = new HttpHeaders();
+        when(clientRequest.getHeaders()).thenReturn(headers);
+
+        String targetEntity = springClientFilter.getTargetEntity(clientRequest);
+        assertEquals("Unknown-Target-Entity", targetEntity);
+    }
+
+    @Test
+    public void setupMDCTest() throws URISyntaxException {
+        URI uri = new URI("onap/so/serviceInstances");
+        when(clientRequest.getURI()).thenReturn(uri);
+        when(clientRequest.getHeaders()).thenReturn(new HttpHeaders());
+        setupMDC(clientRequest);
+        assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME));
+        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() {
+        HttpHeaders headers = new HttpHeaders();
+        setupHeaders(clientRequest, headers, "0a908a5d-e774-4558-96ff-6edcbba65483",
+                "4d93e6e2-ff27-4818-9752-1cfe3090d3f1");
+
+        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));
+        assertNotNull(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 = extractRequestID();
+        assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", requestId);
+    }
+
+    @Test
+    public void extractRequestIDNullTest() {
+        // NPE exception will occur when extractRequestID is called if INVOKE_TIMESTAMP is null
+        MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP,
+                ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT));
+        String requestId = extractRequestID();
+        assertNotNull(requestId);
+        assertNotNull(ONAPLogConstants.MDCs.LOG_TIMESTAMP);
+        assertNotNull(ONAPLogConstants.MDCs.ELAPSED_TIME);
+    }
+
+    @Test
+    public void interceptTest() throws IOException {
+        byte[] body = new byte[3];
+        doReturn(response).when(execution).execute(clientRequest, body);
+        ClientHttpResponse httpResponse = springClientFilter.intercept(clientRequest, body, execution);
+        assertEquals(response, httpResponse);
+    }
+}