Increase code coverage on aai-common: aai-els-onap-logging library
[aai/aai-common.git] / aai-els-onap-logging / src / test / java / org / onap / logging / ref / slf4j / ONAPLogAdapterTest.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.logging
4  * ================================================================================
5  * Copyright © 2018 Amdocs
6  * All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *    http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.logging.ref.slf4j;
23
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.slf4j.MDC;
27 import org.slf4j.event.Level;
28 import org.springframework.mock.web.MockHttpServletRequest;
29 import org.testng.Assert;
30 import org.testng.annotations.AfterMethod;
31 import org.testng.annotations.Test;
32
33 import javax.xml.bind.DatatypeConverter;
34 import java.util.HashMap;
35 import java.util.Map;
36 import java.util.UUID;
37
38 import static org.hamcrest.MatcherAssert.assertThat;
39 import static org.hamcrest.core.Is.is;
40 import static org.hamcrest.core.IsNot.not;
41 import static org.hamcrest.core.IsNull.notNullValue;
42 import static org.hamcrest.core.IsNull.nullValue;
43 import static org.hamcrest.core.IsSame.sameInstance;
44 import static org.hamcrest.core.StringEndsWith.endsWith;
45 import static org.hamcrest.number.OrderingComparison.lessThan;
46
47 /**
48  * Tests for {@link ONAPLogAdapter}.
49  */
50 public class ONAPLogAdapterTest {
51
52     /**
53      * Ensure that MDCs are cleared after each testcase.
54      */
55     @AfterMethod
56     public void resetMDCs() {
57         MDC.clear();
58     }
59
60     /**
61      * Test nullcheck.
62      */
63     @Test
64     public void testCheckNotNull() {
65
66         ONAPLogAdapter.checkNotNull("");
67
68         try {
69             ONAPLogAdapter.checkNotNull(null);
70             Assert.fail("Should throw NullPointerException");
71         }
72         catch (final NullPointerException e) {
73
74         }
75     }
76
77     /**
78      * Test defaulting of nulls.
79      */
80     @Test
81     public void testDefaultToEmpty() {
82         assertThat(ONAPLogAdapter.defaultToEmpty("123"), is("123"));
83         assertThat(ONAPLogAdapter.defaultToEmpty(Integer.valueOf(1984)), is("1984"));
84         assertThat(ONAPLogAdapter.defaultToEmpty(null), is(""));
85     }
86
87     /**
88      * Test defaulting of nulls.
89      */
90     @Test
91     public void testDefaultToUUID() {
92         assertThat(ONAPLogAdapter.defaultToUUID("123"), is("123"));
93         UUID.fromString(ONAPLogAdapter.defaultToUUID(null));
94     }
95
96     /**
97      * Test ENTERING.
98      */
99     @Test
100     public void testEntering() {
101
102         final Logger logger = LoggerFactory.getLogger(this.getClass());
103         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
104         final MockHttpServletRequest http = new MockHttpServletRequest();
105         http.setRequestURI("uri123");
106         http.setServerName("local123");
107         http.setRemoteAddr("remote123");
108         http.addHeader("X-ONAP-RequestID", "request123");
109         http.addHeader("X-InvocationID", "invocation123");
110         http.addHeader("X-ONAP-PartnerName", "partner123");
111
112         try {
113             adapter.getServiceDescriptor().setServiceName("uri123");
114             adapter.entering(http);
115             final Map<String, String> mdcs = MDC.getCopyOfContextMap();
116             assertThat(mdcs.get("RequestID"), is("request123"));
117             assertThat(mdcs.get("PartnerName"), is("partner123"));
118             assertThat(mdcs.get("ServiceName"), is("uri123"));
119             assertThat(mdcs.get("ServerFQDN"), is("local123"));
120             assertThat(mdcs.get("ClientIPAddress"), is("remote123"));
121
122             // Timestamp format and value:
123
124             final String invokeTimestampString = mdcs.get("InvokeTimestamp");
125             assertThat(invokeTimestampString, notNullValue());
126             assertThat(invokeTimestampString, endsWith("Z"));
127             final long invokeTimestamp = DatatypeConverter.parseDateTime(invokeTimestampString).getTimeInMillis();
128             assertThat(Math.abs(System.currentTimeMillis() - invokeTimestamp), lessThan(5000L));
129         }
130         finally {
131             MDC.clear();
132         }
133     }
134     
135     /**
136      * Test ENTERING with an EMPTY_STRING serviceName.
137      */
138     @Test
139     public void testEnteringWithEMPTY_STRING_serviceName() {
140
141         final Logger logger = LoggerFactory.getLogger(this.getClass());
142         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
143         final MockHttpServletRequest http = new MockHttpServletRequest();
144         http.setRequestURI("uri123");
145         http.setServerName("local123");
146         http.setRemoteAddr("remote123");
147         http.addHeader("X-ONAP-RequestID", "request123");
148         http.addHeader("X-InvocationID", "invocation123");
149         http.addHeader("X-ONAP-PartnerName", "partner123");
150
151         try {
152             // an empty string should kick in setting the actual service name (treated same as null)
153             adapter.getServiceDescriptor().setServiceName("");
154             adapter.entering(http);
155             final Map<String, String> mdcs = MDC.getCopyOfContextMap();
156             assertThat(mdcs.get("RequestID"), is("request123"));
157             assertThat(mdcs.get("PartnerName"), is("partner123"));
158             assertThat(mdcs.get("ServiceName"), is("uri123"));
159             assertThat(mdcs.get("ServerFQDN"), is("local123"));
160             assertThat(mdcs.get("ClientIPAddress"), is("remote123"));
161
162             // Timestamp format and value:
163
164             final String invokeTimestampString = mdcs.get("InvokeTimestamp");
165             assertThat(invokeTimestampString, notNullValue());
166             assertThat(invokeTimestampString, endsWith("Z"));
167             final long invokeTimestamp = DatatypeConverter.parseDateTime(invokeTimestampString).getTimeInMillis();
168             assertThat(Math.abs(System.currentTimeMillis() - invokeTimestamp), lessThan(5000L));
169         }
170         finally {
171             MDC.clear();
172         }
173     }
174
175     @Test
176     public void testSetServiceDescriptor() {
177         final ONAPLogAdapter.ServiceDescriptor override = new ONAPLogAdapter.ServiceDescriptor();
178         final Logger logger = LoggerFactory.getLogger(this.getClass());
179         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
180         final ONAPLogAdapter.ServiceDescriptor before = adapter.getServiceDescriptor();
181         adapter.setServiceDescriptor(override);
182         final ONAPLogAdapter.ServiceDescriptor after = adapter.getServiceDescriptor();
183         assertThat(after, not(sameInstance(before)));
184         assertThat(after, is(override));
185     }
186
187     @Test
188     public void testSetResponseDescriptor() {
189         final ONAPLogAdapter.ResponseDescriptor override = new ONAPLogAdapter.ResponseDescriptor();
190         final Logger logger = LoggerFactory.getLogger(this.getClass());
191         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
192         final ONAPLogAdapter.ResponseDescriptor before = adapter.getResponseDescriptor();
193         adapter.setResponseDescriptor(override);
194         final ONAPLogAdapter.ResponseDescriptor after = adapter.getResponseDescriptor();
195         assertThat(after, not(sameInstance(before)));
196         assertThat(after, is(override));
197     }
198
199     @Test
200     public void testUnwrap() {
201         final Logger logger = LoggerFactory.getLogger(this.getClass());
202         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
203         assertThat(adapter.unwrap(), is(logger));
204     }
205
206     /**
207      * Test EXITING.
208      */
209     @Test
210     public void testExiting() {
211
212         final Logger logger = LoggerFactory.getLogger(this.getClass());
213         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
214
215         try {
216             MDC.put("somekey", "somevalue");
217             assertThat(MDC.get("somekey"), is("somevalue"));
218             adapter.exiting();
219             assertThat(MDC.get("somekey"), nullValue());
220         }
221         finally {
222             MDC.clear();
223         }
224     }
225
226     /**
227      * Test INVOKE.
228      */
229     @Test
230     public void testInvokeSyncAsyncNull() {
231
232         final Logger logger = LoggerFactory.getLogger(this.getClass());
233         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
234
235         final UUID syncUUID = adapter.invoke(ONAPLogConstants.InvocationMode.SYNCHRONOUS);
236         assertThat(syncUUID, notNullValue());
237
238         final UUID asyncUUID = adapter.invoke(ONAPLogConstants.InvocationMode.SYNCHRONOUS);
239         assertThat(asyncUUID, notNullValue());
240
241         final UUID agnosticUUID = adapter.invoke((ONAPLogConstants.InvocationMode)null);
242         assertThat(agnosticUUID, notNullValue());
243
244     }
245
246     /**
247      * Test INVOKE, with RequestAdapter.
248      */
249     @Test
250     public void testInvokeWithAdapter() throws Exception {
251
252         final Logger logger = LoggerFactory.getLogger(this.getClass());
253         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
254
255         final Map<String, String> headers = new HashMap<>();
256         final ONAPLogAdapter.RequestBuilder builder = new ONAPLogAdapter.RequestBuilder<ONAPLogAdapter.RequestBuilder>() {
257             @Override
258             public ONAPLogAdapter.RequestBuilder setHeader(final String name, final String value) {
259                 headers.put(name, value);
260                 return this;
261             }
262         };
263
264         try {
265             final UUID uuid = adapter.invoke(builder, ONAPLogConstants.InvocationMode.SYNCHRONOUS);
266             assertThat(uuid, notNullValue());
267             assertThat(headers.get(ONAPLogConstants.Headers.INVOCATION_ID), is(uuid.toString()));
268             assertThat(headers.containsKey(ONAPLogConstants.Headers.PARTNER_NAME), is(true));
269             assertThat(headers.containsKey(ONAPLogConstants.Headers.REQUEST_ID), is(true));
270         }
271         finally {
272             MDC.clear();
273         }
274     }
275
276     /**
277      * Test INVOKE, with RequestAdapter.
278      */
279     @Test
280     public void testInvokeWithAdapterAndNull() throws Exception {
281
282         final Logger logger = LoggerFactory.getLogger(this.getClass());
283         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
284
285         final Map<String, String> headers = new HashMap<>();
286         final ONAPLogAdapter.RequestBuilder builder = new ONAPLogAdapter.RequestBuilder<ONAPLogAdapter.RequestBuilder>() {
287             @Override
288             public ONAPLogAdapter.RequestBuilder setHeader(final String name, final String value) {
289                 headers.put(name, value);
290                 return this;
291             }
292         };
293
294         try {
295             final UUID uuid = adapter.invoke(builder);
296             assertThat(uuid, notNullValue());
297             assertThat(headers.get(ONAPLogConstants.Headers.INVOCATION_ID), is(uuid.toString()));
298             assertThat(headers.containsKey(ONAPLogConstants.Headers.PARTNER_NAME), is(true));
299             assertThat(headers.containsKey(ONAPLogConstants.Headers.REQUEST_ID), is(true));
300         }
301         finally {
302             MDC.clear();
303         }
304     }
305
306     @Test
307     public void testHttpServletRequestAdapter() {
308
309         final UUID uuid = UUID.randomUUID();
310         final MockHttpServletRequest request = new MockHttpServletRequest();
311         request.addHeader("uuid", uuid.toString());
312         request.setRequestURI("/ctx0");
313         request.setServerName("srv0");
314
315         final ONAPLogAdapter.HttpServletRequestAdapter adapter
316                 = new ONAPLogAdapter.HttpServletRequestAdapter(request);
317         assertThat(adapter.getHeader("uuid"), is(uuid.toString()));
318         assertThat(adapter.getRequestURI(), is("/ctx0"));
319         assertThat(adapter.getServerAddress(), is("srv0"));
320     }
321
322     @Test
323     public void testServiceDescriptor() {
324         final String uuid = UUID.randomUUID().toString();
325
326         final ONAPLogAdapter.ServiceDescriptor adapter
327                 = new ONAPLogAdapter.ServiceDescriptor();
328         adapter.setServiceUUID(uuid);
329         adapter.setServiceName("name0");
330
331         assertThat(MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME), nullValue());
332         assertThat(MDC.get(ONAPLogConstants.MDCs.INSTANCE_UUID), nullValue());
333
334         adapter.setMDCs();
335
336         assertThat(MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME), is("name0"));
337         assertThat(MDC.get(ONAPLogConstants.MDCs.INSTANCE_UUID), is(uuid));
338     }
339
340     @Test
341     public void testResponseDescriptor() {
342         final String uuid = UUID.randomUUID().toString();
343
344         final ONAPLogAdapter.ResponseDescriptor adapter
345                 = new ONAPLogAdapter.ResponseDescriptor();
346         adapter.setResponseCode("code0");
347         adapter.setResponseDescription("desc0");
348         adapter.setResponseSeverity(Level.INFO);
349         adapter.setResponseStatus(ONAPLogConstants.ResponseStatus.COMPLETE);
350
351         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_CODE), nullValue());
352         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION), nullValue());
353         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_SEVERITY), nullValue());
354         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE), nullValue());
355
356         adapter.setMDCs();
357
358         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_CODE), is("code0"));
359         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION), is("desc0"));
360         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_SEVERITY), is("INFO"));
361         assertThat(MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE), is("COMPLETE"));
362     }
363
364     /**
365      * Exercise the contract, for a caller that's happy to have their
366      * service name automatically derived. (This validates nothing
367      * and achieves nothing; it's just to provide an example of minimal usage).
368      */
369     @Test
370     public void testContract() {
371
372         // Note no wrapper around HttpServletRequest, which will work for
373         // most invocations (since they come via HTTP), but otherwise
374         // can implement your own RequestAdapter.
375
376         final Logger logger = LoggerFactory.getLogger(this.getClass());
377         final ONAPLogAdapter adapter = new ONAPLogAdapter(logger);
378         final MockHttpServletRequest http = new MockHttpServletRequest();
379
380         // Immediately log ENTERING marker, with global MDCs.
381
382         adapter.entering(http);
383         try {
384
385             // Generate (and log) an invocationID, then use it to
386             // invoke another component.
387
388             final RESTClient client = new RESTClient();             // implements ONAPLogAdapter.RequestBuilder<RESTClient>.
389             adapter.invoke(client, ONAPLogConstants.InvocationMode.SYNCHRONOUS);
390             final RESTRequest request = null;                       // TODO: build real request.
391             final RESTResponse response = client.execute(request);  // TODO: handle real response.
392
393             // Set response details prior to #exiting.
394             // (Obviously there'd be errorhandling, etc. IRL).
395
396             adapter.getResponseDescriptor()
397                     .setResponseCode((String)null)
398                     .setResponseSeverity(Level.INFO)
399                     .setResponseStatus(ONAPLogConstants.ResponseStatus.COMPLETE);
400         }
401         finally {
402
403             // Return, logging EXIT marker, with response MDCs.
404
405             adapter.exiting();
406         }
407     }
408
409     /**
410      * Dummy class, for example code.
411      */
412     static class RESTClient implements ONAPLogAdapter.RequestBuilder<RESTClient> {
413
414         @Override
415         public RESTClient setHeader(final String name, final String value) {
416             return null;
417         }
418
419         RESTResponse execute(RESTRequest request) {
420             return null;
421         }
422     }
423
424     /**
425      * Dummy class, for example code.
426      */
427     static class RESTRequest {
428
429     }
430
431     /**
432      * Dummy class, for example code.
433      */
434     static class RESTResponse {
435
436     }
437 }