From c6a769eff2930fcf4f4dadb8106937abf86d8638 Mon Sep 17 00:00:00 2001 From: vempo Date: Wed, 27 Jun 2018 20:36:49 +0300 Subject: Improvements in audit logger for onboarding A few optimizations, more unit-tests, log via the handling resource's logger instead of filter's logger. Change-Id: I40cef2c86a82b25ded1f8fdca1ec3b0f2fe062d8 Issue-ID: SDC-1451 Signed-off-by: vempo --- .../openecomp/sdc/logging/api/LoggerFactory.java | 12 +- .../openecomp/sdc/logging/api/LoggingContext.java | 15 +- .../servlet/jaxrs/LoggingRequestFilter.java | 82 ++----- .../servlet/jaxrs/LoggingResponseFilter.java | 35 ++- .../openecomp/sdc/logging/api/AuditDataTest.java | 30 ++- .../openecomp/sdc/logging/api/ContextDataTest.java | 14 +- .../sdc/logging/api/LoggerFactoryTest.java | 16 +- .../sdc/logging/api/LoggingContextTest.java | 22 +- .../openecomp/sdc/logging/api/MetricsDataTest.java | 28 +-- .../sdc/logging/api/ServiceBinderTest.java | 6 +- .../sdc/logging/servlet/LoggingFilterTest.java | 30 ++- .../sdc/logging/servlet/jaxrs/HttpHeaderTest.java | 33 ++- .../servlet/jaxrs/LoggingRequestFilterTest.java | 160 ++++-------- .../servlet/jaxrs/LoggingResponseFilterTest.java | 272 ++++++++++++++------- 14 files changed, 393 insertions(+), 362 deletions(-) (limited to 'openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src') 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 1f3df8bcc0..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 @@ -36,8 +36,8 @@ public class LoggerFactory { // use the no-op service to prevent recursion in case of an attempt to log an exception as a // result of a logger initialization error - private static final LoggerCreationService SERVICE = ServiceBinder.getCreationServiceBinding().orElse( - new NoOpLoggerCreationService()); + private static final LoggerCreationService SERVICE = ServiceBinder.getCreationServiceBinding().orElseGet( + NoOpLoggerCreationService::new); private LoggerFactory() { // prevent instantiation @@ -53,10 +53,10 @@ public class LoggerFactory { private static class NoOpLoggerCreationService implements LoggerCreationService { - private static final Logger NO_OP_LOGGER = new NoOpLogger(); - private static class NoOpLogger implements Logger { + private static final Logger INSTANCE = new NoOpLogger(); + @Override public String getName() { return "No-Op Logger"; @@ -211,13 +211,13 @@ public class LoggerFactory { @Override public Logger getLogger(String className) { Objects.requireNonNull(className, "Name cannot be null"); - return NO_OP_LOGGER; + return NoOpLogger.INSTANCE; } @Override public Logger getLogger(Class clazz) { Objects.requireNonNull(clazz, "Class cannot be null"); - return NO_OP_LOGGER; + return NoOpLogger.INSTANCE; } } } 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 c17149e98e..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 @@ -36,7 +36,7 @@ import org.openecomp.sdc.logging.spi.LoggingContextService; public class LoggingContext { private static final LoggingContextService SERVICE = - ServiceBinder.getContextServiceBinding().orElse(new NoOpLoggingContextService()); + ServiceBinder.getContextServiceBinding().orElseGet(NoOpLoggingContextService::new); private LoggingContext() { // prevent instantiation @@ -64,8 +64,6 @@ public class LoggingContext { private static class NoOpLoggingContextService implements LoggingContextService { - private static final ContextData EMPTY_CONTEXT = ContextData.builder().build(); - @Override public void put(ContextData contextData) { Objects.requireNonNull(contextData, "Context data cannot be null"); @@ -73,7 +71,7 @@ public class LoggingContext { @Override public ContextData get() { - return EMPTY_CONTEXT; + return EmptyContextData.INSTANCE; } @Override @@ -92,5 +90,14 @@ public class LoggingContext { Objects.requireNonNull(callable, "Callable cannot be null"); return callable; } + + private static class EmptyContextData { + + private static final ContextData INSTANCE = ContextData.builder().build(); + + private EmptyContextData() { + // prevent instantiation + } + } } } 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 498587414a..0e1b7d715b 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,12 +19,10 @@ 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.lang.reflect.Method; -import java.lang.reflect.Proxy; 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; @@ -66,19 +64,27 @@ public class LoggingRequestFilter implements ContainerRequestFilter { private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRequestFilter.class); - private ResourceInfo resource; + 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; /** - * Injection of a resource that matches the request from JAX-RS context. + * Injection of HTTP request object from JAX-RS context. * - * @param resource automatically injected by JAX-RS container + * @param httpRequest automatically injected by JAX-RS container */ @Context - public void setResource(ResourceInfo resource) { - this.resource = resource; + public void setHttpRequest(HttpServletRequest httpRequest) { + this.httpRequest = httpRequest; + } + + /** + * Configuration parameter to include the HTTP method of a request in service name. + */ + public void setHttpMethodInServiceName(boolean includeHttpMethod) { + this.includeHttpMethod = includeHttpMethod; } /** @@ -100,22 +106,10 @@ public class LoggingRequestFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext containerRequestContext) { - if (resource == null) { - // JAX-RS could not find a mapping this response, probably due to HTTP 404 (not found), - // 405 (method not allowed), 415 (unsupported media type), etc. with a message in Web server log - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("No matching resource was found for URI '{}' and method '{}'", - containerRequestContext.getUriInfo().getPath(), containerRequestContext.getMethod()); - } - - return; - } + LoggingContext.clear(); containerRequestContext.setProperty(START_TIME_KEY, System.currentTimeMillis()); - LoggingContext.clear(); - ContextData.ContextDataBuilder contextData = ContextData.builder(); contextData.serviceName(getServiceName()); @@ -131,48 +125,12 @@ public class LoggingRequestFilter implements ContainerRequestFilter { } private String getServiceName() { - - Class resourceClass = resource.getResourceClass(); - Method resourceMethod = resource.getResourceMethod(); - - if (Proxy.isProxyClass(resourceClass)) { - LOGGER.debug("Proxy class injected for JAX-RS resource"); - return getServiceNameFromJavaProxy(resourceClass, resourceMethod); - } - - return formatServiceName(resourceClass, resourceMethod); + return includeHttpMethod + ? formatServiceName(this.httpRequest.getMethod(), this.httpRequest.getRequestURI()) + : this.httpRequest.getRequestURI(); } - private String getServiceNameFromJavaProxy(Class proxyType, Method resourceMethod) { - - for (Class interfaceType : proxyType.getInterfaces()) { - - if (isMatchingInterface(interfaceType, resourceMethod)) { - return formatServiceName(interfaceType, resourceMethod); - } - } - - LOGGER.debug("Failed to find method '{}' in interfaces implemented by injected Java proxy", resourceMethod); - return formatServiceName(proxyType, resourceMethod); - } - - private String formatServiceName(Class resourceClass, Method resourceMethod) { - return resourceClass.getName() + "#" + resourceMethod.getName(); - } - - private boolean isMatchingInterface(Class candidateType, Method requestedMethod) { - - try { - - Method candidate = candidateType.getDeclaredMethod(requestedMethod.getName(), - requestedMethod.getParameterTypes()); - return candidate != null; - - } catch (NoSuchMethodException ignored) { - // ignore and move on to the next - LOGGER.debug("Failed to find method '{}' in interface '{}'", requestedMethod, candidateType); - } - - return false; + static String formatServiceName(String httpMethod, String requestUri) { + return httpMethod + " " + requestUri; } } 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 fbe28a79eb..e0353a43ca 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 @@ -23,6 +23,7 @@ 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; @@ -53,7 +54,9 @@ import org.openecomp.sdc.logging.api.StatusCode; @Provider public class LoggingResponseFilter implements ContainerResponseFilter { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); + 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 @@ -63,6 +66,8 @@ public class LoggingResponseFilter implements ContainerResponseFilter { private HttpServletRequest httpRequest; + private ResourceInfo resource; + /** * Injection of HTTP request object from JAX-RS context. * @@ -73,12 +78,29 @@ public class LoggingResponseFilter implements ContainerResponseFilter { 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) { try { + + if ((resource == null) || (resource.getResourceClass() == null)) { + LOGGER.debug("No matching resource, skipping audit."); + return; + } + writeAudit(containerRequestContext, containerResponseContext); + } finally { LoggingContext.clear(); } @@ -87,7 +109,8 @@ public class LoggingResponseFilter implements ContainerResponseFilter { private void writeAudit(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) { - if (!logger.isAuditEnabled()) { + Logger resourceLogger = LoggerFactory.getLogger(resource.getResourceMethod().getDeclaringClass()); + if (!resourceLogger.isAuditEnabled()) { return; } @@ -102,7 +125,7 @@ public class LoggingResponseFilter implements ContainerResponseFilter { .responseCode(Integer.toString(responseCode)) .responseDescription(statusInfo.getReasonPhrase()) .clientIpAddress(httpRequest.getRemoteAddr()).build(); - logger.audit(auditData); + resourceLogger.audit(auditData); } private boolean isSuccess(int responseCode) { @@ -122,7 +145,7 @@ public class LoggingResponseFilter implements ContainerResponseFilter { 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 0; + return UNKNOWN_START_TIME; } private long parseStartTime(Object startTime) { @@ -131,7 +154,7 @@ public class LoggingResponseFilter implements ContainerResponseFilter { 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()); + + " is expected", LoggingRequestFilter.START_TIME_KEY, startTime.getClass().getName(), e); return 0; } } @@ -140,7 +163,7 @@ public class LoggingResponseFilter implements ContainerResponseFilter { if (reportBadConfiguration) { reportBadConfiguration = false; - logger.error(message, arguments); + LOGGER.error(message, arguments); } } } diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java index 08ce5089b7..98da27dcc5 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java @@ -16,11 +16,14 @@ package org.openecomp.sdc.logging.api; -import static org.testng.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; -import org.testng.annotations.Test; +import org.junit.Test; /** + * Test correct population of audit data. + * * @author EVITALIY * @since 04 Mar 18 */ @@ -33,24 +36,25 @@ public class AuditDataTest { final long end = start + 100; final String responseCode = "Response-Code"; final String responseDescription = "Response-Description"; - final String ipAddress = "10.56.20.70"; + final String ipAddress = "DUMMY.IP.ADDRESS"; AuditData data = AuditData.builder().startTime(start).endTime(end).statusCode(StatusCode.COMPLETE) - .responseCode(responseCode).responseDescription(responseDescription).clientIpAddress(ipAddress).build(); - - assertEquals(data.getClientIpAddress(), ipAddress); - assertEquals(data.getEndTime(), end); - assertEquals(data.getStartTime(), start); - assertEquals(data.getResponseCode(), responseCode); - assertEquals(data.getResponseDescription(), responseDescription); - assertEquals(data.getStatusCode(), StatusCode.COMPLETE); + .responseCode(responseCode).responseDescription(responseDescription) + .clientIpAddress(ipAddress).build(); + + assertEquals(ipAddress, data.getClientIpAddress()); + assertEquals(end, data.getEndTime()); + assertEquals(start, data.getStartTime()); + assertEquals(responseCode, data.getResponseCode()); + assertEquals(responseDescription, data.getResponseDescription()); + assertEquals(StatusCode.COMPLETE, data.getStatusCode()); } @Test public void allPropertiesEmptyWhenUnpopulated() { AuditData data = AuditData.builder().build(); - assertEquals(data.getStartTime(), 0); - assertEquals(data.getEndTime(), 0); + assertEquals(0, data.getStartTime()); + assertEquals(0, data.getEndTime()); assertNull(data.getClientIpAddress()); assertNull(data.getResponseCode()); assertNull(data.getResponseDescription()); diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ContextDataTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ContextDataTest.java index 8a173b452a..873a489b84 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ContextDataTest.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ContextDataTest.java @@ -16,10 +16,10 @@ package org.openecomp.sdc.logging.api; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; -import org.testng.annotations.Test; +import org.junit.Test; /** * Unit-testing context data builder. @@ -37,11 +37,11 @@ public class ContextDataTest { final String requestId = "123412341234"; ContextData data = ContextData.builder() - .serviceName(serviceName).partnerName(partnerName).requestId(requestId).build(); + .serviceName(serviceName).partnerName(partnerName).requestId(requestId).build(); - assertEquals(data.getRequestId(), requestId); - assertEquals(data.getServiceName(), serviceName); - assertEquals(data.getPartnerName(), partnerName); + assertEquals(requestId, data.getRequestId()); + assertEquals(serviceName, data.getServiceName()); + assertEquals(partnerName, data.getPartnerName()); } @Test diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java index a1fe8c2b0f..6f860af60a 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java @@ -16,11 +16,11 @@ package org.openecomp.sdc.logging.api; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import java.lang.reflect.Field; -import org.testng.annotations.Test; +import org.junit.Test; /** * Unit-test creation of a logger via factory, assuming not default binding. @@ -31,15 +31,15 @@ import org.testng.annotations.Test; public class LoggerFactoryTest { @Test - public void shouldHoldNoOpWhenNoBinding() throws Exception { + public void shouldHoldNoOpWhenNoBinding() throws NoSuchFieldException, IllegalAccessException { // set up to access the private static field Field factory = LoggerFactory.class.getDeclaredField("SERVICE"); factory.setAccessible(true); Object impl = factory.get(null); - assertEquals(impl.getClass().getName(), - "org.openecomp.sdc.logging.api.LoggerFactory$NoOpLoggerCreationService"); + assertEquals("org.openecomp.sdc.logging.api.LoggerFactory$NoOpLoggerCreationService", + impl.getClass().getName()); } @Test @@ -54,12 +54,12 @@ public class LoggerFactoryTest { verifyLoggerWorks(logger); } - @Test(expectedExceptions = NullPointerException.class) + @Test(expected = NullPointerException.class) public void throwNpeWhenGetByNameWithNull() { LoggerFactory.getLogger((String) null); } - @Test(expectedExceptions = NullPointerException.class) + @Test(expected = NullPointerException.class) public void throwNpeWhenGetByClassWithNull() { LoggerFactory.getLogger((Class) null); } diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java index 3e7bbe14e0..ea908ae079 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java @@ -16,12 +16,12 @@ package org.openecomp.sdc.logging.api; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; import java.lang.reflect.Field; import java.util.concurrent.Callable; -import org.testng.annotations.Test; +import org.junit.Test; /** * Unit-testing default context service implementation. @@ -32,15 +32,15 @@ import org.testng.annotations.Test; public class LoggingContextTest { @Test - public void shouldHoldNoOpWhenNoBinding() throws Exception { + public void shouldHoldNoOpWhenNoBinding() throws NoSuchFieldException, IllegalAccessException { Field factory = LoggingContext.class.getDeclaredField("SERVICE"); factory.setAccessible(true); Object impl = factory.get(null); - assertEquals(impl.getClass().getName(), - "org.openecomp.sdc.logging.api.LoggingContext$NoOpLoggingContextService"); + assertEquals("org.openecomp.sdc.logging.api.LoggingContext$NoOpLoggingContextService", + impl.getClass().getName()); } - @Test(expectedExceptions = NullPointerException.class) + @Test(expected = NullPointerException.class) public void throwNpeWhenContextIsNull() { LoggingContext.put(null); } @@ -53,10 +53,10 @@ public class LoggingContextTest { @Test public void toRunnableReturnsSameInstance() { Runnable test = () -> { /* do nothing */ }; - assertTrue(test == LoggingContext.copyToRunnable(test)); + assertSame(test, LoggingContext.copyToRunnable(test)); } - @Test(expectedExceptions = NullPointerException.class) + @Test(expected = NullPointerException.class) public void throwNpeWhenToRunnableWithNull() { LoggingContext.copyToRunnable(null); } @@ -64,10 +64,10 @@ public class LoggingContextTest { @Test public void toCallableReturnsSameInstance() { Callable test = () -> ""; - assertTrue(test == LoggingContext.copyToCallable(test)); + assertSame(test, LoggingContext.copyToCallable(test)); } - @Test(expectedExceptions = NullPointerException.class) + @Test(expected = NullPointerException.class) public void throwNpeWhenToCallableWithNull() { LoggingContext.copyToCallable(null); } diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/MetricsDataTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/MetricsDataTest.java index a3c8b1039a..43f913ecab 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/MetricsDataTest.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/MetricsDataTest.java @@ -16,10 +16,10 @@ package org.openecomp.sdc.logging.api; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; -import org.testng.annotations.Test; +import org.junit.Test; /** * Unit-testing metrics builder and structure. @@ -36,7 +36,7 @@ public class MetricsDataTest { final long end = start + 1000; final String responseCode = "Metrics-Response-Code"; final String responseDescription = "Metrics-Response-Description"; - final String ipAddress = "10.56.20.72"; + final String ipAddress = "IP72"; final String targetEntity = "Metrics-Target-Entity"; final String targetVirtualEntity = "Metrics-Target-Virtual-Entity"; @@ -45,22 +45,22 @@ public class MetricsDataTest { .clientIpAddress(ipAddress).targetEntity(targetEntity) .targetVirtualEntity(targetVirtualEntity).build(); - assertEquals(data.getClientIpAddress(), ipAddress); - assertEquals(data.getEndTime(), end); - assertEquals(data.getStartTime(), start); - assertEquals(data.getResponseCode(), responseCode); - assertEquals(data.getResponseDescription(), responseDescription); - assertEquals(data.getStatusCode(), StatusCode.COMPLETE); - assertEquals(data.getTargetEntity(), targetEntity); - assertEquals(data.getTargetVirtualEntity(), targetVirtualEntity); + assertEquals(ipAddress, data.getClientIpAddress()); + assertEquals(end, data.getEndTime()); + assertEquals(start, data.getStartTime()); + assertEquals(responseCode, data.getResponseCode()); + assertEquals(responseDescription, data.getResponseDescription()); + assertEquals(StatusCode.COMPLETE, data.getStatusCode()); + assertEquals(targetEntity, data.getTargetEntity()); + assertEquals(targetVirtualEntity, data.getTargetVirtualEntity()); } @Test public void allMetricsPropertiesEmptyWhenUnpopulated() { MetricsData data = MetricsData.builder().build(); - assertEquals(data.getStartTime(), 0); - assertEquals(data.getEndTime(), 0); + assertEquals(0, data.getStartTime()); + assertEquals(0, data.getEndTime()); assertNull(data.getClientIpAddress()); assertNull(data.getResponseCode()); assertNull(data.getResponseDescription()); diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ServiceBinderTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ServiceBinderTest.java index 1a5c81d90d..74dd9e93f1 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ServiceBinderTest.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ServiceBinderTest.java @@ -16,11 +16,13 @@ package org.openecomp.sdc.logging.api; -import org.testng.annotations.Test; +import static org.junit.Assert.assertFalse; -import static org.testng.Assert.*; +import org.junit.Test; /** + * Test default service binding. + * * @author EVITALIY * @since 08 Jan 18 */ 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 index 535a50ca42..9bba28c5e4 100644 --- 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 @@ -32,14 +32,16 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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.testng.PowerMockTestCase; -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.Test; +import org.powermock.modules.junit4.PowerMockRunner; /** * Unit-tests logging filter for initialization and data retrieval. @@ -47,29 +49,33 @@ import org.testng.annotations.Test; * @author evitaliy * @since 17 Aug 2016 */ +@RunWith(PowerMockRunner.class) @PrepareForTest(LoggingContext.class) -public class LoggingFilterTest extends PowerMockTestCase { +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. */ - @AfterMethod - public void verifyMocks(ITestResult result) { + @After + public void verifyMocks() { try { PowerMock.verifyAll(); } catch (AssertionError e) { - throw new AssertionError("Expectations failed in: " + result.getMethod().getMethodName(), e); + throw new AssertionError("Expectations failed in " + testName.getMethodName() + "()", e); } } @Test - public void filterPopulatesValuesWhenNoInitParamsAndNoHeaders() throws Exception { + public void filterPopulatesValuesWhenNoInitParamsAndNoHeaders() throws IOException, ServletException { mockLoggingContext(); LoggingFilter loggingFilter = new LoggingFilter(); @@ -78,7 +84,7 @@ public class LoggingFilterTest extends PowerMockTestCase { } @Test - public void filterPopulatesValuesWhenNoInitParamsAndExistingHeaders() throws Exception { + public void filterPopulatesValuesWhenNoInitParamsAndExistingHeaders() throws IOException, ServletException { mockLoggingContext(); @@ -91,7 +97,7 @@ public class LoggingFilterTest extends PowerMockTestCase { } @Test - public void filterPopulatesValuesWhenCustomInitParamsAndNoHeaders() throws Exception { + public void filterPopulatesValuesWhenCustomInitParamsAndNoHeaders() throws IOException, ServletException { mockLoggingContext(); @@ -108,7 +114,7 @@ public class LoggingFilterTest extends PowerMockTestCase { } @Test - public void filterPopulatesValuesWhenCustomInitParamsAndExistingHeaders() throws Exception { + public void filterPopulatesValuesWhenCustomInitParamsAndExistingHeaders() throws IOException, ServletException { mockLoggingContext(); 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 index 3376c922e4..ad7be95cec 100644 --- 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 @@ -16,21 +16,24 @@ package org.openecomp.sdc.logging.servlet.jaxrs; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; +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; -import org.testng.annotations.Test; /** - * Unit tests mutliple-option headers. + * 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() { @@ -39,7 +42,7 @@ public class HttpHeaderTest { Function reader = createReader(key, value); HttpHeader header = new HttpHeader(key); - assertEquals(header.getAny(reader), value); + assertEquals(value, header.getAny(reader)); } @Test @@ -66,30 +69,26 @@ public class HttpHeaderTest { final String value = "1234"; Function reader = createReader(lastKey, value); - HttpHeader header = new HttpHeader("First", "Second", lastKey); - assertEquals(header.getAny(reader), value); + HttpHeader header = new HttpHeader(KEY_FIRST, KEY_SECOND, lastKey); + assertEquals(value, header.getAny(reader)); } @Test public void valueReturnedWhenFirstHeaderMatches() { - final String firstKey = "First"; final String value = "1234"; - - Function reader = createReader(firstKey, value); - HttpHeader header = new HttpHeader(firstKey, "Second", "Third"); - assertEquals(header.getAny(reader), value); + Function 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 middleKey = "Second"; final String value = "1234"; - - Function reader = createReader(middleKey, value); - HttpHeader header = new HttpHeader("First", middleKey, "Third"); - assertEquals(header.getAny(reader), value); + Function reader = createReader(KEY_SECOND, value); + HttpHeader header = new HttpHeader(KEY_FIRST, KEY_SECOND, "Third"); + assertEquals(value, header.getAny(reader)); } private Function createReader(String key, String value) { 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 579f41c3e6..4098809e42 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 @@ -20,21 +20,22 @@ 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 java.lang.reflect.Method; -import java.lang.reflect.Proxy; import java.util.UUID; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ResourceInfo; 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.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.testng.PowerMockTestCase; -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.Test; +import org.powermock.modules.junit4.PowerMockRunner; + /** * Unit testing JAX-RS request filter. @@ -42,76 +43,39 @@ import org.testng.annotations.Test; * @author evitaliy * @since 19 Mar 2018 */ +@RunWith(PowerMockRunner.class) @PrepareForTest({LoggingContext.class, ContextData.class}) -public class LoggingRequestFilterTest extends PowerMockTestCase { - - private static final Class DEFAULT_RESOURCE_CLASS = MockResource.class; - private static final Method DEFAULT_RESOURCE_METHOD = MockResource.class.getDeclaredMethods()[0]; - private static final String DEFAULT_SERVICE_NAME = - formatServiceName(DEFAULT_RESOURCE_CLASS, DEFAULT_RESOURCE_METHOD); +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(); - private static String formatServiceName(Class resourceClass, Method resourceMethod) { - return resourceClass.getName() + "#" + resourceMethod.getName(); - } + @Rule + public TestName testName = new TestName(); /** * Verify all mocks after each test. */ - @AfterMethod - public void verifyMocks(ITestResult result) { + @After + public void verifyMocks() { try { PowerMock.verifyAll(); } catch (AssertionError e) { - throw new AssertionError("Expectations failed in: " + result.getMethod().getMethodName(), e); + throw new AssertionError("Expectations failed in " + testName.getMethodName() + "()", e); } } @Test - public void notHandledWhenNoMatchingResource() { - - PowerMock.mockStatic(LoggingContext.class); - PowerMock.replay(LoggingContext.class); - - new LoggingRequestFilter().filter(mockEmptyContainerRequestContext()); - } - - @Test - public void serviceNamePopulatedWhenThereIsMatchingResourceAndConcreteType() { - - mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, null); - mockLoggingContext(); - - LoggingRequestFilter filter = new LoggingRequestFilter(); - filter.setResource(mockResource()); - - filter.filter(mockContainerRequestContext( - new RequestIdHeader(null), - new PartnerHeader(null))); - } - - @Test - public void serviceNamePopulatedWhenThereIsMatchingResourceAndJavaProxyType() throws NoSuchMethodException { - - Object proxyResource = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), - new Class[] {MockResource.class}, (proxy, method, arguments) -> null); - - final String serviceName = formatServiceName(MockResource.class, DEFAULT_RESOURCE_METHOD); + public void serviceNamePopulatedWhenThereIsMatchingResource() { - mockContextDataBuilder(null, serviceName, null); + mockContextDataBuilder(null, null, LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI)); mockLoggingContext(); LoggingRequestFilter filter = new LoggingRequestFilter(); - - Class proxyClass = proxyResource.getClass(); - Method proxyMethod = - proxyClass.getMethod(DEFAULT_RESOURCE_METHOD.getName(), DEFAULT_RESOURCE_METHOD.getParameterTypes()); - - filter.setResource(mockResource(proxyClass, proxyMethod)); + filter.setHttpRequest(mockHttpRequest(true)); filter.filter(mockContainerRequestContext( new RequestIdHeader(null), @@ -119,20 +83,14 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { } @Test - public void serviceNameIncludesProxyClassnameWhenJavaProxyTypeAndNoMatchingInterface() { - - Object proxyResource = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), - new Class[] {Comparable.class}, (proxy, method, arguments) -> null); + public void serviceNameDoesNotIncludeHttpMethodWhenHttpMethodDisabled() { - final String serviceName = formatServiceName(proxyResource.getClass(), DEFAULT_RESOURCE_METHOD); - - mockContextDataBuilder(null, serviceName, null); + mockContextDataBuilder(null, null, REQUEST_URI); mockLoggingContext(); LoggingRequestFilter filter = new LoggingRequestFilter(); - - Class proxyClass = proxyResource.getClass(); - filter.setResource(mockResource(proxyClass, DEFAULT_RESOURCE_METHOD)); + filter.setHttpMethodInServiceName(false); + filter.setHttpRequest(mockHttpRequest(false)); filter.filter(mockContainerRequestContext( new RequestIdHeader(null), @@ -142,11 +100,12 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { @Test public void partnerNamePopulatedWhenPresentInDefaultHeader() { - mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, RANDOM_PARTNER_NAME); + mockContextDataBuilder(null, RANDOM_PARTNER_NAME, + LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI)); mockLoggingContext(); LoggingRequestFilter filter = new LoggingRequestFilter(); - filter.setResource(mockResource()); + filter.setHttpRequest(mockHttpRequest(true)); filter.filter(mockContainerRequestContext( new RequestIdHeader(null), @@ -157,11 +116,12 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { public void partnerNamePopulatedWhenPresentInCustomHeader() { final String partnerHeader = "x-partner-header"; - mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, RANDOM_PARTNER_NAME); + mockContextDataBuilder(null, RANDOM_PARTNER_NAME, + LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI)); mockLoggingContext(); LoggingRequestFilter filter = new LoggingRequestFilter(); - filter.setResource(mockResource()); + filter.setHttpRequest(mockHttpRequest(true)); filter.setPartnerNameHeaders(partnerHeader); filter.filter(mockContainerRequestContext( @@ -172,11 +132,12 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { @Test public void requestIdPopulatedWhenPresentInDefaultHeader() { - mockContextDataBuilder(RANDOM_REQUEST_ID, DEFAULT_SERVICE_NAME, null); + mockContextDataBuilder(RANDOM_REQUEST_ID, null, + LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI)); mockLoggingContext(); LoggingRequestFilter filter = new LoggingRequestFilter(); - filter.setResource(mockResource()); + filter.setHttpRequest(mockHttpRequest(true)); filter.filter(mockContainerRequestContext( new RequestIdHeader(RANDOM_REQUEST_ID), @@ -187,35 +148,30 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { public void requestIdPopulatedWhenPresentInCustomHeader() { final String requestIdHeader = "x-request-id"; - mockContextDataBuilder(RANDOM_REQUEST_ID, DEFAULT_SERVICE_NAME, null); + mockContextDataBuilder(RANDOM_REQUEST_ID, null, + LoggingRequestFilter.formatServiceName(REQUEST_METHOD, REQUEST_URI)); mockLoggingContext(); LoggingRequestFilter filter = new LoggingRequestFilter(); - filter.setResource(mockResource()); filter.setRequestIdHeaders(requestIdHeader); + filter.setHttpRequest(mockHttpRequest(true)); filter.filter(mockContainerRequestContext( new RequestIdHeader(requestIdHeader, RANDOM_REQUEST_ID), new PartnerHeader(null))); } - private ResourceInfo mockResource() { - return mockResource(DEFAULT_RESOURCE_CLASS, DEFAULT_RESOURCE_METHOD); - } + private HttpServletRequest mockHttpRequest(boolean includeMethod) { - private ResourceInfo mockResource(Class resourceType, Method resourceMethod) { - ResourceInfo resource = EasyMock.mock(ResourceInfo.class); - //noinspection unchecked - EasyMock.expect(resource.getResourceClass()).andReturn(resourceType); - EasyMock.expect(resource.getResourceMethod()).andReturn(resourceMethod); - EasyMock.replay(resource); - return resource; - } + HttpServletRequest servletRequest = EasyMock.mock(HttpServletRequest.class); + EasyMock.expect(servletRequest.getRequestURI()).andReturn(REQUEST_URI); - private ContainerRequestContext mockEmptyContainerRequestContext() { - ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class); - EasyMock.replay(requestContext); - return requestContext; + if (includeMethod) { + EasyMock.expect(servletRequest.getMethod()).andReturn(REQUEST_METHOD); + } + + EasyMock.replay(servletRequest); + return servletRequest; } private ContainerRequestContext mockContainerRequestContext(Header... headers) { @@ -233,7 +189,7 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { return requestContext; } - private void mockContextDataBuilder(String requestId, String serviceName, String partnerName) { + private void mockContextDataBuilder(String requestId, String partnerName, String serviceName) { ContextData.ContextDataBuilder mockBuilder = EasyMock.mock(ContextData.ContextDataBuilder.class); @@ -243,9 +199,7 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { EasyMock.expect(mockBuilder.requestId(anyString())).andReturn(mockBuilder); } - if (serviceName != null) { - EasyMock.expect(mockBuilder.serviceName(serviceName)).andReturn(mockBuilder); - } + EasyMock.expect(mockBuilder.serviceName(serviceName)).andReturn(mockBuilder); if (partnerName != null) { EasyMock.expect(mockBuilder.partnerName(partnerName)).andReturn(mockBuilder); @@ -267,10 +221,10 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { PowerMock.mockStatic(LoggingContext.class); LoggingContext.clear(); - EasyMock.expectLastCall().once(); + EasyMock.expectLastCall(); LoggingContext.put(anyObject(ContextData.class)); - EasyMock.expectLastCall().once(); + EasyMock.expectLastCall(); PowerMock.replay(LoggingContext.class); } @@ -307,20 +261,4 @@ public class LoggingRequestFilterTest extends PowerMockTestCase { super(key, value); } } - - private interface MockResource { - - @SuppressWarnings("EmptyMethod") - void process(); - } - - private static class MockResourceImpl implements MockResource { - - @Override - public void process() { - // no-op - } - } - - } \ 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 37627d5d5a..710cf12b7e 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 @@ -19,15 +19,23 @@ package org.openecomp.sdc.logging.servlet.jaxrs; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.anyString; +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; @@ -35,10 +43,7 @@ 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.testng.PowerMockTestCase; -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.Test; +import org.powermock.modules.junit4.PowerMockRunner; /** @@ -47,183 +52,267 @@ import org.testng.annotations.Test; * @author evitaliy * @since 19 Mar 2018 */ -@PrepareForTest({LoggingContext.class, LoggerFactory.class}) -public class LoggingResponseFilterTest extends PowerMockTestCase { +@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. */ - @AfterMethod - public void verifyMocks(ITestResult result) { + @After + public void verifyMocks() { try { PowerMock.verifyAll(); } catch (AssertionError e) { - throw new AssertionError("Expectations failed in: " + result.getMethod().getMethodName(), e); + throw new AssertionError("Expectations failed in " + testName.getMethodName() + "()", e); } } @Test - public void noAuditWhenAuditDisabled() { - mockLogger(false, AuditData.builder().build()); - mockLoggingContext(); - new LoggingResponseFilter().filter(mockDisabledRequestContext(), mockDisabledResponseContext()); - } - - private void mockLogger(boolean enabled, AuditData auditData, Consumer... additionalMockings) { - - Logger logger = EasyMock.mock(Logger.class); + @PrepareForTest({LoggingContext.class, LoggerFactory.class}) + public void noAuditWhenNoMatchingResource() { - EasyMock.expect(logger.isAuditEnabled()).andReturn(enabled).atLeastOnce(); - - if (enabled) { - logger.audit(EasyMock.cmp(auditData, new AuditDataComparator(), LogicalOperator.EQUAL)); + PowerMock.mockStatic(LoggerFactory.class); + mockFilterLogger(logger -> { + logger.debug(anyString()); EasyMock.expectLastCall(); - } + }); + PowerMock.replay(LoggerFactory.class); - for (Consumer mocking : additionalMockings) { - mocking.accept(logger); - } + LoggingResponseFilter responseFilter = new LoggingResponseFilter(); + responseFilter.filter(mockDisabledRequestContext(), mockDisabledResponseContext()); + } - EasyMock.replay(logger); + @Test + @PrepareForTest({LoggingContext.class, LoggerFactory.class}) + public void noAuditWhenNullResource() { PowerMock.mockStatic(LoggerFactory.class); - LoggerFactory.getLogger(LoggingResponseFilter.class); - PowerMock.expectLastCall().andReturn(logger); + mockFilterLogger(logger -> { + logger.debug(anyString()); + EasyMock.expectLastCall(); + }); PowerMock.replay(LoggerFactory.class); - } - private void mockLoggingContext() { - PowerMock.mockStatic(LoggingContext.class); - LoggingContext.clear(); - EasyMock.expectLastCall().once(); - PowerMock.replay(LoggingContext.class); + LoggingResponseFilter responseFilter = new LoggingResponseFilter(); + responseFilter.setResource(null); + responseFilter.filter(mockDisabledRequestContext(), mockDisabledResponseContext()); } - private ContainerRequestContext mockDisabledRequestContext() { - ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class); - EasyMock.replay(requestContext); - return requestContext; - } + @Test + @PrepareForTest({LoggingContext.class, LoggerFactory.class}) + public void noAuditWhenAuditDisabled() { - private ContainerResponseContext mockDisabledResponseContext() { - ContainerResponseContext responseContext = EasyMock.mock(ContainerResponseContext.class); - EasyMock.replay(responseContext); - return responseContext; + 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 = "10.56.56.10"; + final String clientIp = "IP1"; final long startTime = 12345L; final Response.Status ok = Response.Status.OK; - mockLogger(true, buildAuditData(startTime, clientIp, ok, StatusCode.COMPLETE)); + PowerMock.mockStatic(LoggerFactory.class); + mockResourceLogger(true, buildAuditData(startTime, clientIp, ok, StatusCode.COMPLETE)); + mockFilterLogger(); + PowerMock.replay(LoggerFactory.class); - mockLoggingContext(); LoggingResponseFilter filter = new LoggingResponseFilter(); + filter.setResource(mockResource()); filter.setHttpRequest(mockHttpRequest(clientIp)); filter.filter(mockRequestContext(startTime), mockResponseContext(ok)); } - 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 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; - } - @Test + @PrepareForTest({LoggingContext.class, LoggerFactory.class}) public void startTimeZeroWhenNotPresentInRequestContext() { - final String clientIp = "10.56.56.12"; + final String clientIp = "IP2"; final Response.Status ok = Response.Status.OK; AuditData expectedAuditData = buildAuditData(0, clientIp, ok, StatusCode.COMPLETE); - mockLogger(true, expectedAuditData, logger -> { + PowerMock.mockStatic(LoggerFactory.class); + mockResourceLogger(true, expectedAuditData); + mockFilterLogger(logger -> { logger.error(anyString(), anyObject(Object[].class)); EasyMock.expectLastCall(); }); + PowerMock.replay(LoggerFactory.class); - mockLoggingContext(); 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 = "10.56.56.13"; + final String clientIp = "IP3"; final Response.Status accepted = Response.Status.ACCEPTED; AuditData expectedAuditData = buildAuditData(0, clientIp, accepted, StatusCode.COMPLETE); - mockLogger(true, expectedAuditData, logger -> { - logger.error(anyString(), new Object[] {anyString(), anyString()}); + PowerMock.mockStatic(LoggerFactory.class); + mockFilterLogger(logger -> { + logger.error(anyString(), anyString(), anyString(), anyObject()); EasyMock.expectLastCall(); }); + mockResourceLogger(true, expectedAuditData); + PowerMock.replay(LoggerFactory.class); - mockLoggingContext(); 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 = "10.56.56.13"; + final String clientIp = "IP13"; final long startTime = 88668603L; AuditData expectedAuditData = buildAuditData(startTime, clientIp, error, StatusCode.ERROR); - mockLogger(true, expectedAuditData); + PowerMock.mockStatic(LoggerFactory.class); + mockResourceLogger(true, expectedAuditData); + mockFilterLogger(); + PowerMock.replay(LoggerFactory.class); - mockLoggingContext(); 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... expectations) { + + Logger filterLogger = EasyMock.mock(Logger.class); + + for (Consumer 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 { @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(), one.getResponseDescription()) && one.getStartTime() == two - .getStartTime() && Objects.equals(one.getStatusCode(), two.getStatusCode())) { + 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; } @@ -231,4 +320,9 @@ public class LoggingResponseFilterTest extends PowerMockTestCase { return -1; } } + + interface Resource { + @SuppressWarnings("unused") + void method(); + } } \ No newline at end of file -- cgit 1.2.3-korg