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>
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/pom.xml b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/pom.xml
index 29efa61..2bd26ed 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/pom.xml
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/pom.xml
@@ -34,29 +34,17 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <version>${easymock.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-api-easymock</artifactId>
- <version>${powermock.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-core</artifactId>
- <version>${powermock.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito2</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
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 30517cd..96debb5 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 9526713..894dd2c 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 5aaa301..6e5b3e3 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 @@
// 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 0000000..af9b506
--- /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 0000000..2dd2c12
--- /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 0000000..2334f37
--- /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 4dcc197..db10c2e 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 @@
*/
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 e53f281..0000000
--- 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>
- *
- * <filter>
- * <filter-name>LoggingServletFilter</filter-name>
- * <filter-class>org.openecomp.sdc.logging.servlet.LoggingFilter</filter-class>
- * <init-param>
- * <param-name>requestIdHeaders</param-name>
- * <param-value>X-ONAP-RequestID</param-value>
- * </init-param>
- * <init-param>
- * <param-name>partnerNameHeaders</param-name>
- * <param-value>USER_ID</param-value>
- * </init-param>
- * </filter>
- *
- * <filter-mapping>
- * <filter-name>LoggingServletFilter</filter-name>
- * <url-pattern>/*</url-pattern>
- * </filter-mapping>
- *
- * </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 0000000..d3625ed
--- /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 0000000..f65490b
--- /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 0000000..c0337cf
--- /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 0e1b7d7..f846359 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 @@
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>
* <jaxrs:providers>
* <bean class="org.openecomp.sdc.logging.ws.rs.LoggingRequestFilter">
@@ -51,24 +50,33 @@
* </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 LOGGING_TRACKER_KEY = "onap.logging.tracker";
- static final String START_TIME_KEY = "audit.start.time";
-
+ 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 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;
+ }
/**
* Injection of HTTP request object from JAX-RS context.
@@ -81,13 +89,6 @@
}
/**
- * Configuration parameter to include the HTTP method of a request in service name.
- */
- public void setHttpMethodInServiceName(boolean includeHttpMethod) {
- this.includeHttpMethod = includeHttpMethod;
- }
-
- /**
* Configuration parameter for request ID HTTP header.
*/
public void setRequestIdHeaders(String requestIdHeaders) {
@@ -104,33 +105,10 @@
}
@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 4609620..fa9e815 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 @@
* 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 90aebfa..54b5be3 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.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 7c71465..37e212a 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
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/AuditTrackerTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/AuditTrackerTest.java
new file mode 100644
index 0000000..1bd13a9
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/AuditTrackerTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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 junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.openecomp.sdc.logging.api.AuditData;
+import org.openecomp.sdc.logging.api.Logger;
+import org.openecomp.sdc.logging.api.StatusCode;
+
+/**
+ * Test initialization and of audit tracker and log invocation.
+ *
+ * @author evitaliy
+ * @since 01 Aug 2018
+ */
+public class AuditTrackerTest {
+
+ @Test(expected = NullPointerException.class)
+ public void throwExceptionWhenLoggerNull() {
+ new AuditTracker((Logger) null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void throwExceptionWhenResourceTypeNull() {
+ new AuditTracker((Class<?>) null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void throwExceptionWhenPreRequestCalledMoreThanOnce() {
+ AuditTracker tracker = new AuditTracker(mock(Logger.class));
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ tracker.preRequest(request);
+ tracker.preRequest(request);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void throwExceptionWhenRreRequestNeverCalled() {
+ AuditTracker tracker = new AuditTracker(mock(Logger.class));
+ tracker.postRequest(mock(RequestProcessingResult.class));
+ }
+
+ @Test
+ public void nothingHappensWhenAuditDisabled() {
+
+ Logger logger = mock(Logger.class);
+ when(logger.isAuditEnabled()).thenReturn(false);
+
+ AuditTracker tracker = new AuditTracker(logger);
+ tracker.preRequest(mock(HttpServletRequest.class));
+ tracker.postRequest(mock(RequestProcessingResult.class));
+
+ verify(logger, never()).audit(any(AuditData.class));
+ }
+
+ @Test
+ public void reportedTimePositive() {
+
+ Logger logger = mock(Logger.class);
+ when(logger.isAuditEnabled()).thenReturn(true);
+
+ AuditTracker tracker = new AuditTracker(logger);
+ tracker.preRequest(mock(HttpServletRequest.class));
+ tracker.postRequest(mock(RequestProcessingResult.class));
+
+ ArgumentCaptor<AuditData> auditDataCaptor = ArgumentCaptor.forClass(AuditData.class);
+ verify(logger).audit(auditDataCaptor.capture());
+ assertTrue(auditDataCaptor.getValue().getEndTime() > 0);
+ }
+
+ @Test
+ public void interpretedRequestResultsPassedDownToAudit() {
+
+ Logger logger = mock(Logger.class);
+ when(logger.isAuditEnabled()).thenReturn(true);
+
+ AuditTracker tracker = new AuditTracker(logger);
+ tracker.preRequest(mock(HttpServletRequest.class));
+
+ final StubRequestProcessingResult result = new StubRequestProcessingResult();
+ tracker.postRequest(result);
+
+ ArgumentCaptor<AuditData> auditDataCaptor = ArgumentCaptor.forClass(AuditData.class);
+ verify(logger).audit(auditDataCaptor.capture());
+
+ AuditData capturedAuditData = auditDataCaptor.getValue();
+ assertEquals(Integer.toString(result.getStatus()), capturedAuditData.getResponseCode());
+ assertEquals(result.getStatusCode(), capturedAuditData.getStatusCode());
+ assertEquals(result.getStatusPhrase(), capturedAuditData.getResponseDescription());
+ }
+
+ @Test
+ public void clientIpAddressPassedDownToAudit() {
+
+ Logger logger = mock(Logger.class);
+ when(logger.isAuditEnabled()).thenReturn(true);
+
+ final String address = "196.50.30.122";
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getRemoteAddr()).thenReturn(address);
+
+ AuditTracker tracker = new AuditTracker(logger);
+ tracker.preRequest(request);
+ tracker.postRequest(mock(RequestProcessingResult.class));
+
+ ArgumentCaptor<AuditData> auditDataCaptor = ArgumentCaptor.forClass(AuditData.class);
+ verify(logger).audit(auditDataCaptor.capture());
+
+ AuditData capturedAuditData = auditDataCaptor.getValue();
+ assertEquals(address, capturedAuditData.getClientIpAddress());
+ }
+
+ private static class StubRequestProcessingResult implements RequestProcessingResult {
+
+ @Override
+ public int getStatus() {
+ return 505;
+ }
+
+ @Override
+ public StatusCode getStatusCode() {
+ return StatusCode.ERROR;
+ }
+
+ @Override
+ public String getStatusPhrase() {
+ return "Test request failed";
+ }
+ }
+}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/ContextTrackerTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/ContextTrackerTest.java
new file mode 100644
index 0000000..a247d11
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/ContextTrackerTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.powermock.api.mockito.PowerMockito.mock;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.verifyStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.openecomp.sdc.logging.api.ContextData;
+import org.openecomp.sdc.logging.api.LoggingContext;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * Populating context from request data.
+ *
+ * @author evitaliy
+ * @since 01 Aug 2018
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(LoggingContext.class)
+public class ContextTrackerTest {
+
+ private static final String X_REQUEST_ID = "X-REQUEST-ID";
+ private static final HttpHeader REQUEST_ID_HEADER = new HttpHeader(new String[] {X_REQUEST_ID});
+
+ private static final String X_PARTNER_NAME = "X-PARTNER-NAME";
+ private static final HttpHeader PARTNER_NAME_HEADER = new HttpHeader(new String[] {X_PARTNER_NAME});
+
+ @Test(expected = NullPointerException.class)
+ public void throwExceptionWhenPartnerNamesNull() {
+ new ContextTracker(null, REQUEST_ID_HEADER);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void throwExceptionWhenRequestIdsNull() {
+ new ContextTracker(PARTNER_NAME_HEADER, null);
+ }
+
+ @Test
+ public void requestIdCopiedWhenGiven() {
+
+ mockStatic(LoggingContext.class);
+
+ final String requestId = "request-id-for-unit-testing";
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getHeader(X_REQUEST_ID)).thenReturn(requestId);
+
+ ContextTracker tracker = new ContextTracker(PARTNER_NAME_HEADER, REQUEST_ID_HEADER);
+ tracker.preRequest(request);
+
+ ArgumentCaptor<ContextData> contextDataCaptor = ArgumentCaptor.forClass(ContextData.class);
+ verifyStatic(LoggingContext.class);
+
+ LoggingContext.put(contextDataCaptor.capture());
+
+ assertEquals(requestId, contextDataCaptor.getValue().getRequestId());
+ }
+
+ @Test
+ public void requestIdGeneratedWhenNotGiven() {
+
+ mockStatic(LoggingContext.class);
+
+ ContextTracker tracker = new ContextTracker(PARTNER_NAME_HEADER, REQUEST_ID_HEADER);
+ tracker.preRequest(mock(HttpServletRequest.class));
+
+ ArgumentCaptor<ContextData> contextDataCaptor = ArgumentCaptor.forClass(ContextData.class);
+ verifyStatic(LoggingContext.class);
+
+ LoggingContext.put(contextDataCaptor.capture());
+
+ String requestId = contextDataCaptor.getValue().getRequestId();
+ assertNotNull(requestId);
+ assertFalse(requestId.isEmpty());
+ }
+
+ @Test
+ public void partnerNameCopiedWhenGiven() {
+
+ mockStatic(LoggingContext.class);
+
+ final String partner = "partner-name-for-unit-testing";
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getHeader(X_PARTNER_NAME)).thenReturn(partner);
+
+ ContextTracker tracker = new ContextTracker(PARTNER_NAME_HEADER, REQUEST_ID_HEADER);
+ tracker.preRequest(request);
+
+ ArgumentCaptor<ContextData> contextDataCaptor = ArgumentCaptor.forClass(ContextData.class);
+ verifyStatic(LoggingContext.class);
+
+ LoggingContext.put(contextDataCaptor.capture());
+
+ assertEquals(partner, contextDataCaptor.getValue().getPartnerName());
+ }
+
+ @Test
+ public void partnerNameAbsentWhenNotGiven() {
+
+ mockStatic(LoggingContext.class);
+
+ ContextTracker tracker = new ContextTracker(PARTNER_NAME_HEADER, REQUEST_ID_HEADER);
+ tracker.preRequest(mock(HttpServletRequest.class));
+
+ ArgumentCaptor<ContextData> contextDataCaptor = ArgumentCaptor.forClass(ContextData.class);
+ verifyStatic(LoggingContext.class);
+
+ LoggingContext.put(contextDataCaptor.capture());
+
+ assertNull(contextDataCaptor.getValue().getPartnerName());
+ }
+
+ @Test
+ public void serviceNameGenerated() {
+
+ mockStatic(LoggingContext.class);
+
+ ContextTracker tracker = new ContextTracker(PARTNER_NAME_HEADER, REQUEST_ID_HEADER);
+ tracker.preRequest(mock(HttpServletRequest.class));
+
+ ArgumentCaptor<ContextData> contextDataCaptor = ArgumentCaptor.forClass(ContextData.class);
+ verifyStatic(LoggingContext.class);
+
+ LoggingContext.put(contextDataCaptor.capture());
+
+ assertNotNull(contextDataCaptor.getValue().getServiceName());
+ }
+
+ @Test
+ public void contextClearedWhenRequestFinished() {
+
+ mockStatic(LoggingContext.class);
+
+ ContextTracker tracker = new ContextTracker(PARTNER_NAME_HEADER, REQUEST_ID_HEADER);
+ tracker.postRequest(mock(RequestProcessingResult.class));
+
+ verifyStatic(LoggingContext.class);
+ LoggingContext.clear();
+ }
+}
+
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/HttpHeaderTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/HttpHeaderTest.java
new file mode 100644
index 0000000..5cbd0c0
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/HttpHeaderTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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 junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import org.junit.Test;
+
+/**
+ * Unit tests multiple-option headers.
+ *
+ * @author evitaliy
+ * @since 31 Jul 2018
+ */
+public class HttpHeaderTest {
+
+ private static final Supplier<? extends Throwable> VALUE_EXPECTED = () -> new AssertionError("Value expected");
+ private static final Function<String, String> NULL_WHEN_NAME_NOT_B = k -> "B".equals(k) ? "Value" : null;
+
+ @Test(expected = NullPointerException.class)
+ public void throwExceptionWhenInputArrayNull() {
+ new HttpHeader((String[]) null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void throwExceptionWhenInputListNull() {
+ new HttpHeader((List<String>) null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void throwExceptionWhenInputArrayEmpty() {
+ new HttpHeader(new String[0]);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void throwExceptionWhenInputListEmpty() {
+ new HttpHeader(Collections.emptyList());
+ }
+
+ @Test
+ public void valueNotReturnedWhenNameInArrayNotRequested() {
+ HttpHeader header = new HttpHeader(new String[] {"A"});
+ assertFalse(header.getAny(NULL_WHEN_NAME_NOT_B).isPresent());
+ }
+
+ @Test
+ public void valueNotReturnedWhenNameInListNotRequested() {
+ HttpHeader header = new HttpHeader(Collections.singletonList("A"));
+ assertFalse(header.getAny(NULL_WHEN_NAME_NOT_B).isPresent());
+ }
+
+ @Test
+ public void valueReturnedWhenSinglePossibleHeaderInArrayMatches() {
+ HttpHeader header = new HttpHeader(new String[] {"B"});
+ assertTrue(header.getAny(NULL_WHEN_NAME_NOT_B).isPresent());
+ }
+
+ @Test
+ public void valueReturnedWhenSinglePossibleHeaderInListMatches() {
+ HttpHeader header = new HttpHeader(Collections.singletonList("B"));
+ assertTrue(header.getAny(NULL_WHEN_NAME_NOT_B).isPresent());
+ }
+
+ @Test
+ public void valueReturnedWhenLastHeaderInArrayMatches() throws Throwable {
+ HttpHeader header = new HttpHeader(new String[] {"A", "B"});
+ header.getAny(NULL_WHEN_NAME_NOT_B).orElseThrow(VALUE_EXPECTED);
+ }
+
+ @Test
+ public void valueReturnedWhenLastHeaderInListMatches() throws Throwable {
+ HttpHeader header = new HttpHeader(Arrays.asList("A", "B"));
+ header.getAny(NULL_WHEN_NAME_NOT_B).orElseThrow(VALUE_EXPECTED);
+ }
+
+ @Test
+ public void valueReturnedWhenFirstHeaderInArrayMatches() throws Throwable {
+ HttpHeader header = new HttpHeader(new String[] {"B", "A"});
+ header.getAny(NULL_WHEN_NAME_NOT_B).orElseThrow(VALUE_EXPECTED);
+ }
+
+ @Test
+ public void valueReturnedWhenFirstHeaderInListMatches() throws Throwable {
+ HttpHeader header = new HttpHeader(Arrays.asList("B", "A"));
+ header.getAny(NULL_WHEN_NAME_NOT_B).orElseThrow(VALUE_EXPECTED);
+ }
+
+ @Test
+ public void valueReturnedWhenMiddleHeaderInArrayMatches() throws Throwable {
+ HttpHeader header = new HttpHeader(new String[] {"A", "B", "C"});
+ header.getAny(NULL_WHEN_NAME_NOT_B).orElseThrow(VALUE_EXPECTED);
+ }
+
+ @Test
+ public void valueReturnedWhenMiddleHeaderInListMatches() throws Throwable {
+ HttpHeader header = new HttpHeader(Arrays.asList("A", "B", "C"));
+ header.getAny(NULL_WHEN_NAME_NOT_B).orElseThrow(VALUE_EXPECTED);
+ }
+}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/LoggingFilterTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/LoggingFilterTest.java
deleted file mode 100644
index 1ba418f..0000000
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/LoggingFilterTest.java
+++ /dev/null
@@ -1,206 +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 org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.openecomp.sdc.logging.api.ContextData;
-import org.openecomp.sdc.logging.api.LoggingContext;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.UUID;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_PARTNER_NAME_HEADER;
-import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_REQUEST_ID_HEADER;
-import static org.openecomp.sdc.logging.servlet.LoggingFilter.PARTNER_NAME_HEADERS_PARAM;
-import static org.openecomp.sdc.logging.servlet.LoggingFilter.REQUEST_ID_HEADERS_PARAM;
-
-/**
- * Unit-tests logging filter for initialization and data retrieval.
- *
- * @author evitaliy
- * @since 17 Aug 2016
- */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(LoggingContext.class)
-public class LoggingFilterTest {
-
- private static final String RANDOM_REQUEST_URI = UUID.randomUUID().toString();
- private static final String RANDOM_REQUEST_ID = UUID.randomUUID().toString();
- private static final String RANDOM_PARTNER_NAME = UUID.randomUUID().toString();
-
- @Rule
- public TestName testName = new TestName();
-
- /**
- * Verify all mocks after each test.
- */
- @After
- public void verifyMocks() {
-
- try {
- PowerMock.verifyAll();
- } catch (AssertionError e) {
- throw new AssertionError("Expectations failed in " + testName.getMethodName() + "()", e);
- }
- }
-
-
- @Test
- public void filterPopulatesValuesWhenNoInitParamsAndNoHeaders() throws IOException, ServletException {
-
- mockLoggingContext();
- LoggingFilter loggingFilter = new LoggingFilter();
- loggingFilter.init(mockFilterConfig(null, null));
- loggingFilter.doFilter(new MockRequestBuilder().build(), mockResponse(), mockChain());
- }
-
- @Test
- public void filterPopulatesValuesWhenNoInitParamsAndExistingHeaders() throws IOException, ServletException {
-
- mockLoggingContext();
-
- LoggingFilter loggingFilter = new LoggingFilter();
- loggingFilter.init(mockFilterConfig(null, null));
-
- HttpServletRequest mockRequest = new MockRequestBuilder().partnerName(RANDOM_PARTNER_NAME)
- .requestId(RANDOM_REQUEST_ID).build();
- loggingFilter.doFilter(mockRequest, mockResponse(), mockChain());
- }
-
- @Test
- public void filterPopulatesValuesWhenCustomInitParamsAndNoHeaders() throws IOException, ServletException {
-
- mockLoggingContext();
-
- final String requestIdHeader = "x-request";
- final String partnerNameHeader = "x-partner";
-
- LoggingFilter loggingFilter = new LoggingFilter();
- FilterConfig mockConfig = mockFilterConfig(requestIdHeader, partnerNameHeader);
- loggingFilter.init(mockConfig);
-
- HttpServletRequest mockRequest = new MockRequestBuilder().requestIdHeader(requestIdHeader)
- .partnerNameHeader(partnerNameHeader).build();
- loggingFilter.doFilter(mockRequest, mockResponse(), mockChain());
- }
-
- @Test
- public void filterPopulatesValuesWhenCustomInitParamsAndExistingHeaders() throws IOException, ServletException {
-
- mockLoggingContext();
-
- final String requestIdHeader = "x-request-id";
- final String partnerNameHeader = "x-partner-name";
-
- LoggingFilter loggingFilter = new LoggingFilter();
- FilterConfig mockConfig = mockFilterConfig(requestIdHeader, partnerNameHeader);
- loggingFilter.init(mockConfig);
-
- HttpServletRequest mockRequest = new MockRequestBuilder()
- .partnerNameHeader(partnerNameHeader).partnerName(RANDOM_PARTNER_NAME)
- .requestIdHeader(requestIdHeader).requestId(RANDOM_REQUEST_ID).build();
- loggingFilter.doFilter(mockRequest, mockResponse(), mockChain());
- }
-
- private FilterConfig mockFilterConfig(String requestIdHeader, String partnerNameHeader) {
- FilterConfig config = EasyMock.mock(FilterConfig.class);
- EasyMock.expect(config.getInitParameter(REQUEST_ID_HEADERS_PARAM)).andReturn(requestIdHeader);
- EasyMock.expect(config.getInitParameter(PARTNER_NAME_HEADERS_PARAM)).andReturn(partnerNameHeader);
- EasyMock.replay(config);
- return config;
- }
-
- private FilterChain mockChain() throws IOException, ServletException {
- FilterChain chain = EasyMock.mock(FilterChain.class);
- chain.doFilter(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
- EasyMock.expectLastCall().once();
- EasyMock.replay(chain);
- return chain;
- }
-
- private ServletResponse mockResponse() {
- HttpServletResponse servletResponse = EasyMock.mock(HttpServletResponse.class);
- EasyMock.replay(servletResponse);
- return servletResponse;
- }
-
- private void mockLoggingContext() {
-
- PowerMock.mockStatic(LoggingContext.class);
-
- LoggingContext.clear();
- EasyMock.expectLastCall().times(2);
-
- LoggingContext.put(anyObject(ContextData.class));
- EasyMock.expectLastCall().once();
-
- PowerMock.replay(LoggingContext.class);
- }
-
- private static class MockRequestBuilder {
-
- private String requestIdHeader = DEFAULT_REQUEST_ID_HEADER;
- private String partnerNameHeader = DEFAULT_PARTNER_NAME_HEADER;
- private String requestId = null;
- private String partnerName = null;
-
- MockRequestBuilder requestIdHeader(String h) {
- this.requestIdHeader = h;
- return this;
- }
-
- MockRequestBuilder requestId(String id) {
- this.requestId = id;
- return this;
- }
-
- MockRequestBuilder partnerNameHeader(String h) {
- this.partnerNameHeader = h;
- return this;
- }
-
- MockRequestBuilder partnerName(String name) {
- this.partnerName = name;
- return this;
- }
-
- HttpServletRequest build() {
- HttpServletRequest mockRequest = EasyMock.mock(HttpServletRequest.class);
- EasyMock.expect(mockRequest.getRequestURI()).andReturn(RANDOM_REQUEST_URI);
- EasyMock.expect(mockRequest.getHeader(requestIdHeader)).andReturn(requestId);
- EasyMock.expect(mockRequest.getHeader(partnerNameHeader)).andReturn(partnerName);
- EasyMock.replay(mockRequest);
- return mockRequest;
- }
- }
-}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/ServiceNameFormatterTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/ServiceNameFormatterTest.java
new file mode 100644
index 0000000..87fb6f7
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/ServiceNameFormatterTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Test;
+
+/**
+ * Service name formatting.
+ *
+ * @author evitaliy
+ * @since 01 Aug 2018
+ */
+public class ServiceNameFormatterTest {
+
+ @Test
+ public void includesMethodAndUri() {
+ final String method = "ABC";
+ final String uri = "/a/b/c";
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getRequestURI()).thenReturn(uri);
+ when(request.getMethod()).thenReturn(method);
+ assertEquals(method + ": " + uri, ServiceNameFormatter.format(request));
+ }
+}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/HttpHeaderTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/HttpHeaderTest.java
deleted file mode 100644
index ad7be95..0000000
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/HttpHeaderTest.java
+++ /dev/null
@@ -1,97 +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.jaxrs;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import java.util.function.Function;
-import org.junit.Test;
-import org.openecomp.sdc.logging.servlet.HttpHeader;
-
-/**
- * Unit tests multiple-option headers.
- *
- * @author evitaliy
- * @since 25 Mar 2018
- */
-public class HttpHeaderTest {
-
- private static final String KEY_FIRST = "First";
- private static final String KEY_SECOND = "Second";
-
- @Test
- public void valueReturnedWhenSinglePossibleHeader() {
-
- final String key = "Head";
- final String value = "1234";
-
- Function<String, String> reader = createReader(key, value);
- HttpHeader header = new HttpHeader(key);
- assertEquals(value, header.getAny(reader));
- }
-
- @Test
- public void nullReturnedWhenSingleNoMatchingHeader() {
-
- final String key = "Head";
-
- Function<String, String> reader = createReader(key, null);
- HttpHeader header = new HttpHeader(key);
- assertNull(header.getAny(reader));
- }
-
- @Test
- public void nullReturnedWhenNoneHeaderMatches() {
- Function<String, String> reader = createReader("None", "Value");
- HttpHeader header = new HttpHeader("A", "B", "C");
- assertNull(header.getAny(reader));
- }
-
- @Test
- public void valueReturnedWhenLastHeaderMatches() {
-
- final String lastKey = "Last";
- final String value = "1234";
-
- Function<String, String> reader = createReader(lastKey, value);
- HttpHeader header = new HttpHeader(KEY_FIRST, KEY_SECOND, lastKey);
- assertEquals(value, header.getAny(reader));
- }
-
- @Test
- public void valueReturnedWhenFirstHeaderMatches() {
-
- final String value = "1234";
- Function<String, String> reader = createReader(KEY_FIRST, value);
- HttpHeader header = new HttpHeader(KEY_FIRST, KEY_SECOND, "Third");
- assertEquals(value, header.getAny(reader));
- }
-
- @Test
- public void valueReturnedWhenMiddleHeaderMatches() {
-
- final String value = "1234";
- Function<String, String> reader = createReader(KEY_SECOND, value);
- HttpHeader header = new HttpHeader(KEY_FIRST, KEY_SECOND, "Third");
- assertEquals(value, header.getAny(reader));
- }
-
- private Function<String, String> createReader(String key, String value) {
- return h -> h.equals(key) ? value : null;
- }
-}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilterTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilterTest.java
index 4098809..aa77dea 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilterTest.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilterTest.java
@@ -16,25 +16,18 @@
package org.openecomp.sdc.logging.servlet.jaxrs;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.anyString;
-import static org.openecomp.sdc.logging.servlet.jaxrs.LoggingRequestFilter.START_TIME_KEY;
+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.servlet.jaxrs.LoggingRequestFilter.LOGGING_TRACKER_KEY;
-import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Rule;
+import javax.ws.rs.container.ResourceInfo;
import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.openecomp.sdc.logging.LoggingConstants;
-import org.openecomp.sdc.logging.api.ContextData;
-import org.openecomp.sdc.logging.api.LoggingContext;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.openecomp.sdc.logging.servlet.Tracker;
/**
@@ -43,222 +36,25 @@
* @author evitaliy
* @since 19 Mar 2018
*/
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({LoggingContext.class, ContextData.class})
public class LoggingRequestFilterTest {
- private static final String REQUEST_URI = "/test";
- private static final String REQUEST_METHOD = "GET";
- private static final String RANDOM_REQUEST_ID = UUID.randomUUID().toString();
- private static final String RANDOM_PARTNER_NAME = UUID.randomUUID().toString();
-
- @Rule
- public TestName testName = new TestName();
-
- /**
- * Verify all mocks after each test.
- */
- @After
- public void verifyMocks() {
-
- try {
- PowerMock.verifyAll();
- } catch (AssertionError e) {
- throw new AssertionError("Expectations failed in " + testName.getMethodName() + "()", e);
- }
- }
-
@Test
- public void serviceNamePopulatedWhenThereIsMatchingResource() {
+ public void trackerPushedOntoRequestContext() {
- mockContextDataBuilder(null, null, LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI));
- mockLoggingContext();
+ LoggingRequestFilter requestFilter = new LoggingRequestFilter();
+ requestFilter.setHttpRequest(mock(HttpServletRequest.class));
- LoggingRequestFilter filter = new LoggingRequestFilter();
- filter.setHttpRequest(mockHttpRequest(true));
+ ResourceInfo resourceInfo = mock(ResourceInfo.class);
+ when(resourceInfo.getResourceMethod()).thenReturn(Resource.class.getDeclaredMethods()[0]);
+ requestFilter.setResource(resourceInfo);
- filter.filter(mockContainerRequestContext(
- new RequestIdHeader(null),
- new PartnerHeader(null)));
+ ContainerRequestContext requestContext = mock(ContainerRequestContext.class);
+ requestFilter.filter(requestContext);
+ verify(requestContext).setProperty(eq(LOGGING_TRACKER_KEY), any(Tracker.class));
}
- @Test
- public void serviceNameDoesNotIncludeHttpMethodWhenHttpMethodDisabled() {
-
- mockContextDataBuilder(null, null, REQUEST_URI);
- mockLoggingContext();
-
- LoggingRequestFilter filter = new LoggingRequestFilter();
- filter.setHttpMethodInServiceName(false);
- filter.setHttpRequest(mockHttpRequest(false));
-
- filter.filter(mockContainerRequestContext(
- new RequestIdHeader(null),
- new PartnerHeader(null)));
- }
-
- @Test
- public void partnerNamePopulatedWhenPresentInDefaultHeader() {
-
- mockContextDataBuilder(null, RANDOM_PARTNER_NAME,
- LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI));
- mockLoggingContext();
-
- LoggingRequestFilter filter = new LoggingRequestFilter();
- filter.setHttpRequest(mockHttpRequest(true));
-
- filter.filter(mockContainerRequestContext(
- new RequestIdHeader(null),
- new PartnerHeader(RANDOM_PARTNER_NAME)));
- }
-
- @Test
- public void partnerNamePopulatedWhenPresentInCustomHeader() {
-
- final String partnerHeader = "x-partner-header";
- mockContextDataBuilder(null, RANDOM_PARTNER_NAME,
- LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI));
- mockLoggingContext();
-
- LoggingRequestFilter filter = new LoggingRequestFilter();
- filter.setHttpRequest(mockHttpRequest(true));
- filter.setPartnerNameHeaders(partnerHeader);
-
- filter.filter(mockContainerRequestContext(
- new RequestIdHeader(null),
- new PartnerHeader(partnerHeader, RANDOM_PARTNER_NAME)));
- }
-
- @Test
- public void requestIdPopulatedWhenPresentInDefaultHeader() {
-
- mockContextDataBuilder(RANDOM_REQUEST_ID, null,
- LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI));
- mockLoggingContext();
-
- LoggingRequestFilter filter = new LoggingRequestFilter();
- filter.setHttpRequest(mockHttpRequest(true));
-
- filter.filter(mockContainerRequestContext(
- new RequestIdHeader(RANDOM_REQUEST_ID),
- new PartnerHeader(null)));
- }
-
- @Test
- public void requestIdPopulatedWhenPresentInCustomHeader() {
-
- final String requestIdHeader = "x-request-id";
- mockContextDataBuilder(RANDOM_REQUEST_ID, null,
- LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI));
- mockLoggingContext();
-
- LoggingRequestFilter filter = new LoggingRequestFilter();
- filter.setRequestIdHeaders(requestIdHeader);
- filter.setHttpRequest(mockHttpRequest(true));
-
- filter.filter(mockContainerRequestContext(
- new RequestIdHeader(requestIdHeader, RANDOM_REQUEST_ID),
- new PartnerHeader(null)));
- }
-
- private HttpServletRequest mockHttpRequest(boolean includeMethod) {
-
- HttpServletRequest servletRequest = EasyMock.mock(HttpServletRequest.class);
- EasyMock.expect(servletRequest.getRequestURI()).andReturn(REQUEST_URI);
-
- if (includeMethod) {
- EasyMock.expect(servletRequest.getMethod()).andReturn(REQUEST_METHOD);
- }
-
- EasyMock.replay(servletRequest);
- return servletRequest;
- }
-
- private ContainerRequestContext mockContainerRequestContext(Header... headers) {
-
- ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
-
- for (Header h : headers) {
- EasyMock.expect(requestContext.getHeaderString(h.key)).andReturn(h.value);
- }
-
- requestContext.setProperty(EasyMock.eq(START_TIME_KEY), EasyMock.anyLong());
- EasyMock.expectLastCall();
-
- EasyMock.replay(requestContext);
- return requestContext;
- }
-
- private void mockContextDataBuilder(String requestId, String partnerName, String serviceName) {
-
- ContextData.ContextDataBuilder mockBuilder = EasyMock.mock(ContextData.ContextDataBuilder.class);
-
- if (requestId != null) {
- EasyMock.expect(mockBuilder.requestId(requestId)).andReturn(mockBuilder);
- } else {
- EasyMock.expect(mockBuilder.requestId(anyString())).andReturn(mockBuilder);
- }
-
- EasyMock.expect(mockBuilder.serviceName(serviceName)).andReturn(mockBuilder);
-
- if (partnerName != null) {
- EasyMock.expect(mockBuilder.partnerName(partnerName)).andReturn(mockBuilder);
- }
-
- EasyMock.expect(mockBuilder.build()).andReturn(EasyMock.mock(ContextData.class));
- EasyMock.replay(mockBuilder);
-
- PowerMock.mockStatic(ContextData.class);
-
- ContextData.builder();
- PowerMock.expectLastCall().andReturn(mockBuilder);
-
- PowerMock.replay(ContextData.class);
- }
-
- private void mockLoggingContext() {
-
- PowerMock.mockStatic(LoggingContext.class);
-
- LoggingContext.clear();
- EasyMock.expectLastCall();
-
- LoggingContext.put(anyObject(ContextData.class));
- EasyMock.expectLastCall();
-
- PowerMock.replay(LoggingContext.class);
- }
-
- private abstract static class Header {
-
- private final String key;
- private final String value;
-
- private Header(String key, String value) {
- this.key = key;
- this.value = value;
- }
- }
-
- private static class PartnerHeader extends Header {
-
- private PartnerHeader(String value) {
- super(LoggingConstants.DEFAULT_PARTNER_NAME_HEADER, value);
- }
-
- private PartnerHeader(String key, String value) {
- super(key, value);
- }
- }
-
- private static class RequestIdHeader extends Header {
-
- private RequestIdHeader(String value) {
- super(LoggingConstants.DEFAULT_REQUEST_ID_HEADER, value);
- }
-
- private RequestIdHeader(String key, String value) {
- super(key, value);
- }
+ private interface Resource {
+ @SuppressWarnings("unused")
+ void method();
}
}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilterTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilterTest.java
index 710cf12..336840b 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilterTest.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingResponseFilterTest.java
@@ -16,35 +16,18 @@
package org.openecomp.sdc.logging.servlet.jaxrs;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.anyString;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.openecomp.sdc.logging.servlet.jaxrs.LoggingRequestFilter.LOGGING_TRACKER_KEY;
-import java.lang.reflect.Method;
-import java.util.Comparator;
-import java.util.Objects;
-import java.util.function.Consumer;
-import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
-import javax.ws.rs.container.ResourceInfo;
-import javax.ws.rs.core.Response;
-import org.easymock.EasyMock;
-import org.easymock.LogicalOperator;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.openecomp.sdc.logging.api.AuditData;
-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.api.StatusCode;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
+import org.openecomp.sdc.logging.servlet.RequestProcessingResult;
+import org.openecomp.sdc.logging.servlet.Tracker;
/**
* Unit testing JAX-RS response filter.
@@ -52,277 +35,24 @@
* @author evitaliy
* @since 19 Mar 2018
*/
-@RunWith(PowerMockRunner.class)
public class LoggingResponseFilterTest {
- private static final Class RESOURCE_TYPE = Resource.class;
- private static final Method RESOURCE_METHOD = Resource.class.getDeclaredMethods()[0];
-
- @Rule
- public TestName testName = new TestName();
-
- @Before
- public void prepareLoggingContext() {
- mockLoggingContext();
- }
-
- /**
- * Verify all mocks after each test.
- */
- @After
- public void verifyMocks() {
-
- try {
- PowerMock.verifyAll();
- } catch (AssertionError e) {
- throw new AssertionError("Expectations failed in " + testName.getMethodName() + "()", e);
- }
+ @Test
+ public void noExceptionsWhenTrackerNotPassed() {
+ new LoggingResponseFilter().filter(mock(ContainerRequestContext.class), mock(ContainerResponseContext.class));
}
@Test
- @PrepareForTest({LoggingContext.class, LoggerFactory.class})
- public void noAuditWhenNoMatchingResource() {
+ public void postRequestWhenTrackerPassed() {
- PowerMock.mockStatic(LoggerFactory.class);
- mockFilterLogger(logger -> {
- logger.debug(anyString());
- EasyMock.expectLastCall();
- });
- PowerMock.replay(LoggerFactory.class);
+ Tracker tracker = mock(Tracker.class);
+
+ ContainerRequestContext requestContext = mock(ContainerRequestContext.class);
+ when(requestContext.getProperty(LOGGING_TRACKER_KEY)).thenReturn(tracker);
LoggingResponseFilter responseFilter = new LoggingResponseFilter();
- responseFilter.filter(mockDisabledRequestContext(), mockDisabledResponseContext());
- }
+ responseFilter.filter(requestContext, mock(ContainerResponseContext.class));
- @Test
- @PrepareForTest({LoggingContext.class, LoggerFactory.class})
- public void noAuditWhenNullResource() {
-
- PowerMock.mockStatic(LoggerFactory.class);
- mockFilterLogger(logger -> {
- logger.debug(anyString());
- EasyMock.expectLastCall();
- });
- PowerMock.replay(LoggerFactory.class);
-
- LoggingResponseFilter responseFilter = new LoggingResponseFilter();
- responseFilter.setResource(null);
- responseFilter.filter(mockDisabledRequestContext(), mockDisabledResponseContext());
- }
-
- @Test
- @PrepareForTest({LoggingContext.class, LoggerFactory.class})
- public void noAuditWhenAuditDisabled() {
-
- PowerMock.mockStatic(LoggerFactory.class);
- mockFilterLogger();
- mockResourceLogger(false, AuditData.builder().build());
- PowerMock.replay(LoggerFactory.class);
-
- LoggingResponseFilter responseFilter = new LoggingResponseFilter();
- responseFilter.setResource(mockResource());
- responseFilter.filter(mockDisabledRequestContext(), mockDisabledResponseContext());
- }
-
- @Test
- @PrepareForTest({LoggingContext.class, LoggerFactory.class})
- public void startTimeReadWhenPresentInRequestContext() {
-
- final String clientIp = "IP1";
- final long startTime = 12345L;
- final Response.Status ok = Response.Status.OK;
-
- PowerMock.mockStatic(LoggerFactory.class);
- mockResourceLogger(true, buildAuditData(startTime, clientIp, ok, StatusCode.COMPLETE));
- mockFilterLogger();
- PowerMock.replay(LoggerFactory.class);
-
- LoggingResponseFilter filter = new LoggingResponseFilter();
- filter.setResource(mockResource());
- filter.setHttpRequest(mockHttpRequest(clientIp));
-
- filter.filter(mockRequestContext(startTime), mockResponseContext(ok));
- }
-
- @Test
- @PrepareForTest({LoggingContext.class, LoggerFactory.class})
- public void startTimeZeroWhenNotPresentInRequestContext() {
-
- final String clientIp = "IP2";
- final Response.Status ok = Response.Status.OK;
-
- AuditData expectedAuditData = buildAuditData(0, clientIp, ok, StatusCode.COMPLETE);
-
- PowerMock.mockStatic(LoggerFactory.class);
- mockResourceLogger(true, expectedAuditData);
- mockFilterLogger(logger -> {
- logger.error(anyString(), anyObject(Object[].class));
- EasyMock.expectLastCall();
- });
- PowerMock.replay(LoggerFactory.class);
-
- LoggingResponseFilter filter = new LoggingResponseFilter();
- filter.setResource(mockResource());
- filter.setHttpRequest(mockHttpRequest(clientIp));
-
- filter.filter(mockRequestContext(null), mockResponseContext(ok));
- }
-
- @Test
- @PrepareForTest({LoggingContext.class, LoggerFactory.class})
- public void startTimeZeroWhenIncorrectObjectType() {
-
- final String clientIp = "IP3";
- final Response.Status accepted = Response.Status.ACCEPTED;
-
- AuditData expectedAuditData = buildAuditData(0, clientIp, accepted, StatusCode.COMPLETE);
-
- PowerMock.mockStatic(LoggerFactory.class);
- mockFilterLogger(logger -> {
- logger.error(anyString(), anyString(), anyString(), anyObject());
- EasyMock.expectLastCall();
- });
- mockResourceLogger(true, expectedAuditData);
- PowerMock.replay(LoggerFactory.class);
-
- LoggingResponseFilter filter = new LoggingResponseFilter();
- filter.setResource(mockResource());
- filter.setHttpRequest(mockHttpRequest(clientIp));
-
- filter.filter(mockRequestContext("string object"), mockResponseContext(accepted));
- }
-
- @Test
- @PrepareForTest({LoggingContext.class, LoggerFactory.class})
- public void statusErrorWhenHttpResponseGreaterThan399() {
-
- final Response.Status error = Response.Status.BAD_REQUEST;
- final String clientIp = "IP13";
- final long startTime = 88668603L;
-
- AuditData expectedAuditData = buildAuditData(startTime, clientIp, error, StatusCode.ERROR);
-
- PowerMock.mockStatic(LoggerFactory.class);
- mockResourceLogger(true, expectedAuditData);
- mockFilterLogger();
- PowerMock.replay(LoggerFactory.class);
-
- LoggingResponseFilter filter = new LoggingResponseFilter();
- filter.setResource(mockResource());
- filter.setHttpRequest(mockHttpRequest(clientIp));
-
- filter.filter(mockRequestContext(startTime), mockResponseContext(error));
- }
-
- private AuditData buildAuditData(long startTime, String clientIp, Response.Status responseStatus,
- StatusCode status) {
- return AuditData.builder().startTime(startTime).responseCode(Integer.toString(responseStatus.getStatusCode()))
- .responseDescription(responseStatus.getReasonPhrase()).clientIpAddress(clientIp)
- .statusCode(status).build();
- }
-
- private void mockResourceLogger(boolean enabled, AuditData auditData) {
-
- Logger resourceLogger = EasyMock.mock(Logger.class);
-
- EasyMock.expect(resourceLogger.isAuditEnabled()).andReturn(enabled).atLeastOnce();
-
- if (enabled) {
- resourceLogger.audit(EasyMock.cmp(auditData, new AuditDataComparator(), LogicalOperator.EQUAL));
- EasyMock.expectLastCall();
- }
-
- EasyMock.replay(resourceLogger);
-
- LoggerFactory.getLogger(RESOURCE_TYPE);
- PowerMock.expectLastCall().andReturn(resourceLogger);
- }
-
- @SafeVarargs
- private final void mockFilterLogger(Consumer<Logger>... expectations) {
-
- Logger filterLogger = EasyMock.mock(Logger.class);
-
- for (Consumer<Logger> expect : expectations) {
- expect.accept(filterLogger);
- }
-
- EasyMock.replay(filterLogger);
-
- LoggerFactory.getLogger(LoggingResponseFilter.class);
- PowerMock.expectLastCall().andReturn(filterLogger);
- }
-
- private void mockLoggingContext() {
- PowerMock.mockStatic(LoggingContext.class);
- LoggingContext.clear();
- EasyMock.expectLastCall();
- PowerMock.replay(LoggingContext.class);
- }
-
- private ContainerRequestContext mockDisabledRequestContext() {
- ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
- EasyMock.replay(requestContext);
- return requestContext;
- }
-
- private ContainerResponseContext mockDisabledResponseContext() {
- ContainerResponseContext responseContext = EasyMock.mock(ContainerResponseContext.class);
- EasyMock.replay(responseContext);
- return responseContext;
- }
-
- private HttpServletRequest mockHttpRequest(String clientIp) {
- HttpServletRequest servletRequest = EasyMock.mock(HttpServletRequest.class);
- EasyMock.expect(servletRequest.getRemoteAddr()).andReturn(clientIp);
- EasyMock.replay(servletRequest);
- return servletRequest;
- }
-
- private ContainerRequestContext mockRequestContext(Object startTime) {
- ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
- EasyMock.expect(requestContext.getProperty(LoggingRequestFilter.START_TIME_KEY)).andReturn(startTime);
- EasyMock.replay(requestContext);
- return requestContext;
- }
-
- private ContainerResponseContext mockResponseContext(Response.StatusType statusInfo) {
- ContainerResponseContext responseContext = EasyMock.mock(ContainerResponseContext.class);
- EasyMock.expect(responseContext.getStatusInfo()).andReturn(statusInfo);
- EasyMock.replay(responseContext);
- return responseContext;
- }
-
- private ResourceInfo mockResource() {
- ResourceInfo resource = EasyMock.mock(ResourceInfo.class);
- //noinspection unchecked
- EasyMock.expect(resource.getResourceClass()).andReturn(RESOURCE_TYPE).anyTimes();
- EasyMock.expect(resource.getResourceMethod()).andReturn(RESOURCE_METHOD).anyTimes();
- EasyMock.replay(resource);
- return resource;
- }
-
- private static class AuditDataComparator implements Comparator<AuditData> {
-
- @Override
- public int compare(AuditData one, AuditData two) {
-
- // don't compare end time as it changes
- if (Objects.equals(one.getClientIpAddress(), two.getClientIpAddress())
- && Objects.equals(one.getResponseCode(), two.getResponseCode())
- && Objects.equals(one.getResponseDescription(), two.getResponseDescription())
- && one.getStartTime() == two.getStartTime()
- && Objects.equals(one.getStatusCode(), two.getStatusCode())) {
-
- return 0;
- }
-
- return -1;
- }
- }
-
- interface Resource {
- @SuppressWarnings("unused")
- void method();
+ verify(tracker, times(1)).postRequest(any(RequestProcessingResult.class));
}
}
\ No newline at end of file