Initial OpenECOMP Portal commit
[portal.git] / ecomp-portal-BE / src / main / java / org / openecomp / portalapp / portal / logging / aop / EPEELFLoggerAdvice.java
diff --git a/ecomp-portal-BE/src/main/java/org/openecomp/portalapp/portal/logging/aop/EPEELFLoggerAdvice.java b/ecomp-portal-BE/src/main/java/org/openecomp/portalapp/portal/logging/aop/EPEELFLoggerAdvice.java
new file mode 100644 (file)
index 0000000..a03f515
--- /dev/null
@@ -0,0 +1,341 @@
+/*-
+ * ================================================================================
+ * eCOMP Portal
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ================================================================================
+ */
+package org.openecomp.portalapp.portal.logging.aop;
+
+import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY;
+import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID;
+import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+
+import java.net.InetAddress;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.openecomp.portalapp.portal.domain.EPUser;
+import org.openecomp.portalapp.portal.utils.EPSystemProperties;
+import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
+import org.openecomp.portalapp.util.EPUserUtils;
+import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum;
+import org.openecomp.portalsdk.core.logging.format.AuditLogFormatter;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum;
+import org.openecomp.portalsdk.core.web.support.UserUtils;
+import org.slf4j.MDC;
+
+import com.att.eelf.configuration.Configuration;
+
+@org.springframework.context.annotation.Configuration
+public class EPEELFLoggerAdvice {
+       
+       EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EPEELFLoggerAdvice.class);
+       //DateTime Format according to the ECOMP Application Logging Guidelines.
+       private static final SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+               
+       public void loadServletRequestBasedDefaults(HttpServletRequest req, SecurityEventTypeEnum securityEventType) {
+               try {
+                       this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, req.getServletPath());
+               } catch(Exception e) {
+                       adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
+               }
+       }
+       
+       public Object[] before(SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) {
+               String className        = "";
+               if (passOnArgs[0]!=null) {
+                       className = passOnArgs[0].toString();
+               }
+               
+               String methodName       = "";
+               if (passOnArgs[1]!=null) {
+                       methodName = passOnArgs[1].toString();
+               }
+                               
+               //Initialize Request defaults only for controller methods.
+               MDC.put(className + methodName + EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
+               MDC.put(EPSystemProperties.TARGET_ENTITY, EPSystemProperties.ECOMP_PORTAL_BE);
+               MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, methodName);
+               if (securityEventType!=null) {
+                       MDC.put(className + methodName + EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
+                       HttpServletRequest req = null;
+                       if (args[0]!=null && args[0] instanceof HttpServletRequest ) {
+                               req = (HttpServletRequest)args[0];
+                               this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
+                       }
+               }
+               
+               EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
+               
+               //StopWatch stopWatch = new StopWatch("Metrics for " + className + "." + methodName);
+               //stopWatch.start();
+               
+               logger.debug(EELFLoggerDelegate.debugLogger, "Entered executing " + methodName +".");
+               
+               return new Object[] {""};
+       }
+       
+       public void after(SecurityEventTypeEnum securityEventType, String statusCode, String responseCode, Object[] args, Object[] returnArgs, Object[] passOnArgs) {
+               //ClassName
+               String className        = "";
+               if (passOnArgs[0]!=null) {
+                       className = passOnArgs[0].toString();
+               }
+               
+               //Method Name
+               String methodName       = "";
+               if (passOnArgs[1]!=null) {
+                       methodName = passOnArgs[1].toString();
+               }
+               
+               EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
+               /*/
+               StopWatch stopWatch = (StopWatch)returnArgs[0];
+               if (stopWatch!=null && stopWatch.isRunning()) {
+                       stopWatch.stop();
+                       MDC.put(SystemProperties.MDC_TIMER, stopWatch.getTotalTimeMillis() + "ms");
+               }
+               /**/
+               
+               if (MDC.get(EPSystemProperties.TARGET_SERVICE_NAME) == null || MDC.get(EPSystemProperties.TARGET_SERVICE_NAME) == "") {
+                       MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, methodName);
+               }
+               
+               if (MDC.get(EPSystemProperties.TARGET_ENTITY) == null || MDC.get(EPSystemProperties.TARGET_ENTITY) == "") {
+                       MDC.put(EPSystemProperties.TARGET_ENTITY, EPSystemProperties.ECOMP_PORTAL_BE);
+               }
+               
+               MDC.put(EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, MDC.get(className + methodName + EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP));
+               MDC.put(EPSystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
+               this.calculateDateTimeDifference(MDC.get(EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP), MDC.get(EPSystemProperties.METRICSLOG_END_TIMESTAMP));
+               
+               //Making sure to reload the INCOMING request MDC defaults if they have 
+               //been wiped out by either Outgoing or LDAP Phone book search operations.
+               if (securityEventType!=null && args[0]!=null && args[0] instanceof HttpServletRequest &&
+                               securityEventType==SecurityEventTypeEnum.INCOMING_REST_MESSAGE && 
+                               (MDC.get(EPSystemProperties.FULL_URL)==null || MDC.get(EPSystemProperties.FULL_URL)=="")) {
+                       HttpServletRequest req = (HttpServletRequest)args[0];
+                       this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
+               }
+               
+               //Use external API response code in case if it resulted in an error.
+               String externalAPIResponseCode = MDC.get(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE);
+               if (externalAPIResponseCode==null || externalAPIResponseCode=="" || externalAPIResponseCode.trim().equalsIgnoreCase("200")) {
+                       MDC.put(EPSystemProperties.RESPONSE_CODE, responseCode);
+                       MDC.put(EPSystemProperties.STATUS_CODE, statusCode);
+               } else {
+                       MDC.put(EPSystemProperties.RESPONSE_CODE, externalAPIResponseCode);
+                       MDC.put(EPSystemProperties.STATUS_CODE, "ERROR");
+               }
+               
+               logger.debug(EELFLoggerDelegate.debugLogger, "Finished executing " + methodName + ".");
+               logger.info(EELFLoggerDelegate.metricsLogger,  methodName + " operation is completed.");
+               
+               //Log security message, if necessary
+               if (securityEventType!=null) {
+                       MDC.put(EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, MDC.get(className + methodName + EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP));
+                       MDC.put(EPSystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
+                       this.calculateDateTimeDifference(MDC.get(EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP), MDC.get(EPSystemProperties.AUDITLOG_END_TIMESTAMP));
+                                               
+                       this.logSecurityMessage(logger, securityEventType, methodName);
+                       
+                       //Outgoing & LDAP messages are part of Incoming requests so,
+                       //keep "RequestId", "PartnerName", "ServiceName", "LoginId" &
+                       //"ResponseCode" etc. in memory and remove it only when 
+                       //finished processing the parent incoming message.
+                       if (securityEventType!=SecurityEventTypeEnum.OUTGOING_REST_MESSAGE &&
+                                       securityEventType!=SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
+                               MDC.remove(MDC_KEY_REQUEST_ID);
+                               MDC.remove(EPSystemProperties.PARTNER_NAME);
+                               MDC.remove(Configuration.MDC_SERVICE_NAME);
+                               MDC.remove(EPSystemProperties.MDC_LOGIN_ID);
+                               MDC.remove(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE);
+                       }
+                       
+                       //clear when finishes audit logging
+                       MDC.remove(EPSystemProperties.FULL_URL);
+                       MDC.remove(EPSystemProperties.PROTOCOL);
+                       MDC.remove(EPSystemProperties.STATUS_CODE);
+                       MDC.remove(className + methodName + EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
+                       MDC.remove(EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
+                       MDC.remove(EPSystemProperties.AUDITLOG_END_TIMESTAMP);
+                       MDC.remove(EPSystemProperties.RESPONSE_CODE);
+               }
+               MDC.remove(className + methodName + EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
+               MDC.remove(EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
+               MDC.remove(EPSystemProperties.METRICSLOG_END_TIMESTAMP);
+               MDC.remove(EPSystemProperties.MDC_TIMER);
+               MDC.remove(EPSystemProperties.TARGET_ENTITY);
+               MDC.remove(EPSystemProperties.TARGET_SERVICE_NAME);
+       }
+       
+       private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType, String restMethod) {
+               StringBuilder additionalInfoAppender = new StringBuilder();
+               String auditMessage = "";
+               
+               if (securityEventType == SecurityEventTypeEnum.OUTGOING_REST_MESSAGE) {
+                       additionalInfoAppender.append(String.format("%s '%s' request was initiated.", 
+                                                                                                                       restMethod, MDC.get(EPSystemProperties.TARGET_SERVICE_NAME)));
+               } else if (securityEventType==SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
+                       additionalInfoAppender.append("LDAP Phonebook search operation is performed.");
+               } else {
+                       additionalInfoAppender.append(String.format("%s request was received.", restMethod));
+                       
+                       if (securityEventType == SecurityEventTypeEnum.FE_LOGIN_ATTEMPT) {
+                               String loginId = "";
+                               String additionalMessage = " Successfully authenticated.";
+                               loginId = MDC.get(EPSystemProperties.MDC_LOGIN_ID);
+                               if (loginId==null || loginId=="" || loginId== EPSystemProperties.UNKNOWN) {
+                                       additionalMessage = " No cookies are found.";
+                               }
+                               additionalInfoAppender.append(additionalMessage);
+                       } else if (securityEventType == SecurityEventTypeEnum.FE_LOGOUT) {
+                               additionalInfoAppender.append(" User has been successfully logged out.");
+                       }
+               }
+               
+               String fullURL = MDC.get(EPSystemProperties.FULL_URL);
+               if (fullURL!=null && fullURL!="") {
+                       additionalInfoAppender.append(" Request-URL:" + MDC.get(EPSystemProperties.FULL_URL));
+               }
+               
+               auditMessage = AuditLogFormatter.getInstance().createMessage(   MDC.get(EPSystemProperties.PROTOCOL),
+                                                                                                                                               securityEventType.name(),
+                                                                                                                                               MDC.get(EPSystemProperties.MDC_LOGIN_ID),
+                                                                                                                                               additionalInfoAppender.toString());
+               
+               logger.info(EELFLoggerDelegate.auditLogger, auditMessage);
+       }
+       
+       private void setHttpRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req, SecurityEventTypeEnum securityEventType, String restMethod) {
+               //No need to load the request based defaults for the following security messages
+               //since either they are initiated by the Portal BE or not Http request based.
+               if (req!=null) {
+                       if (securityEventType!=SecurityEventTypeEnum.OUTGOING_REST_MESSAGE && 
+                                       securityEventType!=SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH && 
+                                       securityEventType!=SecurityEventTypeEnum.INCOMING_UEB_MESSAGE) {
+                               //Load the RequestID (aka TrasactionId) into MDC context.
+                               String requestId = UserUtils.getRequestId(req);
+                               if (requestId=="" || requestId==null) {
+                                       requestId = UUID.randomUUID().toString();
+                               }
+                               MDC.put(MDC_KEY_REQUEST_ID, requestId);
+                               
+                               //Load user agent into MDC context, if available.
+                               String accessingClient = "Unknown";
+                               accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME);
+                               if (accessingClient!=null && accessingClient!="" && 
+                                               (accessingClient.contains("Mozilla") || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) {
+                                       accessingClient = EPSystemProperties.ECOMP_PORTAL_FE;
+                               }
+                               MDC.put(EPSystemProperties.PARTNER_NAME, accessingClient);
+                                                               
+                               //Load loginId into MDC context.
+                               String loginId = "";
+                               try {
+                                       loginId = UserUtils.getUserIdFromCookie(req);
+                               } catch (Exception e) {
+                                       adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
+                               }
+                               if (loginId == null || loginId == "") {
+                                       EPUser user = EPUserUtils.getUserSession(req);
+                                       if (user != null) {
+                                               loginId = user.getLoginId();
+                                       }
+                                       
+                                       if (loginId==null || loginId=="") {
+                                               loginId = "Unknown";
+                                       }
+                               }
+                               MDC.put(EPSystemProperties.MDC_LOGIN_ID, loginId);
+                               
+                               //Rest URL & Protocol 
+                               String restURL = "";
+                               MDC.put(EPSystemProperties.FULL_URL, EPSystemProperties.UNKNOWN);
+                               MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTP);
+                               restURL = UserUtils.getFullURL(req);
+                               if (restURL!=null && restURL!="") {
+                                       MDC.put(EPSystemProperties.FULL_URL, restURL);
+                                       if (restURL.toLowerCase().contains("https")) {
+                                               MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTPS);
+                                       }
+                               }
+                               
+                               //Rest Path
+                               MDC.put(MDC_SERVICE_NAME, restMethod);
+                               String restPath = req.getServletPath();
+                               if (restPath!=null && restPath!="") {
+                                       MDC.put(MDC_SERVICE_NAME, restPath);
+                               }
+                               
+                               //Client IPAddress i.e. IPAddress of the remote host who is making this request.
+                               String clientIPAddress = "";
+                               clientIPAddress = req.getHeader("X-FORWARDED-FOR");
+                               if (clientIPAddress == null) {
+                                       clientIPAddress = req.getRemoteAddr();
+                               }
+                               MDC.put(EPSystemProperties.CLIENT_IP_ADDRESS, clientIPAddress);
+                       } else if(securityEventType==SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
+                               MDC.put(EPSystemProperties.TARGET_ENTITY, "Phonebook");
+                               MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, "search");
+                       }
+               } else {
+                       MDC.put(MDC_SERVICE_NAME, restMethod);
+                       MDC.put(EPSystemProperties.PARTNER_NAME,  EPSystemProperties.ECOMP_PORTAL_FE);
+               }
+               
+               MDC.put(MDC_SERVICE_INSTANCE_ID, "");
+               MDC.put(MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.toString());
+               try {
+                       MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
+                       MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
+                       MDC.put(MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID));
+               } catch (Exception e) {
+                       adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));          
+               }
+       }
+       
+       private String getCurrentDateTimeUTC() {
+               String currentDateTime = ecompLogDateFormat.format(new Date());
+               return currentDateTime;
+       }
+       
+       private void calculateDateTimeDifference(String beginDateTime, String endDateTime) {
+               if (beginDateTime!=null && endDateTime!=null) {
+                       try {
+                               Date beginDate = ecompLogDateFormat.parse(beginDateTime);
+                               Date endDate = ecompLogDateFormat.parse(endDateTime);
+                               String timeDifference = String.format("%d ms", endDate.getTime() - beginDate.getTime());
+                               MDC.put(SystemProperties.MDC_TIMER, timeDifference);
+                       } catch(Exception e) {
+                               adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
+                       }
+               }
+       }
+       
+       public String getInternalResponseCode() {
+               return MDC.get(EPSystemProperties.RESPONSE_CODE);
+       }
+}