2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.logging.servlet.jaxrs;
19 import static org.easymock.EasyMock.anyObject;
20 import static org.easymock.EasyMock.anyString;
21 import static org.openecomp.sdc.logging.servlet.jaxrs.LoggingRequestFilter.START_TIME_KEY;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Proxy;
25 import java.util.UUID;
26 import javax.ws.rs.container.ContainerRequestContext;
27 import javax.ws.rs.container.ResourceInfo;
28 import org.easymock.EasyMock;
29 import org.openecomp.sdc.logging.LoggingConstants;
30 import org.openecomp.sdc.logging.api.ContextData;
31 import org.openecomp.sdc.logging.api.LoggingContext;
32 import org.powermock.api.easymock.PowerMock;
33 import org.powermock.core.classloader.annotations.PrepareForTest;
34 import org.powermock.modules.testng.PowerMockTestCase;
35 import org.testng.ITestResult;
36 import org.testng.annotations.AfterMethod;
37 import org.testng.annotations.Test;
40 * Unit testing JAX-RS request filter.
45 @PrepareForTest({LoggingContext.class, ContextData.class})
46 public class LoggingRequestFilterTest extends PowerMockTestCase {
48 private static final Class DEFAULT_RESOURCE_CLASS = MockResource.class;
49 private static final Method DEFAULT_RESOURCE_METHOD = MockResource.class.getDeclaredMethods()[0];
50 private static final String DEFAULT_SERVICE_NAME =
51 formatServiceName(DEFAULT_RESOURCE_CLASS, DEFAULT_RESOURCE_METHOD);
53 private static final String RANDOM_REQUEST_ID = UUID.randomUUID().toString();
55 private static final String RANDOM_PARTNER_NAME = UUID.randomUUID().toString();
57 private static String formatServiceName(Class resourceClass, Method resourceMethod) {
58 return resourceClass.getName() + "#" + resourceMethod.getName();
62 * Verify all mocks after each test.
65 public void verifyMocks(ITestResult result) {
68 PowerMock.verifyAll();
69 } catch (AssertionError e) {
70 throw new AssertionError("Expectations failed in: " + result.getMethod().getMethodName(), e);
75 public void notHandledWhenNoMatchingResource() {
77 PowerMock.mockStatic(LoggingContext.class);
78 PowerMock.replay(LoggingContext.class);
80 new LoggingRequestFilter().filter(mockEmptyContainerRequestContext());
84 public void serviceNamePopulatedWhenThereIsMatchingResourceAndConcreteType() {
86 mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, null);
89 LoggingRequestFilter filter = new LoggingRequestFilter();
90 filter.setResource(mockResource());
92 filter.filter(mockContainerRequestContext(
93 new RequestIdHeader(null),
94 new PartnerHeader(null)));
98 public void serviceNamePopulatedWhenThereIsMatchingResourceAndJavaProxyType() throws NoSuchMethodException {
100 Object proxyResource = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
101 new Class<?>[] {MockResource.class}, (proxy, method, arguments) -> null);
103 final String serviceName = formatServiceName(MockResource.class, DEFAULT_RESOURCE_METHOD);
105 mockContextDataBuilder(null, serviceName, null);
106 mockLoggingContext();
108 LoggingRequestFilter filter = new LoggingRequestFilter();
110 Class<?> proxyClass = proxyResource.getClass();
112 proxyClass.getMethod(DEFAULT_RESOURCE_METHOD.getName(), DEFAULT_RESOURCE_METHOD.getParameterTypes());
114 filter.setResource(mockResource(proxyClass, proxyMethod));
116 filter.filter(mockContainerRequestContext(
117 new RequestIdHeader(null),
118 new PartnerHeader(null)));
122 public void serviceNameIncludesProxyClassnameWhenJavaProxyTypeAndNoMatchingInterface() {
124 Object proxyResource = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
125 new Class<?>[] {Comparable.class}, (proxy, method, arguments) -> null);
127 final String serviceName = formatServiceName(proxyResource.getClass(), DEFAULT_RESOURCE_METHOD);
129 mockContextDataBuilder(null, serviceName, null);
130 mockLoggingContext();
132 LoggingRequestFilter filter = new LoggingRequestFilter();
134 Class<?> proxyClass = proxyResource.getClass();
135 filter.setResource(mockResource(proxyClass, DEFAULT_RESOURCE_METHOD));
137 filter.filter(mockContainerRequestContext(
138 new RequestIdHeader(null),
139 new PartnerHeader(null)));
143 public void partnerNamePopulatedWhenPresentInDefaultHeader() {
145 mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, RANDOM_PARTNER_NAME);
146 mockLoggingContext();
148 LoggingRequestFilter filter = new LoggingRequestFilter();
149 filter.setResource(mockResource());
151 filter.filter(mockContainerRequestContext(
152 new RequestIdHeader(null),
153 new PartnerHeader(RANDOM_PARTNER_NAME)));
157 public void partnerNamePopulatedWhenPresentInCustomHeader() {
159 final String partnerHeader = "x-partner-header";
160 mockContextDataBuilder(null, DEFAULT_SERVICE_NAME, RANDOM_PARTNER_NAME);
161 mockLoggingContext();
163 LoggingRequestFilter filter = new LoggingRequestFilter();
164 filter.setResource(mockResource());
165 filter.setPartnerNameHeaders(partnerHeader);
167 filter.filter(mockContainerRequestContext(
168 new RequestIdHeader(null),
169 new PartnerHeader(partnerHeader, RANDOM_PARTNER_NAME)));
173 public void requestIdPopulatedWhenPresentInDefaultHeader() {
175 mockContextDataBuilder(RANDOM_REQUEST_ID, DEFAULT_SERVICE_NAME, null);
176 mockLoggingContext();
178 LoggingRequestFilter filter = new LoggingRequestFilter();
179 filter.setResource(mockResource());
181 filter.filter(mockContainerRequestContext(
182 new RequestIdHeader(RANDOM_REQUEST_ID),
183 new PartnerHeader(null)));
187 public void requestIdPopulatedWhenPresentInCustomHeader() {
189 final String requestIdHeader = "x-request-id";
190 mockContextDataBuilder(RANDOM_REQUEST_ID, DEFAULT_SERVICE_NAME, null);
191 mockLoggingContext();
193 LoggingRequestFilter filter = new LoggingRequestFilter();
194 filter.setResource(mockResource());
195 filter.setRequestIdHeaders(requestIdHeader);
197 filter.filter(mockContainerRequestContext(
198 new RequestIdHeader(requestIdHeader, RANDOM_REQUEST_ID),
199 new PartnerHeader(null)));
202 private ResourceInfo mockResource() {
203 return mockResource(DEFAULT_RESOURCE_CLASS, DEFAULT_RESOURCE_METHOD);
206 private ResourceInfo mockResource(Class resourceType, Method resourceMethod) {
207 ResourceInfo resource = EasyMock.mock(ResourceInfo.class);
208 //noinspection unchecked
209 EasyMock.expect(resource.getResourceClass()).andReturn(resourceType);
210 EasyMock.expect(resource.getResourceMethod()).andReturn(resourceMethod);
211 EasyMock.replay(resource);
215 private ContainerRequestContext mockEmptyContainerRequestContext() {
216 ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
217 EasyMock.replay(requestContext);
218 return requestContext;
221 private ContainerRequestContext mockContainerRequestContext(Header... headers) {
223 ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
225 for (Header h : headers) {
226 EasyMock.expect(requestContext.getHeaderString(h.key)).andReturn(h.value);
229 requestContext.setProperty(EasyMock.eq(START_TIME_KEY), EasyMock.anyLong());
230 EasyMock.expectLastCall();
232 EasyMock.replay(requestContext);
233 return requestContext;
236 private void mockContextDataBuilder(String requestId, String serviceName, String partnerName) {
238 ContextData.ContextDataBuilder mockBuilder = EasyMock.mock(ContextData.ContextDataBuilder.class);
240 if (requestId != null) {
241 EasyMock.expect(mockBuilder.requestId(requestId)).andReturn(mockBuilder);
243 EasyMock.expect(mockBuilder.requestId(anyString())).andReturn(mockBuilder);
246 if (serviceName != null) {
247 EasyMock.expect(mockBuilder.serviceName(serviceName)).andReturn(mockBuilder);
250 if (partnerName != null) {
251 EasyMock.expect(mockBuilder.partnerName(partnerName)).andReturn(mockBuilder);
254 EasyMock.expect(mockBuilder.build()).andReturn(EasyMock.mock(ContextData.class));
255 EasyMock.replay(mockBuilder);
257 PowerMock.mockStatic(ContextData.class);
259 ContextData.builder();
260 PowerMock.expectLastCall().andReturn(mockBuilder);
262 PowerMock.replay(ContextData.class);
265 private void mockLoggingContext() {
267 PowerMock.mockStatic(LoggingContext.class);
269 LoggingContext.clear();
270 EasyMock.expectLastCall().once();
272 LoggingContext.put(anyObject(ContextData.class));
273 EasyMock.expectLastCall().once();
275 PowerMock.replay(LoggingContext.class);
278 private abstract static class Header {
280 private final String key;
281 private final String value;
283 private Header(String key, String value) {
289 private static class PartnerHeader extends Header {
291 private PartnerHeader(String value) {
292 super(LoggingConstants.DEFAULT_PARTNER_NAME_HEADER, value);
295 private PartnerHeader(String key, String value) {
300 private static class RequestIdHeader extends Header {
302 private RequestIdHeader(String value) {
303 super(LoggingConstants.DEFAULT_REQUEST_ID_HEADER, value);
306 private RequestIdHeader(String key, String value) {
311 private interface MockResource {
313 @SuppressWarnings("EmptyMethod")
317 private static class MockResourceImpl implements MockResource {
320 public void process() {