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