Standalone TCA with EELF Logger
[dcaegen2/analytics/tca-gen2.git] / dcae-analytics / dcae-analytics-web / src / main / java / org / onap / dcae / analytics / web / http / EelfAuditLogInterceptor.java
1 /*
2  * ================================================================================
3  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ============LICENSE_END=========================================================
17  *
18  */
19
20 package org.onap.dcae.analytics.web.http;
21
22
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.nio.charset.Charset;
27 import java.util.Date;
28 import java.util.Locale;
29
30 import org.onap.dcae.analytics.model.AnalyticsModelConstants;
31 import org.onap.dcae.analytics.model.TcaModelConstants;
32 import org.onap.dcae.analytics.model.ecomplogger.AnalyticsErrorType;
33 import org.onap.dcae.analytics.web.util.AnalyticsHttpUtils;
34 import org.onap.dcae.utils.eelf.logger.api.info.ResponseLogInfo;
35 import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo;
36 import org.onap.dcae.utils.eelf.logger.api.info.TargetServiceLogInfo;
37 import org.onap.dcae.utils.eelf.logger.api.log.EELFLogFactory;
38 import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger;
39 import org.onap.dcae.utils.eelf.logger.model.info.RequestIdLogInfoImpl;
40 import org.onap.dcae.utils.eelf.logger.model.info.RequestTimingLogInfoImpl;
41 import org.onap.dcae.utils.eelf.logger.model.info.ResponseLogInfoImpl;
42 import org.onap.dcae.utils.eelf.logger.model.info.ServiceLogInfoImpl;
43 import org.onap.dcae.utils.eelf.logger.model.info.TargetServiceLogInfoImpl;
44 import org.onap.dcae.utils.eelf.logger.model.spec.MetricLogSpecImpl;
45 import org.springframework.core.Ordered;
46 import org.springframework.http.HttpHeaders;
47 import org.springframework.http.HttpRequest;
48 import org.springframework.http.HttpStatus;
49 import org.springframework.http.client.AbstractClientHttpResponse;
50 import org.springframework.http.client.ClientHttpRequestExecution;
51 import org.springframework.http.client.ClientHttpRequestInterceptor;
52 import org.springframework.http.client.ClientHttpResponse;
53 import org.springframework.util.StreamUtils;
54
55 /**
56  * Eelf Audit log interceptor is used to log ECOMP Audit Logging
57  *
58  * @author Rajiv Singla
59  */
60 public class EelfAuditLogInterceptor implements ClientHttpRequestInterceptor, Ordered {
61
62     private static final EELFLogger logger = EELFLogFactory.getLogger(EelfAuditLogInterceptor.class);
63
64     private final ServiceLogInfo serviceLogInfo;
65     private final String targetEntityName;
66
67     public EelfAuditLogInterceptor(final HttpClientPreferences httpClientPreferences) {
68         this.serviceLogInfo = getServiceLogInfo(httpClientPreferences);
69         this.targetEntityName = getTargetEntityName(httpClientPreferences);
70     }
71
72     @Override
73     public ClientHttpResponse intercept(final HttpRequest request,
74                                         final byte[] body,
75                                         final ClientHttpRequestExecution execution) throws IOException {
76
77         final String requestId = AnalyticsHttpUtils.getRequestId(request.getHeaders());
78         final String transactionId = AnalyticsHttpUtils.getTransactionId(request.getHeaders());
79
80         ClientHttpResponse clientHttpResponse = null;
81         HttpStatus httpStatus = null;
82         String statusText = "";
83         String errorMessage = null;
84         final Date requestBeginTimeStamp = new Date();
85         try {
86             clientHttpResponse = execution.execute(request, body);
87             httpStatus = clientHttpResponse.getStatusCode();
88             if (httpStatus.is2xxSuccessful()) {
89                 errorMessage = null;
90                 statusText = clientHttpResponse.getStatusText();
91             } else {
92                 errorMessage = StreamUtils.copyToString(clientHttpResponse.getBody(), Charset.defaultCharset());
93                 statusText = clientHttpResponse.getStatusText();
94             }
95         } catch (IOException e) {
96             httpStatus = HttpStatus.SERVICE_UNAVAILABLE;
97             statusText = AnalyticsErrorType.TIMEOUT_ERROR.getErrorDescription();
98             errorMessage = e.toString();
99         }
100         final Date requestEndTimeStamp = new Date();
101         final long elapsedTime = requestEndTimeStamp.getTime() - requestBeginTimeStamp.getTime();
102         final RequestTimingLogInfoImpl requestTimingLogInfo = new RequestTimingLogInfoImpl(requestBeginTimeStamp,
103                 requestEndTimeStamp, elapsedTime);
104         final MetricLogSpecImpl metricLogSpec = new MetricLogSpecImpl(new RequestIdLogInfoImpl(requestId),
105                 serviceLogInfo, requestTimingLogInfo,
106                 getResponseLogInfo(httpStatus, statusText), getTargetServiceLogInfo(request, targetEntityName));
107
108         if (errorMessage != null) {
109             logger.metricLog().error("Request Id: {}, Transaction Id: {}, Elapsed Time: {} ms, Error Message: {} ",
110                     metricLogSpec, requestId, transactionId, Long.toString(elapsedTime), errorMessage);
111         } else {
112             logger.metricLog().info("Request Id: {}, Transaction Id: {}, Elapsed Time: {} ms, REST Endpoint Call: {}",
113                     metricLogSpec, requestId, transactionId, Long.toString(elapsedTime),
114                     statusText + "-" + getTargetService(request));
115         }
116
117         return clientHttpResponse != null ? clientHttpResponse : new SimpleClientHttpResponse();
118     }
119
120     @Override
121     public int getOrder() {
122         return LOWEST_PRECEDENCE;
123     }
124
125     private static ServiceLogInfo getServiceLogInfo(final HttpClientPreferences httpClientPreferences) {
126         return new ServiceLogInfoImpl(TcaModelConstants.TCA_SERVICE_NAME,
127                 httpClientPreferences.getUsername(), "");
128     }
129
130     // translate well known http status code to corresponding Ecomp Logging error codes
131     private static ResponseLogInfo getResponseLogInfo(final HttpStatus httpStatus, final String statusText) {
132         if (httpStatus.is2xxSuccessful()) {
133             return new ResponseLogInfoImpl(AnalyticsErrorType.SUCCESSFUL.getErrorCode(), statusText);
134         } else if (httpStatus.is4xxClientError()) {
135             if (httpStatus == HttpStatus.UNAUTHORIZED || httpStatus == HttpStatus.FORBIDDEN) {
136                 return new ResponseLogInfoImpl(AnalyticsErrorType.PERMISSION_ERROR.getErrorCode(), statusText);
137             }
138             return new ResponseLogInfoImpl(AnalyticsErrorType.DATA_ERROR.getErrorCode(), statusText);
139         } else if (httpStatus.is5xxServerError()) {
140             if (httpStatus == HttpStatus.SERVICE_UNAVAILABLE) {
141                 return new ResponseLogInfoImpl(AnalyticsErrorType.TIMEOUT_ERROR.getErrorCode(), statusText);
142             }
143             return new ResponseLogInfoImpl(AnalyticsErrorType.BUSINESS_PROCESS_ERROR.getErrorCode(),
144                     statusText);
145         }
146         return new ResponseLogInfoImpl(AnalyticsErrorType.UNKNOWN_ERROR.getErrorCode(), statusText);
147     }
148
149
150     private static TargetServiceLogInfo getTargetServiceLogInfo(final HttpRequest httpRequest,
151                                                                 final String targetEntityName) {
152         return new TargetServiceLogInfoImpl(targetEntityName, getTargetService(httpRequest),
153                 getTargetVirtualEntity(httpRequest));
154     }
155
156     private static String getTargetVirtualEntity(final HttpRequest httpRequest) {
157         return httpRequest.getURI().getAuthority();
158     }
159
160     private static String getTargetService(final HttpRequest httpRequest) {
161         return httpRequest.getMethod() + "-" + httpRequest.getURI().getPath();
162     }
163
164     private static String getTargetEntityName(final HttpClientPreferences httpClientPreferences) {
165         final String simpleName = httpClientPreferences.getClass().getSimpleName().toUpperCase(Locale.getDefault());
166         if (simpleName.contains("MRSUB")) {
167             return "DMAAP_MR_SUBSCRIBER";
168         } else if (simpleName.contains("MRPUB")) {
169             return "DMAAP_MR_PUBLISHER";
170         } else if (simpleName.contains("AAI")) {
171             return "AAI_ENRICHMENT";
172         } else {
173             return "UNKNOWN";
174         }
175     }
176
177
178     private static class SimpleClientHttpResponse extends AbstractClientHttpResponse {
179         @Override
180         public int getRawStatusCode() throws IOException {
181             return HttpStatus.SERVICE_UNAVAILABLE.value();
182         }
183
184         @Override
185         public String getStatusText() throws IOException {
186             return HttpStatus.SERVICE_UNAVAILABLE.getReasonPhrase();
187         }
188
189         @Override
190         public void close() {
191             // do nothing
192         }
193
194         @Override
195         public InputStream getBody() throws IOException {
196             return new ByteArrayInputStream("".getBytes(Charset.forName(AnalyticsModelConstants.UTF8_CHARSET_NAME)));
197         }
198
199         @Override
200         public HttpHeaders getHeaders() {
201             return new HttpHeaders();
202         }
203     }
204
205
206 }