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
9 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.dcae.analytics.web.http;
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;
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;
56 * Eelf Audit log interceptor is used to log ECOMP Audit Logging
58 * @author Rajiv Singla
60 public class EelfAuditLogInterceptor implements ClientHttpRequestInterceptor, Ordered {
62 private static final EELFLogger logger = EELFLogFactory.getLogger(EelfAuditLogInterceptor.class);
64 private final ServiceLogInfo serviceLogInfo;
65 private final String targetEntityName;
67 public EelfAuditLogInterceptor(final HttpClientPreferences httpClientPreferences) {
68 this.serviceLogInfo = getServiceLogInfo(httpClientPreferences);
69 this.targetEntityName = getTargetEntityName(httpClientPreferences);
73 public ClientHttpResponse intercept(final HttpRequest request,
75 final ClientHttpRequestExecution execution) throws IOException {
77 final String requestId = AnalyticsHttpUtils.getRequestId(request.getHeaders());
78 final String transactionId = AnalyticsHttpUtils.getTransactionId(request.getHeaders());
80 ClientHttpResponse clientHttpResponse = null;
81 HttpStatus httpStatus = null;
82 String statusText = "";
83 String errorMessage = null;
84 final Date requestBeginTimeStamp = new Date();
86 clientHttpResponse = execution.execute(request, body);
87 httpStatus = clientHttpResponse.getStatusCode();
88 if (httpStatus.is2xxSuccessful()) {
90 statusText = clientHttpResponse.getStatusText();
92 errorMessage = StreamUtils.copyToString(clientHttpResponse.getBody(), Charset.defaultCharset());
93 statusText = clientHttpResponse.getStatusText();
95 } catch (IOException e) {
96 httpStatus = HttpStatus.SERVICE_UNAVAILABLE;
97 statusText = AnalyticsErrorType.TIMEOUT_ERROR.getErrorDescription();
98 errorMessage = e.toString();
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));
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);
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));
117 return clientHttpResponse != null ? clientHttpResponse : new SimpleClientHttpResponse();
121 public int getOrder() {
122 return LOWEST_PRECEDENCE;
125 private static ServiceLogInfo getServiceLogInfo(final HttpClientPreferences httpClientPreferences) {
126 return new ServiceLogInfoImpl(TcaModelConstants.TCA_SERVICE_NAME,
127 httpClientPreferences.getUsername(), "");
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);
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);
143 return new ResponseLogInfoImpl(AnalyticsErrorType.BUSINESS_PROCESS_ERROR.getErrorCode(),
146 return new ResponseLogInfoImpl(AnalyticsErrorType.UNKNOWN_ERROR.getErrorCode(), statusText);
150 private static TargetServiceLogInfo getTargetServiceLogInfo(final HttpRequest httpRequest,
151 final String targetEntityName) {
152 return new TargetServiceLogInfoImpl(targetEntityName, getTargetService(httpRequest),
153 getTargetVirtualEntity(httpRequest));
156 private static String getTargetVirtualEntity(final HttpRequest httpRequest) {
157 return httpRequest.getURI().getAuthority();
160 private static String getTargetService(final HttpRequest httpRequest) {
161 return httpRequest.getMethod() + "-" + httpRequest.getURI().getPath();
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";
178 private static class SimpleClientHttpResponse extends AbstractClientHttpResponse {
180 public int getRawStatusCode() throws IOException {
181 return HttpStatus.SERVICE_UNAVAILABLE.value();
185 public String getStatusText() throws IOException {
186 return HttpStatus.SERVICE_UNAVAILABLE.getReasonPhrase();
190 public void close() {
195 public InputStream getBody() throws IOException {
196 return new ByteArrayInputStream("".getBytes(Charset.forName(AnalyticsModelConstants.UTF8_CHARSET_NAME)));
200 public HttpHeaders getHeaders() {
201 return new HttpHeaders();