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.slf4j;
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNull;
22 import static org.onap.logging.ref.slf4j.ONAPLogConstants.ResponseStatus.COMPLETE;
24 import java.lang.reflect.InvocationHandler;
25 import java.lang.reflect.Method;
26 import java.lang.reflect.Proxy;
27 import java.util.Arrays;
29 import org.junit.Test;
30 import org.openecomp.sdc.logging.api.AuditData;
31 import org.openecomp.sdc.logging.api.MetricsData;
32 import org.slf4j.Logger;
34 import org.slf4j.Marker;
37 * Unit-test of SLF4J implementation of Logger.
42 @SuppressWarnings("CheckStyle")
43 public class SLF4JLoggerWrapperTest {
46 public void auditDoesNotFailWhenInputNull() {
47 new SLF4JLoggerWrapper(this.getClass()).auditExit(null);
51 public void metricsDoesNotFailWhenInputNull() {
52 new SLF4JLoggerWrapper(this.getClass()).metrics((MetricsData) null);
56 public void auditBeginTimeAvailableWhenPassed() {
57 SpyLogger spy = createSpy();
58 long start = System.currentTimeMillis();
59 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().startTime(start).build());
60 assertNotNull(spy.mdc().get(AuditField.BEGIN_TIMESTAMP.asKey()));
64 public void metricsBeginTimeAvailableWhenPassed() {
65 SpyLogger spy = createSpy();
66 long start = System.currentTimeMillis();
67 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().startTime(start).build());
68 assertNotNull(spy.mdc().get(MetricsField.BEGIN_TIMESTAMP.asKey()));
72 public void auditEndTimeAvailableWhenPassed() {
73 SpyLogger spy = createSpy();
74 long end = System.currentTimeMillis();
75 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().endTime(end).build());
76 assertNotNull(spy.mdc().get(AuditField.END_TIMESTAMP.asKey()));
80 public void metricsEndTimeAvailableWhenPassed() {
81 SpyLogger spy = createSpy();
82 long end = System.currentTimeMillis();
83 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().endTime(end).build());
84 assertNotNull(spy.mdc().get(MetricsField.END_TIMESTAMP.asKey()));
88 public void auditElapsedTimeAvailableWhenPassed() {
89 SpyLogger spy = createSpy();
90 long start = System.currentTimeMillis();
91 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder()
92 .startTime(start).endTime(start + 777).build());
93 assertEquals("777", spy.mdc().get(AuditField.ELAPSED_TIME.asKey()));
97 public void metricsElapsedTimeAvailableWhenPassed() {
98 SpyLogger spy = createSpy();
99 long start = System.currentTimeMillis();
100 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder()
101 .startTime(start).endTime(start + 1024).build());
102 assertEquals("1024", spy.mdc().get(MetricsField.ELAPSED_TIME.asKey()));
106 public void auditStatusCodeAvailableWhenPassed() {
107 SpyLogger spy = createSpy();
108 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().statusCode(COMPLETE).build());
109 assertEquals(COMPLETE.name(), spy.mdc().get(AuditField.STATUS_CODE.asKey()));
113 public void metricsStatusCodeAvailableWhenPassed() {
114 SpyLogger spy = createSpy();
115 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().statusCode(COMPLETE).build());
116 assertEquals(COMPLETE.name(), spy.mdc().get(MetricsField.STATUS_CODE.asKey()));
120 public void auditStatusCodeEmptyWhenNotPassed() {
121 SpyLogger spy = createSpy();
122 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().build());
123 assertNull(spy.mdc().get(AuditField.STATUS_CODE.asKey()));
127 public void metricsStatusCodeEmptyWhenNotPassed() {
128 SpyLogger spy = createSpy();
129 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().build());
130 assertNull(spy.mdc().get(MetricsField.STATUS_CODE.asKey()));
134 public void auditResponseCodeAvailableWhenPassed() {
135 final String responseCode = "AuditSpyResponse";
136 SpyLogger spy = createSpy();
137 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().responseCode(responseCode).build());
138 assertEquals(responseCode, spy.mdc().get(AuditField.RESPONSE_CODE.asKey()));
142 public void metricsResponseCodeAvailableWhenPassed() {
143 final String responseCode = "MetricsSpyResponse";
144 SpyLogger spy = createSpy();
145 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().responseCode(responseCode).build());
146 assertEquals(responseCode, spy.mdc().get(MetricsField.RESPONSE_CODE.asKey()));
150 public void auditResponseCodeEmptyWhenNotPassed() {
151 SpyLogger spy = createSpy();
152 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().build());
153 assertNull(spy.mdc().get(AuditField.RESPONSE_CODE.asKey()));
157 public void metricsResponseCodeEmptyWhenNotPassed() {
158 SpyLogger spy = createSpy();
159 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().build());
160 assertNull(spy.mdc().get(MetricsField.RESPONSE_CODE.asKey()));
164 public void auditResponseDescriptionAvailableWhenPassed() {
165 final String responseDescription = "AuditSpyDescription";
166 SpyLogger spy = createSpy();
167 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().responseDescription(responseDescription).build());
168 assertEquals(responseDescription, spy.mdc().get(AuditField.RESPONSE_DESCRIPTION.asKey()));
172 public void metricsResponseDescriptionAvailableWhenPassed() {
173 final String responseDescription = "MetricsSpyDescription";
174 SpyLogger spy = createSpy();
175 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().responseDescription(responseDescription).build());
176 assertEquals(responseDescription, spy.mdc().get(MetricsField.RESPONSE_DESCRIPTION.asKey()));
180 public void auditResponseDescriptionEmptyWhenNotPassed() {
181 SpyLogger spy = createSpy();
182 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().build());
183 assertNull(spy.mdc().get(AuditField.RESPONSE_DESCRIPTION.asKey()));
187 public void metricsResponseDescriptionEmptyWhenNotPassed() {
188 SpyLogger spy = createSpy();
189 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().build());
190 assertNull(spy.mdc().get(MetricsField.RESPONSE_DESCRIPTION.asKey()));
194 public void auditClientIpAddressAvailableWhenPassed() {
195 final String ipAddress = "10.56.20.20";
196 SpyLogger spy = createSpy();
197 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().clientIpAddress(ipAddress).build());
198 assertEquals(ipAddress, spy.mdc().get(AuditField.CLIENT_IP_ADDRESS.asKey()));
202 public void metricsClientIpAddressAvailableWhenPassed() {
203 final String ipAddress = "10.56.20.22";
204 SpyLogger spy = createSpy();
205 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().clientIpAddress(ipAddress).build());
206 assertEquals(ipAddress, spy.mdc().get(MetricsField.CLIENT_IP_ADDRESS.asKey()));
210 public void auditClientIpAddressEmptyWhenNotPassed() {
211 SpyLogger spy = createSpy();
212 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().build());
213 assertNull(spy.mdc().get(AuditField.CLIENT_IP_ADDRESS.asKey()));
217 public void metricsClientIpAddressEmptyWhenNotPassed() {
218 SpyLogger spy = createSpy();
219 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().build());
220 assertNull(spy.mdc().get(MetricsField.CLIENT_IP_ADDRESS.asKey()));
224 public void auditInvocationIdAvailable() {
225 SpyLogger spy = createSpy();
226 new SLF4JLoggerWrapper(spy).auditExit(AuditData.builder().build());
227 assertNotNull(spy.mdc().get(AuditField.INVOCATION_ID.asKey()));
231 public void metricsTargetEntityAvailableWhenPassed() {
232 final String targetEntity = "MetricsTargetEntity";
233 SpyLogger spy = createSpy();
234 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().targetEntity(targetEntity).build());
235 assertEquals(targetEntity, spy.mdc().get(MetricsField.TARGET_ENTITY.asKey()));
239 public void metricsTargetEntityEmptyWhenNotPassed() {
240 SpyLogger spy = createSpy();
241 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().build());
242 assertNull(spy.mdc().get(MetricsField.TARGET_ENTITY.asKey()));
246 public void metricsTargetVirtualEntityAvailableWhenPassed() {
247 final String targetEntity = "MetricsTargetVirtualEntity";
248 SpyLogger spy = createSpy();
249 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().targetVirtualEntity(targetEntity).build());
250 assertEquals(targetEntity, spy.mdc().get(MetricsField.TARGET_VIRTUAL_ENTITY.asKey()));
254 public void metricsTargetVirtualEntityEmptyWhenNotPassed() {
255 SpyLogger spy = createSpy();
256 new SLF4JLoggerWrapper(spy).metrics(MetricsData.builder().build());
257 assertNull(spy.mdc().get(MetricsField.TARGET_VIRTUAL_ENTITY.asKey()));
260 interface SpyLogger extends Logger {
261 Map<String, String> mdc();
265 * Creates a in instance of Logger that can be used to track MDC changes as part of an invocation of
268 * @return object that implements {@link SpyLogger}
270 private static SpyLogger createSpy() {
272 // build a dynamic proxy to avoid implementing the long list of Logger methods
273 // when we actually need just Logger.info() with the audit marker
274 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
275 return (SpyLogger) Proxy.newProxyInstance(classLoader, new Class<?>[] {SpyLogger.class},
276 new SpyingInvocationHandler());
279 private static class SpyingInvocationHandler implements InvocationHandler {
281 private Map<String, String> lastMdc;
284 public Object invoke(Object proxy, Method method, Object[] args) {
286 if (isReturnMdcMethod(method)) {
290 if (!isAuditMethod(method, args) && !isMetricsMethod(method, args)) {
291 throw new UnsupportedOperationException("Method " + method.getName() + " with arguments "
292 + Arrays.toString(args) + " wasn't supposed to be called");
299 private boolean isMetricsMethod(Method method, Object[] args) {
300 return isSpecialLogMethod(method, args, Markers.METRICS);
303 private boolean isAuditMethod(Method method, Object[] args) {
304 return isSpecialLogMethod(method, args, Markers.EXIT);
307 private boolean isSpecialLogMethod(Method method, Object[] args, Marker marker) {
308 return method.getName().equals("info") && args.length > 0 && args[0].equals(marker);
311 private void storeEffectiveMdc() {
312 lastMdc = MDC.getCopyOfContextMap();
315 private boolean isReturnMdcMethod(Method method) {
316 return method.equals(SpyLogger.class.getDeclaredMethods()[0]);