aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilter.java62
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/servlet/jaxrs/LoggingRequestFilterTest.java90
2 files changed, 138 insertions, 14 deletions
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 06660f35f4..498587414a 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,6 +19,8 @@ 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.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
@@ -26,6 +28,8 @@ 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.HttpHeader;
@@ -60,6 +64,8 @@ public class LoggingRequestFilter implements ContainerRequestFilter {
static final String START_TIME_KEY = "audit.start.time";
+ private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRequestFilter.class);
+
private ResourceInfo resource;
private HttpHeader requestIdHeader = new HttpHeader(DEFAULT_REQUEST_ID_HEADER);
@@ -79,6 +85,7 @@ public class LoggingRequestFilter implements ContainerRequestFilter {
* Configuration parameter for request ID HTTP header.
*/
public void setRequestIdHeaders(String requestIdHeaders) {
+ LOGGER.debug("Valid request ID headers: {}", requestIdHeaders);
this.requestIdHeader = new HttpHeader(requestIdHeaders.split(MULTI_VALUE_SEPARATOR));
}
@@ -86,6 +93,7 @@ public class LoggingRequestFilter implements ContainerRequestFilter {
* Configuration parameter for partner name HTTP header.
*/
public void setPartnerNameHeaders(String partnerNameHeaders) {
+ LOGGER.debug("Valid partner name headers: {}", partnerNameHeaders);
this.partnerNameHeader = new HttpHeader(partnerNameHeaders.split(MULTI_VALUE_SEPARATOR));
}
@@ -95,6 +103,12 @@ public class LoggingRequestFilter implements ContainerRequestFilter {
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;
}
@@ -103,7 +117,7 @@ public class LoggingRequestFilter implements ContainerRequestFilter {
LoggingContext.clear();
ContextData.ContextDataBuilder contextData = ContextData.builder();
- contextData.serviceName(resource.getResourceClass().getName() + "." + resource.getResourceMethod().getName());
+ contextData.serviceName(getServiceName());
String partnerName = partnerNameHeader.getAny(containerRequestContext::getHeaderString);
if (partnerName != null) {
@@ -115,4 +129,50 @@ public class LoggingRequestFilter implements ContainerRequestFilter {
LoggingContext.put(contextData.build());
}
+
+ 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);
+ }
+
+ 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;
+ }
}
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 0e0be017df..579f41c3e6 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
@@ -21,6 +21,7 @@ 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.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ResourceInfo;
@@ -44,13 +45,19 @@ import org.testng.annotations.Test;
@PrepareForTest({LoggingContext.class, ContextData.class})
public class LoggingRequestFilterTest extends PowerMockTestCase {
- private static final Class RESOURCE_CLASS = MockResource.class;
- private static final Method RESOURCE_METHOD = MockResource.class.getDeclaredMethods()[0];
- private static final String RESOURCE_NAME = RESOURCE_CLASS.getName() + "." + RESOURCE_METHOD.getName();
+ 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);
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();
+ }
+
/**
* Verify all mocks after each test.
*/
@@ -74,9 +81,9 @@ public class LoggingRequestFilterTest extends PowerMockTestCase {
}
@Test
- public void serviceNamePopulatedWhenThereIsMatchingResource() {
+ public void serviceNamePopulatedWhenThereIsMatchingResourceAndConcreteType() {
- mockContextDataBuilder(null, RESOURCE_NAME, null);
+ mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, null);
mockLoggingContext();
LoggingRequestFilter filter = new LoggingRequestFilter();
@@ -88,9 +95,54 @@ public class LoggingRequestFilterTest extends PowerMockTestCase {
}
@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);
+
+ mockContextDataBuilder(null, serviceName, null);
+ 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.filter(mockContainerRequestContext(
+ new RequestIdHeader(null),
+ new PartnerHeader(null)));
+ }
+
+ @Test
+ public void serviceNameIncludesProxyClassnameWhenJavaProxyTypeAndNoMatchingInterface() {
+
+ Object proxyResource = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
+ new Class<?>[] {Comparable.class}, (proxy, method, arguments) -> null);
+
+ final String serviceName = formatServiceName(proxyResource.getClass(), DEFAULT_RESOURCE_METHOD);
+
+ mockContextDataBuilder(null, serviceName, null);
+ mockLoggingContext();
+
+ LoggingRequestFilter filter = new LoggingRequestFilter();
+
+ Class<?> proxyClass = proxyResource.getClass();
+ filter.setResource(mockResource(proxyClass, DEFAULT_RESOURCE_METHOD));
+
+ filter.filter(mockContainerRequestContext(
+ new RequestIdHeader(null),
+ new PartnerHeader(null)));
+ }
+
+ @Test
public void partnerNamePopulatedWhenPresentInDefaultHeader() {
- mockContextDataBuilder(null, RESOURCE_NAME, RANDOM_PARTNER_NAME);
+ mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, RANDOM_PARTNER_NAME);
mockLoggingContext();
LoggingRequestFilter filter = new LoggingRequestFilter();
@@ -105,7 +157,7 @@ public class LoggingRequestFilterTest extends PowerMockTestCase {
public void partnerNamePopulatedWhenPresentInCustomHeader() {
final String partnerHeader = "x-partner-header";
- mockContextDataBuilder(null, RESOURCE_NAME, RANDOM_PARTNER_NAME);
+ mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, RANDOM_PARTNER_NAME);
mockLoggingContext();
LoggingRequestFilter filter = new LoggingRequestFilter();
@@ -120,7 +172,7 @@ public class LoggingRequestFilterTest extends PowerMockTestCase {
@Test
public void requestIdPopulatedWhenPresentInDefaultHeader() {
- mockContextDataBuilder(RANDOM_REQUEST_ID, RESOURCE_NAME, null);
+ mockContextDataBuilder(RANDOM_REQUEST_ID, DEFAULT_SERVICE_NAME, null);
mockLoggingContext();
LoggingRequestFilter filter = new LoggingRequestFilter();
@@ -135,7 +187,7 @@ public class LoggingRequestFilterTest extends PowerMockTestCase {
public void requestIdPopulatedWhenPresentInCustomHeader() {
final String requestIdHeader = "x-request-id";
- mockContextDataBuilder(RANDOM_REQUEST_ID, RESOURCE_NAME, null);
+ mockContextDataBuilder(RANDOM_REQUEST_ID, DEFAULT_SERVICE_NAME, null);
mockLoggingContext();
LoggingRequestFilter filter = new LoggingRequestFilter();
@@ -148,10 +200,14 @@ public class LoggingRequestFilterTest extends PowerMockTestCase {
}
private ResourceInfo mockResource() {
+ return mockResource(DEFAULT_RESOURCE_CLASS, DEFAULT_RESOURCE_METHOD);
+ }
+
+ private ResourceInfo mockResource(Class resourceType, Method resourceMethod) {
ResourceInfo resource = EasyMock.mock(ResourceInfo.class);
//noinspection unchecked
- EasyMock.expect(resource.getResourceClass()).andReturn(RESOURCE_CLASS);
- EasyMock.expect(resource.getResourceMethod()).andReturn(RESOURCE_METHOD);
+ EasyMock.expect(resource.getResourceClass()).andReturn(resourceType);
+ EasyMock.expect(resource.getResourceMethod()).andReturn(resourceMethod);
EasyMock.replay(resource);
return resource;
}
@@ -252,11 +308,19 @@ public class LoggingRequestFilterTest extends PowerMockTestCase {
}
}
- private static class MockResource {
+ private interface MockResource {
@SuppressWarnings("EmptyMethod")
- void process() {
+ void process();
+ }
+
+ private static class MockResourceImpl implements MockResource {
+
+ @Override
+ public void process() {
// no-op
}
}
+
+
} \ No newline at end of file