02745f6287e7c03a2b462109c7f2aafd26511797
[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;
18
19 import java.util.Objects;
20 import java.util.UUID;
21 import java.util.function.Consumer;
22 import java.util.function.Supplier;
23 import javax.servlet.http.HttpServletRequest;
24 import org.openecomp.sdc.logging.api.ContextData;
25 import org.openecomp.sdc.logging.api.LoggingContext;
26
27 /**
28  * Populates the context before a request is processed, and cleans it after the request has been processed.
29  *
30  * @author evitaliy
31  * @since 31 Jul 2018
32  */
33 public class ContextTracker implements Tracker {
34
35     private final HttpHeader partnerNameHeaders;
36     private final HttpHeader requestIdHeaders;
37
38     private final Supplier<Void> loggingContextClear;
39     private final Consumer<ContextData> loggingContextPut;
40
41     /**
42      * Constructs tracker to handle required logging context in Servlet-based applications. Refer to ONAP logging
43      * guidelines for fields required to be put on logging context.
44      *
45      * @param partnerNameHeaders HTTP headers to check for a partner name, cannot be null
46      * @param requestIdHeaders   HTTP headers to check for a request ID, cannot be null
47      */
48     public ContextTracker(HttpHeader partnerNameHeaders, HttpHeader requestIdHeaders) {
49         this.partnerNameHeaders = Objects.requireNonNull(partnerNameHeaders);
50         this.requestIdHeaders = Objects.requireNonNull(requestIdHeaders);
51         this.loggingContextPut = LoggingContext::put;
52         this.loggingContextClear = () -> {
53             LoggingContext.clear();
54             return null;
55         };
56     }
57
58     /**
59      * Package level constructor used for tests. Clean and Put are passed as functions
60      * in order to avoid static mock and service loader config - LoggingServiceProvider in LoggingContext
61      *
62      * @param partnerNameHeaders
63      * @param requestIdHeaders
64      * @param loggingContextClear
65      * @param loggingContextPut
66      */
67     ContextTracker(HttpHeader partnerNameHeaders,
68         HttpHeader requestIdHeaders,
69         Supplier<Void> loggingContextClear,
70         Consumer<ContextData> loggingContextPut) {
71         this.partnerNameHeaders = Objects.requireNonNull(partnerNameHeaders);
72         this.requestIdHeaders = Objects.requireNonNull(requestIdHeaders);
73         this.loggingContextPut = loggingContextPut;
74         this.loggingContextClear =loggingContextClear;
75     }
76
77     @Override
78     public void preRequest(HttpServletRequest request) {
79
80         loggingContextClear.get();
81
82         String serviceName = ServiceNameFormatter.format(request);
83         String requestId = requestIdHeaders.getAny(request::getHeader).orElse(UUID.randomUUID().toString());
84         ContextData.ContextDataBuilder contextBuilder =
85                 ContextData.builder().serviceName(serviceName).requestId(requestId);
86         String partnerName = partnerNameHeaders.getAny(request::getHeader).orElse("UNKNOWN");
87         contextBuilder.partnerName(partnerName);
88
89         loggingContextPut.accept(contextBuilder.build());
90     }
91
92     @Override
93     public void postRequest(RequestProcessingResult result) {
94         loggingContextClear.get();
95     }
96 }