aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main
diff options
context:
space:
mode:
authorvempo <vitaliy.emporopulo@amdocs.com>2018-07-31 18:50:14 +0300
committerAvi Gaffa <avi.gaffa@amdocs.com>2018-08-05 12:15:49 +0000
commit1b01b984901d5f69d5e421e459d62a6d03292444 (patch)
tree2e172e9c4ba8b19a286b89d93270629a5b768a89 /openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main
parentd05277df22ddde79458cd853f98e7ab3a4d98913 (diff)
Simplified logging code for servlets
Added and simplified unit tests, organized imports, refactored for simplicity and reuse. Change-Id: I4c4837447329528ae855f2e8d1a1f4b883617f33 Issue-ID: SDC-1580 Signed-off-by: vempo <vitaliy.emporopulo@amdocs.com>
Diffstat (limited to 'openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main')
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java3
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java3
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java9
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/AuditTracker.java85
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/CombinedTracker.java55
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ContextTracker.java66
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/HttpHeader.java73
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/LoggingFilter.java136
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/RequestProcessingResult.java49
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ServiceNameFormatter.java36
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/Tracker.java44
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilter.java78
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilter.java133
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggerCreationService.java1
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggingContextService.java3
15 files changed, 466 insertions, 308 deletions
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java
index 30517cd5fb..96debb56b0 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java
@@ -16,9 +16,8 @@
package org.openecomp.sdc.logging.api;
-import org.openecomp.sdc.logging.spi.LoggerCreationService;
-
import java.util.Objects;
+import org.openecomp.sdc.logging.spi.LoggerCreationService;
/**
* <a>Factory to hide a concrete, framework-specific implementation of logger creation.</a>
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java
index 9526713093..894dd2c00c 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java
@@ -16,10 +16,9 @@
package org.openecomp.sdc.logging.api;
-import org.openecomp.sdc.logging.spi.LoggingContextService;
-
import java.util.Objects;
import java.util.concurrent.Callable;
+import org.openecomp.sdc.logging.spi.LoggingContextService;
/**
* <p>Factory to hide a concrete, framework-specific implementation of diagnostic context.</p>
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java
index 5aaa301a9c..6e5b3e3501 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java
@@ -16,13 +16,12 @@
package org.openecomp.sdc.logging.api;
-import org.openecomp.sdc.logging.spi.LoggerCreationService;
-import org.openecomp.sdc.logging.spi.LoggingContextService;
-import org.openecomp.sdc.logging.spi.LoggingServiceProvider;
-
import java.util.Iterator;
import java.util.Optional;
import java.util.ServiceLoader;
+import org.openecomp.sdc.logging.spi.LoggerCreationService;
+import org.openecomp.sdc.logging.spi.LoggingContextService;
+import org.openecomp.sdc.logging.spi.LoggingServiceProvider;
/**
* <p>Binds to a concrete implementation of logging services.</p>
@@ -37,7 +36,7 @@ import java.util.ServiceLoader;
// No advanced logging can be used here because we don't know
// which underlying implementation will be used
-@SuppressWarnings({"UseOfSystemOutOrSystemErr", "squid:S106"})
+@SuppressWarnings({"UseOfSystemOutOrSystemErr", "squid:S106", "squid:S1166"})
class ServiceBinder {
private static final LoggingServiceProvider PROVIDER = lookupProvider();
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/AuditTracker.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/AuditTracker.java
new file mode 100644
index 0000000000..af9b5061fd
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/AuditTracker.java
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+import java.util.Objects;
+import javax.servlet.http.HttpServletRequest;
+import org.openecomp.sdc.logging.api.AuditData;
+import org.openecomp.sdc.logging.api.Logger;
+import org.openecomp.sdc.logging.api.LoggerFactory;
+
+/**
+ * Tracks and logs audit information when a request is being processed. An instance of this class cannot be reused, and
+ * the pre- and post-request methods must be called only once.
+ *
+ * @author evitaliy
+ * @since 31 Jul 2018
+ */
+public class AuditTracker implements Tracker {
+
+ private final Logger logger;
+ private volatile long started;
+ private volatile String clientIpAddress;
+
+ /**
+ * Allows passing a class that will be used to log audit.
+ *
+ * @param resourceType audit will be logged through the logger of this class
+ */
+ public AuditTracker(Class<?> resourceType) {
+ this.logger = LoggerFactory.getLogger(resourceType);
+ }
+
+ /**
+ * Allows passing a logger that will be used to log audit.
+ *
+ * @param logger audit will be logged through this logger, cannot be null
+ */
+ public AuditTracker(Logger logger) {
+ this.logger = Objects.requireNonNull(logger);
+ }
+
+ @Override
+ public synchronized void preRequest(HttpServletRequest request) {
+
+ if (this.started > 0) {
+ throw new IllegalStateException("Pre-request has been already called");
+ }
+
+ this.started = System.currentTimeMillis();
+ this.clientIpAddress = request.getRemoteAddr();
+ }
+
+ @Override
+ public synchronized void postRequest(RequestProcessingResult result) {
+
+ if (this.started == 0) {
+ throw new IllegalStateException("Pre-request must be called first");
+ }
+
+ if (!logger.isAuditEnabled()) {
+ return;
+ }
+
+ long end = System.currentTimeMillis();
+ AuditData auditData = AuditData.builder().startTime(started).endTime(end).statusCode(result.getStatusCode())
+ .responseCode(Integer.toString(result.getStatus()))
+ .responseDescription(result.getStatusPhrase()).clientIpAddress(clientIpAddress)
+ .build();
+ logger.audit(auditData);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/CombinedTracker.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/CombinedTracker.java
new file mode 100644
index 0000000000..2dd2c12143
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/CombinedTracker.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import javax.servlet.http.HttpServletRequest;
+import org.openecomp.sdc.logging.api.Logger;
+
+/**
+ * Tracker for all the elements of ONAP logging and tracing at an entry point to an application - context and audit.
+ * The order of invocations is important, assuming the context must be kept as long as audit hasn't been finished.
+ *
+ * @author evitaliy
+ * @since 01 Aug 2018
+ */
+public class CombinedTracker implements Tracker {
+
+ private final ContextTracker context;
+ private final AuditTracker audit;
+
+ public CombinedTracker(Logger logger, HttpHeader partnerNameHeader, HttpHeader requestIdHeader) {
+ this.context = new ContextTracker(partnerNameHeader, requestIdHeader);
+ this.audit = new AuditTracker(logger);
+ }
+
+ public CombinedTracker(Class<?> resourceType, HttpHeader partnerNameHeader, HttpHeader requestIdHeader) {
+ this.context = new ContextTracker(partnerNameHeader, requestIdHeader);
+ this.audit = new AuditTracker(resourceType);
+ }
+
+ @Override
+ public void preRequest(HttpServletRequest request) {
+ this.context.preRequest(request);
+ this.audit.preRequest(request);
+ }
+
+ @Override
+ public void postRequest(RequestProcessingResult result) {
+ this.audit.postRequest(result);
+ this.context.postRequest(result);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ContextTracker.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ContextTracker.java
new file mode 100644
index 0000000000..2334f373bc
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ContextTracker.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import java.util.Objects;
+import java.util.UUID;
+import javax.servlet.http.HttpServletRequest;
+import org.openecomp.sdc.logging.api.ContextData;
+import org.openecomp.sdc.logging.api.LoggingContext;
+
+/**
+ * Populates the context before a request is processed, and cleans it after the request has been processed.
+ *
+ * @author evitaliy
+ * @since 31 Jul 2018
+ */
+public class ContextTracker implements Tracker {
+
+ private final HttpHeader partnerNameHeaders;
+ private final HttpHeader requestIdHeaders;
+
+ /**
+ * Constructs tracker to handle required logging context in Servlet-based applications. Refer to ONAP logging
+ * guidelines for fields required to be put on logging context.
+ *
+ * @param partnerNameHeaders HTTP headers to check for a partner name, cannot be null
+ * @param requestIdHeaders HTTP headers to check for a request ID, cannot be null
+ */
+ public ContextTracker(HttpHeader partnerNameHeaders, HttpHeader requestIdHeaders) {
+ this.partnerNameHeaders = Objects.requireNonNull(partnerNameHeaders);
+ this.requestIdHeaders = Objects.requireNonNull(requestIdHeaders);
+ }
+
+ @Override
+ public void preRequest(HttpServletRequest request) {
+
+ LoggingContext.clear();
+
+ String serviceName = ServiceNameFormatter.format(request);
+ String requestId = requestIdHeaders.getAny(request::getHeader).orElse(UUID.randomUUID().toString());
+ ContextData.ContextDataBuilder contextBuilder =
+ ContextData.builder().serviceName(serviceName).requestId(requestId);
+
+ partnerNameHeaders.getAny(request::getHeader).ifPresent(contextBuilder::partnerName);
+ LoggingContext.put(contextBuilder.build());
+ }
+
+ @Override
+ public void postRequest(RequestProcessingResult result) {
+ LoggingContext.clear();
+ }
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/HttpHeader.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/HttpHeader.java
index 4dcc197796..db10c2e4f3 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/HttpHeader.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/HttpHeader.java
@@ -16,6 +16,11 @@
package org.openecomp.sdc.logging.servlet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
import java.util.function.Function;
/**
@@ -28,28 +33,80 @@ import java.util.function.Function;
*/
public class HttpHeader {
- private final String[] keys;
+ private static final String NAMES_CANNOT_BE_NULL = "Names cannot be null";
+ private static final String AT_LEAST_ONE_NAME_REQUIRED = "At least one name required";
- public HttpHeader(String... keys) {
- this.keys = keys;
+ private final List<String> headerNames;
+
+ /**
+ * Receives a list of accepted header names as a String array.
+ *
+ * @param headerNames cannot be null or empty
+ */
+ public HttpHeader(String[] headerNames) {
+
+ if (Objects.requireNonNull(headerNames, NAMES_CANNOT_BE_NULL).length < 1) {
+ throw new IllegalArgumentException(AT_LEAST_ONE_NAME_REQUIRED);
+ }
+
+ this.headerNames = Arrays.asList(headerNames);
+ }
+
+ /**
+ * Receives a list of accepted header names as a list of String.
+ *
+ * @param headerNames cannot be null or empty
+ */
+ public HttpHeader(List<String> headerNames) {
+
+ if (Objects.requireNonNull(headerNames, NAMES_CANNOT_BE_NULL).isEmpty()) {
+ throw new IllegalArgumentException(AT_LEAST_ONE_NAME_REQUIRED);
+ }
+
+ this.headerNames = new ArrayList<>(headerNames);
}
/**
* Returns the value of any of the possible headers.
*
* @param reader function for reading an HTTP header.
- * @return value or null if not found
+ * @return value or empty if not found
*/
- public String getAny(Function<String, String> reader) {
+ public Optional<String> getAny(Function<String, String> reader) {
- for (String k : keys) {
+ for (String k : headerNames) {
String value = reader.apply(k);
if (value != null) {
- return value;
+ return Optional.of(value);
}
}
- return null;
+ return Optional.empty();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (this == o) {
+ return true;
+ }
+
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ HttpHeader that = (HttpHeader) o;
+ return Objects.equals(headerNames, that.headerNames);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(headerNames);
+ }
+
+ @Override
+ public String toString() {
+ return "HttpHeader{headerNames=" + headerNames + '}';
}
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/LoggingFilter.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/LoggingFilter.java
deleted file mode 100644
index e53f28119c..0000000000
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/LoggingFilter.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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;
-
-import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_PARTNER_NAME_HEADER;
-import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_REQUEST_ID_HEADER;
-
-import java.io.IOException;
-import java.util.UUID;
-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 org.openecomp.sdc.logging.api.ContextData;
-import org.openecomp.sdc.logging.api.Logger;
-import org.openecomp.sdc.logging.api.LoggerFactory;
-import org.openecomp.sdc.logging.api.LoggingContext;
-import org.openecomp.sdc.logging.servlet.jaxrs.LoggingRequestFilter;
-import org.openecomp.sdc.logging.servlet.jaxrs.LoggingResponseFilter;
-
-/**
- * <p>Places logging context information. Must be configured as a servlet filter in <i>web.xml</i>. The behavior can be
- * customized via init-params.</p>
- * <p>Example:</p>
- * <pre>
- *
- * &lt;filter&gt;
- * &lt;filter-name&gt;LoggingServletFilter&lt;/filter-name&gt;
- * &lt;filter-class&gt;org.openecomp.sdc.logging.servlet.LoggingFilter&lt;/filter-class&gt;
- * &lt;init-param&gt;
- * &lt;param-name&gt;requestIdHeaders&lt;/param-name&gt;
- * &lt;param-value&gt;X-ONAP-RequestID&lt;/param-value&gt;
- * &lt;/init-param&gt;
- * &lt;init-param&gt;
- * &lt;param-name&gt;partnerNameHeaders&lt;/param-name&gt;
- * &lt;param-value&gt;USER_ID&lt;/param-value&gt;
- * &lt;/init-param&gt;
- * &lt;/filter&gt;
- *
- * &lt;filter-mapping&gt;
- * &lt;filter-name&gt;LoggingServletFilter&lt;/filter-name&gt;
- * &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
- * &lt;/filter-mapping&gt;
- *
- * </pre>
- *
- * @author evitaliy
- * @since 25 Jul 2016
- * @deprecated Kept for backward compatibility. For JAX-RS application, use
- * {@link LoggingRequestFilter} and
- * {@link LoggingResponseFilter} instead.
- */
-@Deprecated
-public class LoggingFilter implements Filter {
-
- static final String MULTI_VALUE_SEPARATOR = ",";
-
- static final String REQUEST_ID_HEADERS_PARAM = "requestIdHeaders";
- static final String PARTNER_NAME_HEADERS_PARAM = "partnerNameHeaders";
-
- private static final Logger LOGGER = LoggerFactory.getLogger(LoggingFilter.class);
-
- private HttpHeader requestIdHeaders;
- private HttpHeader partnerNameHeaders;
-
- @Override
- public void init(FilterConfig config) {
- requestIdHeaders = getInitParam(config, REQUEST_ID_HEADERS_PARAM, DEFAULT_REQUEST_ID_HEADER);
- partnerNameHeaders = getInitParam(config, PARTNER_NAME_HEADERS_PARAM, DEFAULT_PARTNER_NAME_HEADER);
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
-
- HttpServletRequest httpRequest = HttpServletRequest.class.cast(request);
-
- try {
-
- LoggingContext.clear();
-
- ContextData.ContextDataBuilder contextData = ContextData.builder();
-
- contextData.serviceName(httpRequest.getRequestURI());
-
- String requestId = requestIdHeaders.getAny(httpRequest::getHeader);
- contextData.requestId(requestId == null ? UUID.randomUUID().toString() : requestId);
-
- String partner = partnerNameHeaders.getAny(httpRequest::getHeader);
- if (partner != null) {
- contextData.partnerName(partner);
- }
-
- LoggingContext.put(contextData.build());
-
- chain.doFilter(request, response);
-
- } finally {
- LoggingContext.clear();
- }
- }
-
- @Override
- public void destroy() {
- // forced by the interface - not implemented
- }
-
- private HttpHeader getInitParam(FilterConfig config, String paramName, String defaultValue) {
-
- String value = config.getInitParameter(paramName);
- LOGGER.debug("Logging filter configuration param '{}' value '{}'", paramName, value);
-
- if (value == null) {
- return new HttpHeader(defaultValue);
- } else {
- return new HttpHeader(value.split(MULTI_VALUE_SEPARATOR));
- }
- }
-}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/RequestProcessingResult.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/RequestProcessingResult.java
new file mode 100644
index 0000000000..d3625ed303
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/RequestProcessingResult.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import org.openecomp.sdc.logging.api.StatusCode;
+
+/**
+ * Interpretation of request processing results.
+ *
+ * @author evitaliy
+ * @since 02 Aug 2018
+ */
+public interface RequestProcessingResult {
+
+ /**
+ * Numeric status code.
+ *
+ * @return usually HTTP response status.
+ */
+ int getStatus();
+
+ /**
+ * Whether the response is considered success or failure.
+ *
+ * @return on of pre-defined status codes
+ */
+ StatusCode getStatusCode();
+
+ /**
+ * Human-friendly description of the numeric status.
+ *
+ * @return usually HTTP reason phrase
+ */
+ String getStatusPhrase();
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ServiceNameFormatter.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ServiceNameFormatter.java
new file mode 100644
index 0000000000..f65490bf18
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/ServiceNameFormatter.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Formats a service name based on HTTP method and request URI.
+ *
+ * @author evitaliy
+ * @since 01 Aug 2018
+ */
+class ServiceNameFormatter {
+
+ private ServiceNameFormatter() {
+ // utility class, prevent instantiation
+ }
+
+ public static String format(HttpServletRequest request) {
+ return request.getMethod() + ": " + request.getRequestURI();
+ }
+} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/Tracker.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/Tracker.java
new file mode 100644
index 0000000000..c0337cfb4d
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/Tracker.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Tracks logging and tracing information through the processing of an HTTP request.
+ *
+ * @author evitaliy
+ * @since 31 Jul 2018
+ */
+public interface Tracker {
+
+ /**
+ * Will be executed before request processing has started.
+ *
+ * @param request provided by every Servlet container
+ */
+ void preRequest(HttpServletRequest request);
+
+ /**
+ * Will be executed after a request has been processed. Results may be treated differently depending on a container
+ * and application. For instance, JAX-RS applications may take into account exception mappers before generating a
+ * response; some applications may Swagger annotations to map a response status to a human-friendly message, etc.
+ *
+ * @param result application- and container-specific request results
+ */
+ void postRequest(RequestProcessingResult result);
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilter.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilter.java
index 0e1b7d715b..f846359b82 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilter.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilter.java
@@ -19,25 +19,24 @@ package org.openecomp.sdc.logging.servlet.jaxrs;
import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_PARTNER_NAME_HEADER;
import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_REQUEST_ID_HEADER;
-import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
-import org.openecomp.sdc.logging.api.ContextData;
import org.openecomp.sdc.logging.api.Logger;
import org.openecomp.sdc.logging.api.LoggerFactory;
-import org.openecomp.sdc.logging.api.LoggingContext;
+import org.openecomp.sdc.logging.servlet.CombinedTracker;
import org.openecomp.sdc.logging.servlet.HttpHeader;
+import org.openecomp.sdc.logging.servlet.Tracker;
/**
* <p>Takes care of logging initialization an HTTP request hits the application. This includes populating logging
- * context and storing the request processing start time, so that it can be used for audit. The filter was built
- * <b>works in tandem</b> with {@link LoggingResponseFilter} or a similar implementation.</p>
+ * context and tracking the request for audit. The filter <b>works in tandem</b> with {@link LoggingResponseFilter} or
+ * a similar implementation.</p>
* <p>The filter requires a few HTTP header names to be configured. These HTTP headers are used for propagating logging
- * and tracing information between ONAP components.</p>
- * <p>Sample configuration for a Spring environment:</p>
+ * and tracing information between ONAP components. Sample configuration for a Spring environment:</p>
* <pre>
* &lt;jaxrs:providers&gt;
* &lt;bean class="org.openecomp.sdc.logging.ws.rs.LoggingRequestFilter"&gt;
@@ -51,40 +50,42 @@ import org.openecomp.sdc.logging.servlet.HttpHeader;
* </p>
*
* @author evitaliy, katyr
- * @since 29 Oct 17
- *
* @see ContainerRequestFilter
+ * @since 29 Oct 17
*/
@Provider
public class LoggingRequestFilter implements ContainerRequestFilter {
- static final String MULTI_VALUE_SEPARATOR = ",";
-
- static final String START_TIME_KEY = "audit.start.time";
+ static final String LOGGING_TRACKER_KEY = "onap.logging.tracker";
+ private static final String MULTI_VALUE_SEPARATOR = ",";
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRequestFilter.class);
private HttpServletRequest httpRequest;
- private HttpHeader requestIdHeader = new HttpHeader(DEFAULT_REQUEST_ID_HEADER);
- private HttpHeader partnerNameHeader = new HttpHeader(DEFAULT_PARTNER_NAME_HEADER);
- private boolean includeHttpMethod = true;
+ private HttpHeader requestIdHeader = new HttpHeader(new String[] {DEFAULT_REQUEST_ID_HEADER});
+ private HttpHeader partnerNameHeader = new HttpHeader(new String[] {DEFAULT_PARTNER_NAME_HEADER});
+
+ private ResourceInfo resource;
/**
- * Injection of HTTP request object from JAX-RS context.
+ * Injection of a resource that matches the request from JAX-RS context.
*
- * @param httpRequest automatically injected by JAX-RS container
+ * @param resource automatically injected by JAX-RS container
*/
@Context
- public void setHttpRequest(HttpServletRequest httpRequest) {
- this.httpRequest = httpRequest;
+ public void setResource(ResourceInfo resource) {
+ this.resource = resource;
}
/**
- * Configuration parameter to include the HTTP method of a request in service name.
+ * Injection of HTTP request object from JAX-RS context.
+ *
+ * @param httpRequest automatically injected by JAX-RS container
*/
- public void setHttpMethodInServiceName(boolean includeHttpMethod) {
- this.includeHttpMethod = includeHttpMethod;
+ @Context
+ public void setHttpRequest(HttpServletRequest httpRequest) {
+ this.httpRequest = httpRequest;
}
/**
@@ -104,33 +105,10 @@ public class LoggingRequestFilter implements ContainerRequestFilter {
}
@Override
- public void filter(ContainerRequestContext containerRequestContext) {
-
- LoggingContext.clear();
-
- containerRequestContext.setProperty(START_TIME_KEY, System.currentTimeMillis());
-
- ContextData.ContextDataBuilder contextData = ContextData.builder();
- contextData.serviceName(getServiceName());
-
- String partnerName = partnerNameHeader.getAny(containerRequestContext::getHeaderString);
- if (partnerName != null) {
- contextData.partnerName(partnerName);
- }
-
- String requestId = requestIdHeader.getAny(containerRequestContext::getHeaderString);
- contextData.requestId(requestId == null ? UUID.randomUUID().toString() : requestId);
-
- LoggingContext.put(contextData.build());
- }
-
- private String getServiceName() {
- return includeHttpMethod
- ? formatServiceName(this.httpRequest.getMethod(), this.httpRequest.getRequestURI())
- : this.httpRequest.getRequestURI();
- }
-
- static String formatServiceName(String httpMethod, String requestUri) {
- return httpMethod + " " + requestUri;
+ public void filter(ContainerRequestContext requestContext) {
+ Class<?> resourceClass = resource.getResourceMethod().getDeclaringClass();
+ Tracker tracker = new CombinedTracker(resourceClass, partnerNameHeader, requestIdHeader);
+ requestContext.setProperty(LOGGING_TRACKER_KEY, tracker);
+ tracker.preRequest(httpRequest);
}
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilter.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilter.java
index 4609620be1..fa9e815db8 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilter.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilter.java
@@ -16,19 +16,22 @@
package org.openecomp.sdc.logging.servlet.jaxrs;
-import org.openecomp.sdc.logging.api.*;
+import static javax.ws.rs.core.Response.Status.Family.REDIRECTION;
+import static javax.ws.rs.core.Response.Status.Family.SUCCESSFUL;
+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.jaxrs.LoggingRequestFilter.LOGGING_TRACKER_KEY;
-import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
-import javax.ws.rs.container.ResourceInfo;
-import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
-
-import static org.openecomp.sdc.logging.api.StatusCode.COMPLETE;
-import static org.openecomp.sdc.logging.api.StatusCode.ERROR;
+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.RequestProcessingResult;
+import org.openecomp.sdc.logging.servlet.Tracker;
/**
* <p>Takes care of logging when an HTTP request leaves the application. This includes writing to audit and clearing
@@ -44,123 +47,49 @@ import static org.openecomp.sdc.logging.api.StatusCode.ERROR;
* due to unhandled application or container exceptions.</i></p>
*
* @author evitaliy
- * @since 29 Oct 17
- *
* @see ContainerResponseFilter
+ * @since 29 Oct 17
*/
@Provider
public class LoggingResponseFilter implements ContainerResponseFilter {
- private static final int UNKNOWN_START_TIME = 0;
-
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingResponseFilter.class);
- /**
- * Tracks reporting configuration problems to the log. We want to report them only once, and not to write to log
- * upon every request, as the configuration will not change in runtime.
- */
- private boolean reportBadConfiguration = true;
-
- private HttpServletRequest httpRequest;
-
- private ResourceInfo resource;
-
- /**
- * Injection of HTTP request object from JAX-RS context.
- *
- * @param httpRequest automatically injected by JAX-RS container
- */
- @Context
- public void setHttpRequest(HttpServletRequest httpRequest) {
- this.httpRequest = httpRequest;
- }
-
- /**
- * Injection of a resource that matches the request from JAX-RS context.
- *
- * @param resource automatically injected by JAX-RS container
- */
- @Context
- public void setResource(ResourceInfo resource) {
- this.resource = resource;
- }
-
@Override
- public void filter(ContainerRequestContext containerRequestContext,
- ContainerResponseContext containerResponseContext) {
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
- try {
+ Tracker tracker = (Tracker) requestContext.getProperty(LOGGING_TRACKER_KEY);
- if ((resource == null) || (resource.getResourceClass() == null)) {
- LOGGER.debug("No matching resource, skipping audit.");
- return;
- }
-
- writeAudit(containerRequestContext, containerResponseContext);
-
- } finally {
- LoggingContext.clear();
- }
- }
-
- private void writeAudit(ContainerRequestContext containerRequestContext,
- ContainerResponseContext containerResponseContext) {
-
- Logger resourceLogger = LoggerFactory.getLogger(resource.getResourceMethod().getDeclaringClass());
- if (!resourceLogger.isAuditEnabled()) {
+ if (tracker == null) {
+ LOGGER.debug("No logging tracker received");
return;
}
- long start = readStartTime(containerRequestContext);
- long end = System.currentTimeMillis();
-
- Response.StatusType statusInfo = containerResponseContext.getStatusInfo();
- int responseCode = statusInfo.getStatusCode();
- StatusCode statusCode = isSuccess(responseCode) ? COMPLETE : ERROR;
-
- AuditData auditData = AuditData.builder().startTime(start).endTime(end).statusCode(statusCode)
- .responseCode(Integer.toString(responseCode))
- .responseDescription(statusInfo.getReasonPhrase())
- .clientIpAddress(httpRequest.getRemoteAddr()).build();
- resourceLogger.audit(auditData);
+ tracker.postRequest(new ContainerResponseResult(responseContext.getStatusInfo()));
}
- private boolean isSuccess(int responseCode) {
- return responseCode > 199 && responseCode < 400;
- }
+ private static class ContainerResponseResult implements RequestProcessingResult {
- private long readStartTime(ContainerRequestContext containerRequestContext) {
+ private final Response.StatusType statusInfo;
- Object startTime = containerRequestContext.getProperty(LoggingRequestFilter.START_TIME_KEY);
- if (startTime == null) {
- return handleMissingStartTime();
+ private ContainerResponseResult(Response.StatusType statusInfo) {
+ this.statusInfo = statusInfo;
}
- return parseStartTime(startTime);
- }
-
- private long handleMissingStartTime() {
- reportConfigProblem("{} key was not found in JAX-RS request context. "
- + "Make sure you configured a request filter", LoggingRequestFilter.START_TIME_KEY);
- return UNKNOWN_START_TIME;
- }
-
- private long parseStartTime(Object startTime) {
-
- try {
- return Long.class.cast(startTime);
- } catch (ClassCastException e) {
- reportConfigProblem("{} key in JAX-RS request context contains an object of type '{}', but 'java.lang.Long'"
- + " is expected", LoggingRequestFilter.START_TIME_KEY, startTime.getClass().getName(), e);
- return 0;
+ @Override
+ public int getStatus() {
+ return statusInfo.getStatusCode();
}
- }
- private void reportConfigProblem(String message, Object... arguments) {
+ @Override
+ public StatusCode getStatusCode() {
+ Response.Status.Family family = statusInfo.getFamily();
+ return family.equals(SUCCESSFUL) || family.equals(REDIRECTION) ? COMPLETE : ERROR;
+ }
- if (reportBadConfiguration) {
- reportBadConfiguration = false;
- LOGGER.error(message, arguments);
+ @Override
+ public String getStatusPhrase() {
+ return statusInfo.getReasonPhrase();
}
}
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggerCreationService.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggerCreationService.java
index 90aebfa221..54b5be3a27 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggerCreationService.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggerCreationService.java
@@ -20,7 +20,6 @@ import org.openecomp.sdc.logging.api.Logger;
import org.openecomp.sdc.logging.api.LoggerFactory;
/**
- *
* Implements a framework-specific logging, to be used by {@link LoggerFactory}.
*
* @author evitaliy
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggingContextService.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggingContextService.java
index 7c71465846..37e212ac54 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggingContextService.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/spi/LoggingContextService.java
@@ -16,9 +16,8 @@
package org.openecomp.sdc.logging.spi;
-import org.openecomp.sdc.logging.api.ContextData;
-
import java.util.concurrent.Callable;
+import org.openecomp.sdc.logging.api.ContextData;
/**
* Should be used to implement a framework-specific mechanism of managing a per-thread diagnostic context (for instance