37627d5d5a15cb9475293994e83d6faaa23be0aa
[sdc.git] /
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.openecomp.sdc.logging.servlet.jaxrs;
18
19 import static org.easymock.EasyMock.anyObject;
20 import static org.easymock.EasyMock.anyString;
21
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;
42
43
44 /**
45  * Unit testing JAX-RS response filter.
46  *
47  * @author evitaliy
48  * @since 19 Mar 2018
49  */
50 @PrepareForTest({LoggingContext.class, LoggerFactory.class})
51 public class LoggingResponseFilterTest extends PowerMockTestCase {
52
53     /**
54      * Verify all mocks after each test.
55      */
56     @AfterMethod
57     public void verifyMocks(ITestResult result) {
58
59         try {
60             PowerMock.verifyAll();
61         } catch (AssertionError e) {
62             throw new AssertionError("Expectations failed in: " + result.getMethod().getMethodName(), e);
63         }
64     }
65
66     @Test
67     public void noAuditWhenAuditDisabled() {
68         mockLogger(false, AuditData.builder().build());
69         mockLoggingContext();
70         new LoggingResponseFilter().filter(mockDisabledRequestContext(), mockDisabledResponseContext());
71     }
72
73     private void mockLogger(boolean enabled, AuditData auditData, Consumer<Logger>... additionalMockings) {
74
75         Logger logger = EasyMock.mock(Logger.class);
76
77         EasyMock.expect(logger.isAuditEnabled()).andReturn(enabled).atLeastOnce();
78
79         if (enabled) {
80             logger.audit(EasyMock.cmp(auditData, new AuditDataComparator(), LogicalOperator.EQUAL));
81             EasyMock.expectLastCall();
82         }
83
84         for (Consumer<Logger> mocking : additionalMockings) {
85             mocking.accept(logger);
86         }
87
88         EasyMock.replay(logger);
89
90         PowerMock.mockStatic(LoggerFactory.class);
91         LoggerFactory.getLogger(LoggingResponseFilter.class);
92         PowerMock.expectLastCall().andReturn(logger);
93         PowerMock.replay(LoggerFactory.class);
94     }
95
96     private void mockLoggingContext() {
97         PowerMock.mockStatic(LoggingContext.class);
98         LoggingContext.clear();
99         EasyMock.expectLastCall().once();
100         PowerMock.replay(LoggingContext.class);
101     }
102
103     private ContainerRequestContext mockDisabledRequestContext() {
104         ContainerRequestContext requestContext = EasyMock.mock(ContainerRequestContext.class);
105         EasyMock.replay(requestContext);
106         return requestContext;
107     }
108
109     private ContainerResponseContext mockDisabledResponseContext() {
110         ContainerResponseContext responseContext = EasyMock.mock(ContainerResponseContext.class);
111         EasyMock.replay(responseContext);
112         return responseContext;
113     }
114
115     @Test
116     public void startTimeReadWhenPresentInRequestContext() {
117
118         final String clientIp = "10.56.56.10";
119         final long startTime = 12345L;
120         final Response.Status ok = Response.Status.OK;
121
122         mockLogger(true, buildAuditData(startTime, clientIp, ok, StatusCode.COMPLETE));
123
124         mockLoggingContext();
125         LoggingResponseFilter filter = new LoggingResponseFilter();
126         filter.setHttpRequest(mockHttpRequest(clientIp));
127
128         filter.filter(mockRequestContext(startTime), mockResponseContext(ok));
129     }
130
131     private AuditData buildAuditData(long startTime, String clientIp, Response.Status responseStatus,
132             StatusCode status) {
133         return AuditData.builder().startTime(startTime).responseCode(Integer.toString(responseStatus.getStatusCode()))
134                         .responseDescription(responseStatus.getReasonPhrase()).clientIpAddress(clientIp)
135                         .statusCode(status).build();
136     }
137
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;
143     }
144
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;
150     }
151
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;
157     }
158
159     @Test
160     public void startTimeZeroWhenNotPresentInRequestContext() {
161
162         final String clientIp = "10.56.56.12";
163         final Response.Status ok = Response.Status.OK;
164
165         AuditData expectedAuditData = buildAuditData(0, clientIp, ok, StatusCode.COMPLETE);
166
167         mockLogger(true, expectedAuditData, logger -> {
168             logger.error(anyString(), anyObject(Object[].class));
169             EasyMock.expectLastCall();
170         });
171
172         mockLoggingContext();
173         LoggingResponseFilter filter = new LoggingResponseFilter();
174         filter.setHttpRequest(mockHttpRequest(clientIp));
175
176         filter.filter(mockRequestContext(null), mockResponseContext(ok));
177     }
178
179     @Test
180     public void startTimeZeroWhenIncorrectObjectType() {
181
182         final String clientIp = "10.56.56.13";
183         final Response.Status accepted = Response.Status.ACCEPTED;
184
185         AuditData expectedAuditData = buildAuditData(0, clientIp, accepted, StatusCode.COMPLETE);
186
187         mockLogger(true, expectedAuditData, logger -> {
188             logger.error(anyString(), new Object[] {anyString(), anyString()});
189             EasyMock.expectLastCall();
190         });
191
192         mockLoggingContext();
193         LoggingResponseFilter filter = new LoggingResponseFilter();
194         filter.setHttpRequest(mockHttpRequest(clientIp));
195
196         filter.filter(mockRequestContext("string object"), mockResponseContext(accepted));
197     }
198
199     @Test
200     public void statusErrorWhenHttpResponseGreaterThan399() {
201
202         final Response.Status error = Response.Status.BAD_REQUEST;
203         final String clientIp = "10.56.56.13";
204         final long startTime = 88668603L;
205
206         AuditData expectedAuditData = buildAuditData(startTime, clientIp, error, StatusCode.ERROR);
207
208         mockLogger(true, expectedAuditData);
209
210         mockLoggingContext();
211         LoggingResponseFilter filter = new LoggingResponseFilter();
212         filter.setHttpRequest(mockHttpRequest(clientIp));
213
214         filter.filter(mockRequestContext(startTime), mockResponseContext(error));
215     }
216
217     private static class AuditDataComparator implements Comparator<AuditData> {
218
219         @Override
220         public int compare(AuditData one, AuditData two) {
221
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())) {
227
228                 return 0;
229             }
230
231             return -1;
232         }
233     }
234 }