2  * ============LICENSE_START==========================================
 
   4  * ===================================================================
 
   5  * Copyright © 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.openecomp.portalapp.portal.logging.aop;
 
  40 import java.net.InetAddress;
 
  41 import java.text.SimpleDateFormat;
 
  42 import java.util.Date;
 
  43 import java.util.UUID;
 
  45 import javax.servlet.http.HttpServletRequest;
 
  47 import org.openecomp.portalapp.portal.domain.EPUser;
 
  48 import org.openecomp.portalapp.portal.utils.EPCommonSystemProperties;
 
  49 import org.openecomp.portalapp.util.EPUserUtils;
 
  50 import org.openecomp.portalsdk.core.exception.SessionExpiredException;
 
  51 import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum;
 
  52 import org.openecomp.portalsdk.core.logging.format.AuditLogFormatter;
 
  53 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
 
  54 import org.openecomp.portalsdk.core.util.SystemProperties;
 
  55 import org.openecomp.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum;
 
  56 import org.openecomp.portalsdk.core.web.support.UserUtils;
 
  59 import com.att.eelf.configuration.Configuration;
 
  61 @org.springframework.context.annotation.Configuration
 
  62 public class EPEELFLoggerAdvice {
 
  64         private EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EPEELFLoggerAdvice.class);
 
  67          * DateTime Format according to the ECOMP Application Logging Guidelines.
 
  69         private static final SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
 
  72          * @return Current date and time in the format specified by the ECOMP
 
  73          *         Application Logging Guidelines.
 
  75         public static String getCurrentDateTimeUTC() {
 
  76                 String currentDateTime = ecompLogDateFormat.format(new Date());
 
  77                 return currentDateTime;
 
  81          * Sets logging context with values from HttpServletRequest object.
 
  85          * @param securityEventType
 
  86          *            SecurityEventTypeEnum
 
  88         public void loadServletRequestBasedDefaults(HttpServletRequest req, SecurityEventTypeEnum securityEventType) {
 
  90                         setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, req.getServletPath());
 
  91                 } catch (Exception e) {
 
  92                         adviceLogger.error(EELFLoggerDelegate.errorLogger, "loadServletRequestBasedDefaults failed", e);
 
  98          * @param securityEventType
 
 101          * @return Object array
 
 103         public Object[] before(SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) {
 
 104                 String className = "";
 
 105                 if (passOnArgs[0] != null) {
 
 106                         className = passOnArgs[0].toString();
 
 109                 String methodName = "";
 
 110                 if (passOnArgs[1] != null) {
 
 111                         methodName = passOnArgs[1].toString();
 
 114                 // Initialize Request defaults only for controller methods.
 
 115                 MDC.put(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
 
 116                 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
 
 117                 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
 
 118                 if (securityEventType != null) {
 
 119                         MDC.put(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
 
 120                                         getCurrentDateTimeUTC());
 
 121                         HttpServletRequest req = null;
 
 122                         if (args[0] != null && args[0] instanceof HttpServletRequest) {
 
 123                                 req = (HttpServletRequest) args[0];
 
 124                                 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
 
 128                 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
 
 129                 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#before: entering {}", methodName);
 
 130                 return new Object[] { "" };
 
 135          * @param securityEventType
 
 137          * @param responseCode
 
 142         public void after(SecurityEventTypeEnum securityEventType, String statusCode, String responseCode, Object[] args,
 
 143                         Object[] returnArgs, Object[] passOnArgs) {
 
 144                 String className = "";
 
 145                 if (passOnArgs[0] != null)
 
 146                         className = passOnArgs[0].toString();
 
 149                 String methodName = "";
 
 150                 if (passOnArgs[1] != null)
 
 151                         methodName = passOnArgs[1].toString();
 
 153                 if (MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME) == null
 
 154                                 || MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME) == "")
 
 155                         MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
 
 157                 if (MDC.get(EPCommonSystemProperties.TARGET_ENTITY) == null
 
 158                                 || MDC.get(EPCommonSystemProperties.TARGET_ENTITY) == "")
 
 159                         MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
 
 161                 MDC.put(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP,
 
 162                                 MDC.get(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP));
 
 163                 MDC.put(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
 
 164                 this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP),
 
 165                                 MDC.get(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP));
 
 167                 // Making sure to reload the INCOMING request MDC defaults if they have
 
 168                 // been wiped out by either Outgoing or LDAP Phone book search
 
 170                 if (securityEventType != null && args[0] != null && args[0] instanceof HttpServletRequest
 
 171                                 && securityEventType == SecurityEventTypeEnum.INCOMING_REST_MESSAGE
 
 172                                 && (MDC.get(EPCommonSystemProperties.FULL_URL) == null
 
 173                                                 || MDC.get(EPCommonSystemProperties.FULL_URL) == "")) {
 
 174                         HttpServletRequest req = (HttpServletRequest) args[0];
 
 175                         this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
 
 178                 // Use external API response code in case if it resulted in an error.
 
 179                 String externalAPIResponseCode = MDC.get(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
 
 180                 if (externalAPIResponseCode == null || externalAPIResponseCode == ""
 
 181                                 || externalAPIResponseCode.trim().equalsIgnoreCase("200")) {
 
 182                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, responseCode);
 
 183                         MDC.put(EPCommonSystemProperties.STATUS_CODE, statusCode);
 
 185                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, externalAPIResponseCode);
 
 186                         MDC.put(EPCommonSystemProperties.STATUS_CODE, "ERROR");
 
 189                 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
 
 190                 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#after: finished {}", methodName);
 
 191                 // add the metrics log
 
 192                 logger.info(EELFLoggerDelegate.metricsLogger,  methodName + " operation is completed.");
 
 194                 // Log security message, if necessary
 
 195                 if (securityEventType != null) {
 
 196                         MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
 
 197                                         MDC.get(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP));
 
 198                         MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
 
 199                         this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP),
 
 200                                         MDC.get(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP));
 
 202                         this.logSecurityMessage(logger, securityEventType, methodName);
 
 204                         // Outgoing & LDAP messages are part of Incoming requests so,
 
 205                         // keep "RequestId", "PartnerName", "ServiceName", "LoginId" &
 
 206                         // "ResponseCode" etc. in memory and remove it only when
 
 207                         // finished processing the parent incoming message.
 
 208                         if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
 
 209                                         && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
 
 210                                 MDC.remove(Configuration.MDC_KEY_REQUEST_ID);
 
 211                                 MDC.remove(EPCommonSystemProperties.PARTNER_NAME);
 
 212                                 MDC.remove(Configuration.MDC_SERVICE_NAME);
 
 213                                 MDC.remove(EPCommonSystemProperties.MDC_LOGIN_ID);
 
 214                                 MDC.remove(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
 
 217                         // clear when finishes audit logging
 
 218                         MDC.remove(EPCommonSystemProperties.FULL_URL);
 
 219                         MDC.remove(EPCommonSystemProperties.PROTOCOL);
 
 220                         MDC.remove(EPCommonSystemProperties.STATUS_CODE);
 
 221                         MDC.remove(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
 
 222                         MDC.remove(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
 
 223                         MDC.remove(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP);
 
 224                         MDC.remove(EPCommonSystemProperties.RESPONSE_CODE);
 
 226                 MDC.remove(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
 
 227                 MDC.remove(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
 
 228                 MDC.remove(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP);
 
 229                 MDC.remove(EPCommonSystemProperties.MDC_TIMER);
 
 230                 MDC.remove(EPCommonSystemProperties.TARGET_ENTITY);
 
 231                 MDC.remove(EPCommonSystemProperties.TARGET_SERVICE_NAME);
 
 237          * @param securityEventType
 
 240         private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType,
 
 242                 StringBuilder additionalInfoAppender = new StringBuilder();
 
 243                 String auditMessage = "";
 
 245                 if (securityEventType == SecurityEventTypeEnum.OUTGOING_REST_MESSAGE) {
 
 246                         additionalInfoAppender.append(String.format("%s '%s' request was initiated.", restMethod,
 
 247                                         MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME)));
 
 248                 } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
 
 249                         additionalInfoAppender.append("LDAP Phonebook search operation is performed.");
 
 251                         additionalInfoAppender.append(String.format("%s request was received.", restMethod));
 
 253                         if (securityEventType == SecurityEventTypeEnum.FE_LOGIN_ATTEMPT) {
 
 255                                 String additionalMessage = " Successfully authenticated.";
 
 256                                 loginId = MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID);
 
 257                                 if (loginId == null || loginId == "" || loginId == EPCommonSystemProperties.UNKNOWN) {
 
 258                                         additionalMessage = " No cookies are found.";
 
 260                                 additionalInfoAppender.append(additionalMessage);
 
 261                         } else if (securityEventType == SecurityEventTypeEnum.FE_LOGOUT) {
 
 262                                 additionalInfoAppender.append(" User has been successfully logged out.");
 
 266                 String fullURL = MDC.get(EPCommonSystemProperties.FULL_URL);
 
 267                 if (fullURL != null && fullURL != "") {
 
 268                         additionalInfoAppender.append(" Request-URL:" + MDC.get(EPCommonSystemProperties.FULL_URL));
 
 271                 auditMessage = AuditLogFormatter.getInstance().createMessage(MDC.get(EPCommonSystemProperties.PROTOCOL),
 
 272                                 securityEventType.name(), MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID),
 
 273                                 additionalInfoAppender.toString());
 
 275                 logger.info(EELFLoggerDelegate.auditLogger, auditMessage);
 
 281          * @param securityEventType
 
 284         private void setHttpRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req,
 
 285                         SecurityEventTypeEnum securityEventType, String restMethod) {
 
 287                  * No need to load the request based defaults for the following security
 
 288                  * messages since either they are initiated by the Portal BE or not Http
 
 292                         if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
 
 293                                         && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH
 
 294                                         && securityEventType != SecurityEventTypeEnum.INCOMING_UEB_MESSAGE) {
 
 295                                 // Load the RequestID (aka TrasactionId) into MDC context.
 
 296                                 String requestId = UserUtils.getRequestId(req);
 
 297                                 if (requestId == "" || requestId == null) {
 
 298                                         requestId = UUID.randomUUID().toString();
 
 300                                 MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
 
 302                                 // Load user agent into MDC context, if available.
 
 303                                 String accessingClient = "Unknown";
 
 304                                 accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME);
 
 305                                 if (accessingClient != null && accessingClient != "" && (accessingClient.contains("Mozilla")
 
 306                                                 || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) {
 
 307                                         accessingClient = EPCommonSystemProperties.ECOMP_PORTAL_FE;
 
 309                                 MDC.put(EPCommonSystemProperties.PARTNER_NAME, accessingClient);
 
 311                                 // Load loginId into MDC context.
 
 314                                         user = EPUserUtils.getUserSession(req);
 
 315                                 } catch (SessionExpiredException se) {
 
 316                                         adviceLogger.debug(EELFLoggerDelegate.debugLogger,
 
 317                                                         "setHttpRequestBasedDefaultsIntoGlobalLoggingContext: No user found in session");
 
 320                                 MDC.put(EPCommonSystemProperties.MDC_LOGIN_ID, (user != null ? user.getOrgUserId() : "NoUser"));
 
 322                                 // Rest URL & Protocol
 
 324                                 MDC.put(EPCommonSystemProperties.FULL_URL, EPCommonSystemProperties.UNKNOWN);
 
 325                                 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTP);
 
 326                                 restURL = UserUtils.getFullURL(req);
 
 327                                 if (restURL != null && restURL != "") {
 
 328                                         MDC.put(EPCommonSystemProperties.FULL_URL, restURL);
 
 329                                         if (restURL.toLowerCase().contains("https")) {
 
 330                                                 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTPS);
 
 335                                 MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
 
 336                                 String restPath = req.getServletPath();
 
 337                                 if (restPath != null && restPath != "") {
 
 338                                         MDC.put(Configuration.MDC_SERVICE_NAME, restPath);
 
 341                                 // Client IPAddress i.e. IPAddress of the remote host who is
 
 342                                 // making this request.
 
 343                                 String clientIPAddress = "";
 
 344                                 clientIPAddress = req.getHeader("X-FORWARDED-FOR");
 
 345                                 if (clientIPAddress == null) {
 
 346                                         clientIPAddress = req.getRemoteAddr();
 
 348                                 MDC.put(EPCommonSystemProperties.CLIENT_IP_ADDRESS, clientIPAddress);
 
 349                         } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
 
 350                                 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, "Phonebook");
 
 351                                 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, "search");
 
 354                         MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
 
 355                         MDC.put(EPCommonSystemProperties.PARTNER_NAME, EPCommonSystemProperties.ECOMP_PORTAL_FE);
 
 358                 MDC.put(Configuration.MDC_SERVICE_INSTANCE_ID, "");
 
 359                 MDC.put(Configuration.MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.toString());
 
 361                         MDC.put(Configuration.MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
 
 362                         MDC.put(Configuration.MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
 
 363                         MDC.put(Configuration.MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID));
 
 364                 } catch (Exception e) {
 
 365                         adviceLogger.error(EELFLoggerDelegate.errorLogger,
 
 366                                         "setHttpRequestBasedDefaultsIntoGlobalLoggingContext failed", e);
 
 372          * @param beginDateTime
 
 375         private void calculateDateTimeDifference(String beginDateTime, String endDateTime) {
 
 376                 if (beginDateTime != null && endDateTime != null) {
 
 378                                 Date beginDate = ecompLogDateFormat.parse(beginDateTime);
 
 379                                 Date endDate = ecompLogDateFormat.parse(endDateTime);
 
 380                                 String timeDifference = String.format("%d", endDate.getTime() - beginDate.getTime());
 
 381                                 MDC.put(SystemProperties.MDC_TIMER, timeDifference);
 
 382                         } catch (Exception e) {
 
 383                                 adviceLogger.error(EELFLoggerDelegate.errorLogger, "calculateDateTimeDifference failed", e);
 
 388         public String getInternalResponseCode() {
 
 389                 return MDC.get(EPCommonSystemProperties.RESPONSE_CODE);