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