2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ===================================================================
8 * Unless otherwise specified, all software contained herein is licensed
9 * under the Apache License, Version 2.0 (the "License");
10 * you may not use this software except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * Unless otherwise specified, all documentation contained herein is licensed
22 * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
23 * you may not use this documentation except in compliance with the License.
24 * You may obtain a copy of the License at
26 * https://creativecommons.org/licenses/by/4.0/
28 * Unless required by applicable law or agreed to in writing, documentation
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
34 * ============LICENSE_END============================================
36 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
38 package org.onap.portalapp.portal.logging.aop;
40 import java.net.InetAddress;
41 import java.text.ParseException;
42 import java.text.SimpleDateFormat;
43 import java.util.Date;
44 import java.util.UUID;
46 import javax.servlet.http.HttpServletRequest;
48 import org.onap.portalapp.portal.domain.EPUser;
49 import org.onap.portalapp.portal.utils.EPCommonSystemProperties;
50 import org.onap.portalapp.util.EPUserUtils;
51 import org.onap.portalsdk.core.exception.SessionExpiredException;
52 import org.onap.portalsdk.core.logging.format.AlarmSeverityEnum;
53 import org.onap.portalsdk.core.logging.format.AuditLogFormatter;
54 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
55 import org.onap.portalsdk.core.util.SystemProperties;
56 import org.onap.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum;
57 import org.onap.portalsdk.core.web.support.UserUtils;
60 import com.att.eelf.configuration.Configuration;
62 @org.springframework.context.annotation.Configuration
63 public class EPEELFLoggerAdvice {
65 private EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EPEELFLoggerAdvice.class);
68 * DateTime Format according to the ECOMP Application Logging Guidelines.
72 * @return Current date and time in the format specified by the ECOMP
73 * Application Logging Guidelines.
75 public static String getCurrentDateTimeUTC() {
76 SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
77 String currentDateTime = ecompLogDateFormat.format(new Date());
78 return currentDateTime;
82 * Sets logging context with values from HttpServletRequest object.
86 * @param securityEventType
87 * SecurityEventTypeEnum
89 public void loadServletRequestBasedDefaults(HttpServletRequest req, SecurityEventTypeEnum securityEventType) {
91 setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, req.getServletPath());
92 } catch (Exception e) {
93 adviceLogger.error(EELFLoggerDelegate.errorLogger, "loadServletRequestBasedDefaults failed", e);
99 * @param securityEventType
102 * @return Object array
104 public Object[] before(SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) {
105 String className = "";
106 if (passOnArgs.length > 0 && passOnArgs[0] != null)
107 className = passOnArgs[0].toString();
108 String methodName = EPCommonSystemProperties.ECOMP_PORTAL_BE;
109 if (passOnArgs.length > 1 && passOnArgs[1] != null)
110 methodName = passOnArgs[1].toString();
112 // Initialize Request defaults only for controller methods.
113 MDC.put(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
114 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
115 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
116 if (MDC.get(Configuration.MDC_KEY_REQUEST_ID) == null||MDC.get(Configuration.MDC_KEY_REQUEST_ID).isEmpty()){
117 String requestId = UUID.randomUUID().toString();
118 MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
120 MDC.put(EPCommonSystemProperties.PARTNER_NAME, "Unknown");
121 MDC.put(Configuration.MDC_SERVICE_NAME, EPCommonSystemProperties.ECOMP_PORTAL_BE);
123 if (securityEventType != null) {
124 MDC.put(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
125 getCurrentDateTimeUTC());
126 HttpServletRequest req = null;
127 if (args.length > 0 && args[0] != null && args[0] instanceof HttpServletRequest) {
128 req = (HttpServletRequest) args[0];
129 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
133 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
134 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#before: entering {}", methodName);
135 return new Object[] { "" };
140 * @param securityEventType
142 * @param responseCode
147 public void after(SecurityEventTypeEnum securityEventType, String statusCode, String responseCode, Object[] args,
148 Object[] returnArgs, Object[] passOnArgs) {
149 String className = "";
150 if (passOnArgs.length > 0 && passOnArgs[0] != null)
151 className = passOnArgs[0].toString();
153 String methodName = EPCommonSystemProperties.ECOMP_PORTAL_BE;
154 if (passOnArgs.length > 1 && passOnArgs[1] != null)
155 methodName = passOnArgs[1].toString();
157 if (MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME) == null
158 || MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME) == "")
159 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
161 if (MDC.get(EPCommonSystemProperties.TARGET_ENTITY) == null
162 || MDC.get(EPCommonSystemProperties.TARGET_ENTITY) == "")
163 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
165 if (MDC.get(Configuration.MDC_KEY_REQUEST_ID) == null||MDC.get(Configuration.MDC_KEY_REQUEST_ID).isEmpty()){
166 String requestId = UUID.randomUUID().toString();
167 MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
169 MDC.put(EPCommonSystemProperties.PARTNER_NAME, "Unknown");
170 MDC.put(Configuration.MDC_SERVICE_NAME, EPCommonSystemProperties.ECOMP_PORTAL_BE);
173 MDC.put(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP,
174 MDC.get(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP));
175 MDC.put(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
176 this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP),
177 MDC.get(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP));
179 // Making sure to reload the INCOMING request MDC defaults if they have
180 // been wiped out by either Outgoing or LDAP Phone book search
182 if (securityEventType != null && args.length > 0 && args[0] != null && args[0] instanceof HttpServletRequest
183 && securityEventType == SecurityEventTypeEnum.INCOMING_REST_MESSAGE
184 && (MDC.get(EPCommonSystemProperties.FULL_URL) == null
185 || MDC.get(EPCommonSystemProperties.FULL_URL).isEmpty())) {
186 HttpServletRequest req = (HttpServletRequest) args[0];
187 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
190 // Use external API response code in case if it resulted in an error.
191 String externalAPIResponseCode = MDC.get(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
192 if (externalAPIResponseCode == null || externalAPIResponseCode == ""
193 || externalAPIResponseCode.trim().equalsIgnoreCase("200")) {
194 MDC.put(EPCommonSystemProperties.RESPONSE_CODE, responseCode);
195 MDC.put(EPCommonSystemProperties.STATUS_CODE, statusCode);
197 MDC.put(EPCommonSystemProperties.RESPONSE_CODE, externalAPIResponseCode);
198 MDC.put(EPCommonSystemProperties.STATUS_CODE, "ERROR");
201 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
202 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#after: finished {}", methodName);
203 // add the metrics log
204 logger.info(EELFLoggerDelegate.metricsLogger, methodName + " operation is completed.");
206 // Log security message, if necessary
207 if (securityEventType != null) {
208 MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
209 MDC.get(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP));
210 MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
211 this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP),
212 MDC.get(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP));
214 this.logSecurityMessage(logger, securityEventType, methodName);
216 // Outgoing & LDAP messages are part of Incoming requests so,
217 // keep "RequestId", "PartnerName", "ServiceName", "LoginId" &
218 // "ResponseCode" etc. in memory and remove it only when
219 // finished processing the parent incoming message.
220 if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
221 && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
222 MDC.remove(Configuration.MDC_KEY_REQUEST_ID);
223 MDC.remove(EPCommonSystemProperties.PARTNER_NAME);
224 MDC.remove(Configuration.MDC_SERVICE_NAME);
225 MDC.remove(EPCommonSystemProperties.MDC_LOGIN_ID);
226 MDC.remove(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
228 MDC.remove(Configuration.MDC_KEY_REQUEST_ID);
229 MDC.remove(EPCommonSystemProperties.PARTNER_NAME);
230 MDC.remove(Configuration.MDC_SERVICE_NAME);
233 // clear when finishes audit logging
234 MDC.remove(EPCommonSystemProperties.FULL_URL);
235 MDC.remove(EPCommonSystemProperties.PROTOCOL);
236 MDC.remove(EPCommonSystemProperties.STATUS_CODE);
237 MDC.remove(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
238 MDC.remove(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
239 MDC.remove(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP);
240 MDC.remove(EPCommonSystemProperties.RESPONSE_CODE);
242 MDC.remove(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
243 MDC.remove(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
244 MDC.remove(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP);
245 MDC.remove(EPCommonSystemProperties.MDC_TIMER);
246 MDC.remove(EPCommonSystemProperties.TARGET_ENTITY);
247 MDC.remove(EPCommonSystemProperties.TARGET_SERVICE_NAME);
254 * @param securityEventType
257 private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType,
259 StringBuilder additionalInfoAppender = new StringBuilder();
260 String auditMessage = "";
262 if (securityEventType == SecurityEventTypeEnum.OUTGOING_REST_MESSAGE) {
263 additionalInfoAppender.append(String.format("%s '%s' request was initiated.", restMethod,
264 MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME)));
265 } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
266 additionalInfoAppender.append("LDAP Phonebook search operation is performed.");
268 additionalInfoAppender.append(String.format("%s request was received.", restMethod));
270 if (securityEventType == SecurityEventTypeEnum.FE_LOGIN_ATTEMPT) {
272 String additionalMessage = " Successfully authenticated.";
273 loginId = MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID);
274 if (loginId == null || loginId == "" || loginId == EPCommonSystemProperties.UNKNOWN) {
275 additionalMessage = " No cookies are found.";
277 additionalInfoAppender.append(additionalMessage);
278 } else if (securityEventType == SecurityEventTypeEnum.FE_LOGOUT) {
279 additionalInfoAppender.append(" User has been successfully logged out.");
283 String fullURL = MDC.get(EPCommonSystemProperties.FULL_URL);
284 if (fullURL != null && fullURL != "") {
285 additionalInfoAppender.append(" Request-URL:" + MDC.get(EPCommonSystemProperties.FULL_URL));
288 auditMessage = AuditLogFormatter.getInstance().createMessage(MDC.get(EPCommonSystemProperties.PROTOCOL),
289 securityEventType.name(), MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID),
290 additionalInfoAppender.toString());
292 logger.info(EELFLoggerDelegate.auditLogger, auditMessage);
298 * @param securityEventType
301 private void setHttpRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req,
302 SecurityEventTypeEnum securityEventType, String restMethod) {
304 * No need to load the request based defaults for the following security
305 * messages since either they are initiated by the Portal BE or not Http
309 if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
310 && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH
311 && securityEventType != SecurityEventTypeEnum.INCOMING_UEB_MESSAGE) {
312 // Load the RequestID (aka TrasactionId) into MDC context.
313 String requestId = UserUtils.getRequestId(req);
314 if (requestId == null||requestId.trim().length()==0) {
315 requestId = UUID.randomUUID().toString();
317 MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
319 // Load user agent into MDC context, if available.
320 String accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME);
321 accessingClient = (accessingClient == null || accessingClient.trim().length()==0)?"Unknown":accessingClient;
322 if (accessingClient != null && accessingClient.trim().length()==0 && (accessingClient.contains("Mozilla")
323 || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) {
324 accessingClient = EPCommonSystemProperties.ECOMP_PORTAL_FE;
326 MDC.put(EPCommonSystemProperties.PARTNER_NAME, accessingClient);
328 // Load loginId into MDC context.
331 user = EPUserUtils.getUserSession(req);
332 } catch (SessionExpiredException se) {
333 adviceLogger.debug(EELFLoggerDelegate.debugLogger,
334 "setHttpRequestBasedDefaultsIntoGlobalLoggingContext: No user found in session");
337 MDC.put(EPCommonSystemProperties.MDC_LOGIN_ID, (user != null ? user.getOrgUserId() : "NoUser"));
339 // Rest URL & Protocol
341 MDC.put(EPCommonSystemProperties.FULL_URL, EPCommonSystemProperties.UNKNOWN);
342 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTP);
343 restURL = UserUtils.getFullURL(req);
344 //if (restURL != null && restURL != "") {
345 if (restURL != null && restURL.trim().length()>0) {
346 MDC.put(EPCommonSystemProperties.FULL_URL, restURL);
347 if (restURL.toLowerCase().contains("https")) {
348 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTPS);
353 MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
354 String restPath = req.getServletPath();
355 //if (restPath != null && restPath != "") {
356 if (restPath != null && restPath.trim().length()>0) {
358 MDC.put(Configuration.MDC_SERVICE_NAME, restPath);
361 // Client IPAddress i.e. IPAddress of the remote host who is
362 // making this request.
363 String clientIPAddress = "";
364 clientIPAddress = req.getHeader("X-FORWARDED-FOR");
365 if (clientIPAddress == null) {
366 clientIPAddress = req.getRemoteAddr();
368 MDC.put(EPCommonSystemProperties.CLIENT_IP_ADDRESS, clientIPAddress);
369 } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
370 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, "Phonebook");
371 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, "search");
374 MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
375 MDC.put(EPCommonSystemProperties.PARTNER_NAME, EPCommonSystemProperties.ECOMP_PORTAL_FE);
378 MDC.put(Configuration.MDC_SERVICE_INSTANCE_ID, "");
379 MDC.put(Configuration.MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.severity());
381 MDC.put(Configuration.MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName());
382 MDC.put(Configuration.MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
383 MDC.put(Configuration.MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID));
384 } catch (Exception e) {
385 adviceLogger.error(EELFLoggerDelegate.errorLogger,
386 "setHttpRequestBasedDefaultsIntoGlobalLoggingContext failed", e);
392 * @param beginDateTime
395 private void calculateDateTimeDifference(String beginDateTime, String endDateTime) {
396 if (beginDateTime != null && endDateTime != null && !beginDateTime.isEmpty()&&!endDateTime.isEmpty()) {
398 SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
399 Date beginDate = ecompLogDateFormat.parse(beginDateTime);
400 Date endDate = ecompLogDateFormat.parse(endDateTime);
401 String timeDifference = String.format("%d", endDate.getTime() - beginDate.getTime());
402 MDC.put(SystemProperties.MDC_TIMER, timeDifference);
403 } catch (Exception e) {
404 adviceLogger.error(EELFLoggerDelegate.errorLogger, "calculateDateTimeDifference failed", e);
409 public String getInternalResponseCode() {
410 return MDC.get(EPCommonSystemProperties.RESPONSE_CODE);