aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvempo <vitaliy.emporopulo@amdocs.com>2018-08-02 17:25:25 +0300
committerAvi Gaffa <avi.gaffa@amdocs.com>2018-08-06 08:24:42 +0000
commitc8661bd2bab88a77a29167c782a76cdf729648ed (patch)
treed5a003ca4ebc4ff7948c0dcddb9e8b9244b1aa8c
parent6e6a179914fd6b8516c697991a501535bfc53172 (diff)
Added logging interceptor for Spring
Change-Id: I1de1f6baca48f36f05e32231f5a7e900738bd900 Issue-ID: SDC-1580 Signed-off-by: vempo <vitaliy.emporopulo@amdocs.com>
-rw-r--r--onboarding/pom.xml5
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/pom.xml27
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/main/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptor.java115
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/test/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptorTest.java117
4 files changed, 264 insertions, 0 deletions
diff --git a/onboarding/pom.xml b/onboarding/pom.xml
index bbc6396921..f310178a12 100644
--- a/onboarding/pom.xml
+++ b/onboarding/pom.xml
@@ -125,6 +125,11 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${spring.framework.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.3</version>
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/pom.xml b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/pom.xml
index b556a2a9b0..8b87fba922 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/pom.xml
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/pom.xml
@@ -28,5 +28,32 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>openecomp-sdc-logging-spring</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdc</groupId>
+ <artifactId>openecomp-sdc-logging-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
</project> \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/main/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptor.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/main/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptor.java
new file mode 100644
index 0000000000..a467a9e38a
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/main/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptor.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.logging.servlet.spring;
+
+import static org.openecomp.sdc.logging.api.StatusCode.COMPLETE;
+import static org.openecomp.sdc.logging.api.StatusCode.ERROR;
+
+import java.util.Objects;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.openecomp.sdc.logging.api.Logger;
+import org.openecomp.sdc.logging.api.LoggerFactory;
+import org.openecomp.sdc.logging.api.StatusCode;
+import org.openecomp.sdc.logging.servlet.CombinedTracker;
+import org.openecomp.sdc.logging.servlet.HttpHeader;
+import org.openecomp.sdc.logging.servlet.RequestProcessingResult;
+import org.openecomp.sdc.logging.servlet.Tracker;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+/**
+ * <p>IMPORTANT: For this interceptor to work, all exceptions must be properly handled before being returned to a
+ * client. Any unexpected, automatically handled exception bypasses the interceptor and will not be logged.</p>
+ * <p>The interceptor must be either registered in Spring configuration XML as a bean, or programmatically as described
+ * in <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-config-interceptors">
+ * Spring MVC Config: Interceptors</a>.</p>
+ *
+ * @author evitaliy
+ * @since 02 Aug 2018
+ */
+public class LoggingInterceptor extends HandlerInterceptorAdapter {
+
+ static final String LOGGING_TRACKER_KEY = "onap.logging.tracker";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LoggingInterceptor.class);
+
+ private final HttpHeader partnerNameHeader;
+ private final HttpHeader requestIdHeader;
+
+ public LoggingInterceptor(HttpHeader partnerNameHeader, HttpHeader requestIdHeader) {
+ this.partnerNameHeader = Objects.requireNonNull(partnerNameHeader);
+ this.requestIdHeader = Objects.requireNonNull(requestIdHeader);
+ }
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ Class<?> resourceClass = getResourceType(handler);
+ Tracker tracker = new CombinedTracker(resourceClass, partnerNameHeader, requestIdHeader);
+ request.setAttribute(LOGGING_TRACKER_KEY, tracker);
+ tracker.preRequest(request);
+ return true;
+ }
+
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
+ Exception ex) {
+
+ Tracker tracker = (Tracker) request.getAttribute(LOGGING_TRACKER_KEY);
+
+ if (tracker == null) {
+ LOGGER.debug("No logging tracker received");
+ return;
+ }
+
+ tracker.postRequest(new ServletResponseResult(response.getStatus()));
+ }
+
+ private Class<?> getResourceType(Object handler) {
+
+ if (handler instanceof HandlerMethod) {
+ return ((HandlerMethod) handler).getMethod().getDeclaringClass();
+ }
+
+ return LoggingInterceptor.class;
+ }
+
+ static class ServletResponseResult implements RequestProcessingResult {
+
+ private final HttpStatus status;
+
+ ServletResponseResult(int status) {
+ this.status = HttpStatus.valueOf(status);
+ }
+
+ @Override
+ public int getStatus() {
+ return status.value();
+ }
+
+ @Override
+ public StatusCode getStatusCode() {
+ return status.is2xxSuccessful() || status.is3xxRedirection() ? COMPLETE : ERROR;
+ }
+
+ @Override
+ public String getStatusPhrase() {
+ return status.getReasonPhrase();
+ }
+ }
+} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/test/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptorTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/test/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptorTest.java
new file mode 100644
index 0000000000..ccd0b70552
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-spring/src/test/java/org/openecomp/sdc/logging/servlet/spring/LoggingInterceptorTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.logging.servlet.spring;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.openecomp.sdc.logging.api.StatusCode.COMPLETE;
+import static org.openecomp.sdc.logging.api.StatusCode.ERROR;
+import static org.openecomp.sdc.logging.servlet.spring.LoggingInterceptor.LOGGING_TRACKER_KEY;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Test;
+import org.openecomp.sdc.logging.servlet.HttpHeader;
+import org.openecomp.sdc.logging.servlet.RequestProcessingResult;
+import org.openecomp.sdc.logging.servlet.Tracker;
+
+/**
+ * Audit tracking via Spring interceptor.
+ *
+ * @author evitaliy
+ * @since 05 Aug 2018
+ */
+public class LoggingInterceptorTest {
+
+ @Test(expected = NullPointerException.class)
+ public void exceptionThrownWhenPartnerNameHeaderNull() {
+ new LoggingInterceptor(null, mock(HttpHeader.class));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void exceptionThrownWhenRequestIdHeaderNull() {
+ new LoggingInterceptor(mock(HttpHeader.class), null);
+ }
+
+ @Test
+ public void trackerAddedWhenBeforeRequest() {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ LoggingInterceptor interceptor = new LoggingInterceptor(mock(HttpHeader.class), mock(HttpHeader.class));
+ interceptor.preHandle(request, mock(HttpServletResponse.class), null);
+ verify(request).setAttribute(eq(LOGGING_TRACKER_KEY), any(Tracker.class));
+ }
+
+ @Test
+ public void trackerInvokedWhenPresentInRequest() {
+
+ Tracker tracker = mock(Tracker.class);
+
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getAttribute(LOGGING_TRACKER_KEY)).thenReturn(tracker);
+
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ when(response.getStatus()).thenReturn(200);
+
+ LoggingInterceptor interceptor = new LoggingInterceptor(mock(HttpHeader.class), mock(HttpHeader.class));
+ interceptor.afterCompletion(request, response, null, null);
+ verify(tracker).postRequest(any(RequestProcessingResult.class));
+ }
+
+ @Test
+ public void errorStatusWhenInformationalCode() {
+ final int status = 101;
+ LoggingInterceptor.ServletResponseResult result = new LoggingInterceptor.ServletResponseResult(status);
+ assertEquals(status, result.getStatus());
+ assertEquals(ERROR, result.getStatusCode());
+ }
+
+ @Test
+ public void errorStatusWhenClientErrorCode() {
+ final int status = 404;
+ LoggingInterceptor.ServletResponseResult result = new LoggingInterceptor.ServletResponseResult(status);
+ assertEquals(status, result.getStatus());
+ assertEquals(ERROR, result.getStatusCode());
+ }
+
+ @Test
+ public void errorStatusWhenServerErrorCode() {
+ final int status = 503;
+ LoggingInterceptor.ServletResponseResult result = new LoggingInterceptor.ServletResponseResult(status);
+ assertEquals(status, result.getStatus());
+ assertEquals(ERROR, result.getStatusCode());
+ }
+
+ @Test
+ public void completeStatusWhenSuccessCode() {
+ final int status = 204;
+ LoggingInterceptor.ServletResponseResult result = new LoggingInterceptor.ServletResponseResult(status);
+ assertEquals(status, result.getStatus());
+ assertEquals(COMPLETE, result.getStatusCode());
+ }
+
+ @Test
+ public void completeStatusWhenRedirectionCode() {
+ final int status = 307;
+ LoggingInterceptor.ServletResponseResult result = new LoggingInterceptor.ServletResponseResult(status);
+ assertEquals(status, result.getStatus());
+ assertEquals(COMPLETE, result.getStatusCode());
+ }
+} \ No newline at end of file