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;
22 import java.util.Comparator;
23 import java.util.Objects;
24 import java.util.function.Consumer;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.ws.rs.container.ContainerRequestContext;
27 import javax.ws.rs.container.ContainerResponseContext;
28 import javax.ws.rs.core.Response;
29 import org.easymock.EasyMock;
30 import org.easymock.LogicalOperator;
31 import org.openecomp.sdc.logging.api.AuditData;
32 import org.openecomp.sdc.logging.api.Logger;
33 import org.openecomp.sdc.logging.api.LoggerFactory;
34 import org.openecomp.sdc.logging.api.LoggingContext;
35 import org.openecomp.sdc.logging.api.StatusCode;
36 import org.powermock.api.easymock.PowerMock;
37 import org.powermock.core.classloader.annotations.PrepareForTest;
38 import org.powermock.modules.testng.PowerMockTestCase;
39 import org.testng.ITestResult;
40 import org.testng.annotations.AfterMethod;
41 import org.testng.annotations.Test;
45 * Unit testing JAX-RS response filter.
50 @PrepareForTest({LoggingContext.class, LoggerFactory.class})
51 public class LoggingResponseFilterTest extends PowerMockTestCase {
54 * Verify all mocks after each test.
57 public void verifyMocks(ITestResult result) {
60 PowerMock.verifyAll();
61 } catch (AssertionError e) {
62 throw new AssertionError("Expectations failed in: " + result.getMethod().getMethodName(), e);
67 public void noAuditWhenAuditDisabled() {
68 mockLogger(false, AuditData.builder().build());
70 new LoggingResponseFilter().filter(mockDisabledRequestContext(), mockDisabledResponseContext());
73 private void mockLogger(boolean enabled, AuditData auditData, Consumer<Logger>... additionalMockings) {
75 Logger logger = EasyMock.mock(Logger.class);
77 EasyMock.expect(logger.isAuditEnabled()).andReturn(enabled).atLeastOnce();
80 logger.audit(EasyMock.cmp(auditData, new AuditDataComparator(), LogicalOperator.EQUAL));
81 EasyMock.expectLastCall();
84 for (Consumer<Logger> mocking : additionalMockings) {
85 mocking.accept(logger);
88 EasyMock.replay(logger);
90 PowerMock.mockStatic(LoggerFactory.class);
91 LoggerFactory.getLogger(LoggingResponseFilter.class);
92 PowerMock.expectLastCall().andReturn(logger);
93 PowerMock.replay(LoggerFactory.class);
96 private void mockLoggingContext() {
97 PowerMock.mockStatic(LoggingContext.class);
98 LoggingContext.clear();
99 EasyMock.expectLastCall().once();
100 PowerMock.replay(LoggingContext.class);
103 private ContainerRequestContext mockDisabledRequestContext() {
104 ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
105 EasyMock.replay(requestContext);
106 return requestContext;
109 private ContainerResponseContext mockDisabledResponseContext() {
110 ContainerResponseContext responseContext = EasyMock.mock(ContainerResponseContext.class);
111 EasyMock.replay(responseContext);
112 return responseContext;
116 public void startTimeReadWhenPresentInRequestContext() {
118 final String clientIp = "10.56.56.10";
119 final long startTime = 12345L;
120 final Response.Status ok = Response.Status.OK;
122 mockLogger(true, buildAuditData(startTime, clientIp, ok, StatusCode.COMPLETE));
124 mockLoggingContext();
125 LoggingResponseFilter filter = new LoggingResponseFilter();
126 filter.setHttpRequest(mockHttpRequest(clientIp));
128 filter.filter(mockRequestContext(startTime), mockResponseContext(ok));
131 private AuditData buildAuditData(long startTime, String clientIp, Response.Status responseStatus,
133 return AuditData.builder().startTime(startTime).responseCode(Integer.toString(responseStatus.getStatusCode()))
134 .responseDescription(responseStatus.getReasonPhrase()).clientIpAddress(clientIp)
135 .statusCode(status).build();
138 private HttpServletRequest mockHttpRequest(String clientIp) {
139 HttpServletRequest servletRequest = EasyMock.mock(HttpServletRequest.class);
140 EasyMock.expect(servletRequest.getRemoteAddr()).andReturn(clientIp);
141 EasyMock.replay(servletRequest);
142 return servletRequest;
145 private ContainerRequestContext mockRequestContext(Object startTime) {
146 ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
147 EasyMock.expect(requestContext.getProperty(LoggingRequestFilter.START_TIME_KEY)).andReturn(startTime);
148 EasyMock.replay(requestContext);
149 return requestContext;
152 private ContainerResponseContext mockResponseContext(Response.StatusType statusInfo) {
153 ContainerResponseContext responseContext = EasyMock.mock(ContainerResponseContext.class);
154 EasyMock.expect(responseContext.getStatusInfo()).andReturn(statusInfo);
155 EasyMock.replay(responseContext);
156 return responseContext;
160 public void startTimeZeroWhenNotPresentInRequestContext() {
162 final String clientIp = "10.56.56.12";
163 final Response.Status ok = Response.Status.OK;
165 AuditData expectedAuditData = buildAuditData(0, clientIp, ok, StatusCode.COMPLETE);
167 mockLogger(true, expectedAuditData, logger -> {
168 logger.error(anyString(), anyObject(Object[].class));
169 EasyMock.expectLastCall();
172 mockLoggingContext();
173 LoggingResponseFilter filter = new LoggingResponseFilter();
174 filter.setHttpRequest(mockHttpRequest(clientIp));
176 filter.filter(mockRequestContext(null), mockResponseContext(ok));
180 public void startTimeZeroWhenIncorrectObjectType() {
182 final String clientIp = "10.56.56.13";
183 final Response.Status accepted = Response.Status.ACCEPTED;
185 AuditData expectedAuditData = buildAuditData(0, clientIp, accepted, StatusCode.COMPLETE);
187 mockLogger(true, expectedAuditData, logger -> {
188 logger.error(anyString(), new Object[] {anyString(), anyString()});
189 EasyMock.expectLastCall();
192 mockLoggingContext();
193 LoggingResponseFilter filter = new LoggingResponseFilter();
194 filter.setHttpRequest(mockHttpRequest(clientIp));
196 filter.filter(mockRequestContext("string object"), mockResponseContext(accepted));
200 public void statusErrorWhenHttpResponseGreaterThan399() {
202 final Response.Status error = Response.Status.BAD_REQUEST;
203 final String clientIp = "10.56.56.13";
204 final long startTime = 88668603L;
206 AuditData expectedAuditData = buildAuditData(startTime, clientIp, error, StatusCode.ERROR);
208 mockLogger(true, expectedAuditData);
210 mockLoggingContext();
211 LoggingResponseFilter filter = new LoggingResponseFilter();
212 filter.setHttpRequest(mockHttpRequest(clientIp));
214 filter.filter(mockRequestContext(startTime), mockResponseContext(error));
217 private static class AuditDataComparator implements Comparator<AuditData> {
220 public int compare(AuditData one, AuditData two) {
222 // don't compare end time as it changes
223 if (Objects.equals(one.getClientIpAddress(), two.getClientIpAddress()) && Objects
224 .equals(one.getResponseCode(), two.getResponseCode()) && Objects
225 .equals(one.getResponseDescription(), one.getResponseDescription()) && one.getStartTime() == two
226 .getStartTime() && Objects.equals(one.getStatusCode(), two.getStatusCode())) {