Initial OpenECOMP Portal commit
[portal.git] / ecomp-portal-BE / src / main / java / org / openecomp / portalapp / service / sessionmgt / TimeoutHandler.java
diff --git a/ecomp-portal-BE/src/main/java/org/openecomp/portalapp/service/sessionmgt/TimeoutHandler.java b/ecomp-portal-BE/src/main/java/org/openecomp/portalapp/service/sessionmgt/TimeoutHandler.java
new file mode 100644 (file)
index 0000000..84dcf3f
--- /dev/null
@@ -0,0 +1,252 @@
+/*-
+ * ================================================================================
+ * 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.service.sessionmgt;
+
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpSession;
+
+import org.openecomp.portalapp.portal.logging.aop.EPMetricsLog;
+import org.openecomp.portalapp.portal.logging.format.EPAppMessagesEnum;
+import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
+import org.openecomp.portalapp.portal.service.EPAppService;
+import org.openecomp.portalapp.portal.transport.OnboardingApp;
+import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
+import org.openecomp.portalsdk.core.domain.sessionmgt.TimeoutVO;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.PersistJobDataAfterExecution;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Executed periodically by Quartz to discover remote application sessions and
+ * update timeouts suitably.
+ */
+@PersistJobDataAfterExecution
+@DisallowConcurrentExecution
+@org.springframework.context.annotation.Configuration
+@EnableAspectJAutoProxy
+@EPMetricsLog
+public class TimeoutHandler extends QuartzJobBean {
+       EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(TimeoutHandler.class);
+       
+       ObjectMapper mapper = new ObjectMapper();
+
+       /**
+        * Supports static call {@link #timeoutSessions(HttpSession)}
+        */
+       private static List<OnboardingApp> onboardedAppList = null;
+       
+       @Autowired
+       SessionCommunication sessionCommunication;
+       
+       @Override
+       protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
+               try {
+                       //Create a request id if there is none available,
+                       //and which will internally be used when making
+                       //session extended timeout calls to the partner applications.
+                       if (getSessionCommunication()!=null) {
+                               getSessionCommunication().setRequestId();
+                       }
+                       logger.info(EELFLoggerDelegate.debugLogger, "Quartz Cronjob for Session Management begins");
+                       
+                       ManageService manageService = (ManageService) applicationContext.getBean("manageService");
+                       EPAppService appService = (EPAppService) applicationContext.getBean("epAppService");
+
+                       List<OnboardingApp> appList = appService.getEnabledNonOpenOnboardingApps();
+                       onboardedAppList = appList;
+                       TypeReference<Hashtable<String, TimeoutVO>> typeRef = new TypeReference<Hashtable<String, TimeoutVO>>() {
+                       };
+                       String portalJsonSessionStr;
+                       Map<String, TimeoutVO> portalSessionTimeoutMap = null;
+
+                       portalJsonSessionStr = manageService.gatherSessionExtenstions();
+                       if (portalJsonSessionStr == null || portalJsonSessionStr == "") {
+                               logger.error(EELFLoggerDelegate.errorLogger, "Session Management: Portal session information is empty.");
+                               return;
+                       }
+                       
+                       try {
+                               portalSessionTimeoutMap = mapper.readValue(portalJsonSessionStr, typeRef);
+                       } catch (JsonMappingException | JsonParseException je) {
+                               EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
+                               logger.error(EELFLoggerDelegate.errorLogger, "Session Management: JSON Mapping Exception occurred while gathering the Session", je);
+                               return;
+                       } catch (Exception e) {
+                               logger.error(EELFLoggerDelegate.errorLogger, "Session Management: Error while gather Session from portal", e);
+                               return;
+                       }
+                       
+                       Map<Long, Map<String, TimeoutVO>> appSessionTimeOutMap = new Hashtable<Long, Map<String, TimeoutVO>>();
+                       // determine the Max TimeOut Time for each of the managed sessions
+                       for (OnboardingApp app : appList) {
+                               if (app.restUrl == null) {
+                                       logger.info(EELFLoggerDelegate.debugLogger, "Session Management: null restUrl, not fetching from app " + app.name);
+                                       continue;
+                               }
+                               logger.info(EELFLoggerDelegate.debugLogger, "Session Management: Calling App " + app.name + " at URL " + app.restUrl);
+                               String jsonSessionStr = fetchAppSessions(app);
+                               logger.info(EELFLoggerDelegate.debugLogger, "Session Management: App " + app.name + " returned  " + jsonSessionStr);
+                               if (jsonSessionStr == null || jsonSessionStr.isEmpty())
+                                       continue;
+
+                               try {
+                                       Map<String, TimeoutVO> sessionTimeoutMap = mapper.readValue(jsonSessionStr, typeRef);
+                                       appSessionTimeOutMap.put(app.id, sessionTimeoutMap);
+                                       for (String portalJSessionId : sessionTimeoutMap.keySet()) {
+                                               final TimeoutVO maxTimeoutVO = portalSessionTimeoutMap.get(portalJSessionId);
+                                               final TimeoutVO compareTimeoutVO = sessionTimeoutMap.get(portalJSessionId);
+                                               if (maxTimeoutVO != null && compareTimeoutVO != null) {
+                                                       if (maxTimeoutVO.compareTo(compareTimeoutVO) < 0)
+                                                               portalSessionTimeoutMap.get(portalJSessionId)
+                                                                               .setSessionTimOutMilliSec(compareTimeoutVO.getSessionTimOutMilliSec());
+                                               }
+                                       }
+                               } catch (JsonParseException | JsonMappingException e) {
+                                       EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
+                                       logger.error(EELFLoggerDelegate.errorLogger, 
+                                                       "JSON Mapping/Processing Exception occurred while mapping/parsing the jsonSessionStr", e);
+                                       continue;
+                               } catch (Exception e) {
+                                       logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while mapping/parsing the jsonSessionStr", e);
+                                       continue;
+                               }
+
+                       }
+
+                       // post the updated session timeouts back to the Apps
+                       for (OnboardingApp app : appList) {
+                               if (app.restUrl == null) {
+                                       logger.warn(EELFLoggerDelegate.errorLogger, "Session Management: null restUrl, not posting back to app " + app.name);
+                                       continue;
+                               }
+
+                               Map<String, TimeoutVO> sessionTimeoutMap = appSessionTimeOutMap.get(app.id);
+                               if (sessionTimeoutMap == null || sessionTimeoutMap.isEmpty())
+                                       continue;
+
+                               for (String portalJSessionId : sessionTimeoutMap.keySet()) {
+                                       try {
+                                               final TimeoutVO maxTimeoutVO = portalSessionTimeoutMap.get(portalJSessionId);
+                                               final TimeoutVO setTimeoutVO = sessionTimeoutMap.get(portalJSessionId);
+                                               if (maxTimeoutVO == null || setTimeoutVO == null) {
+                                                       String message = String.format(
+                                                                       "Session Management: Failed to update the session timeouts for the app: %s and the sessionId: %s.",
+                                                                       app.name, portalJSessionId);
+                                                       logger.warn(EELFLoggerDelegate.errorLogger, message);
+                                                       continue;
+                                               }
+                                               setTimeoutVO.setSessionTimOutMilliSec(maxTimeoutVO.getSessionTimOutMilliSec());
+                                       } catch (Exception e) {
+                                               logger.error(EELFLoggerDelegate.errorLogger, "Session Management:  error while updating the session timeout map", e);
+                                               continue;
+                                       }
+                               }
+                               logger.info(EELFLoggerDelegate.debugLogger, "Session Management: Updating App " + app.restUrl);
+                               String sessionTimeoutMapStr = "";
+                               try {
+                                       sessionTimeoutMapStr = mapper.writeValueAsString(sessionTimeoutMap);
+                               } catch (JsonProcessingException je) {
+                                       logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while processing sessionTimeOutMap object to a String. Details: "
+                                                                       + EcompPortalUtils.getStackTrace(je));
+                                       EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
+                               }
+                               pingAppSessions(app, sessionTimeoutMapStr);
+                       }
+                       String portalSessionTimeoutMapStr = "";
+                       try {
+                               portalSessionTimeoutMapStr = mapper.writeValueAsString(portalSessionTimeoutMap);
+                       } catch (JsonProcessingException je) {
+                               logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while processing portalSessionTimeOutMap object to a String", je);
+                               EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
+                       }
+                       manageService.updateSessionExtensions(portalSessionTimeoutMapStr);
+               } catch (Exception e) {
+                       logger.error(EELFLoggerDelegate.errorLogger, "************************ Session Management:  error in managing session timeouts", e);
+               } finally {
+                       getSessionCommunication().clear(true);
+               }
+       }
+
+       private String fetchAppSessions(OnboardingApp app) throws Exception {
+               String jsonSessionValue = getSessionCommunication().sendGet(app);
+               getSessionCommunication().clear(false);
+               return jsonSessionValue;
+       }
+
+       private void pingAppSessions(OnboardingApp app, String sessionTimeoutMapStr) throws Exception {
+               getSessionCommunication().pingSession(app, sessionTimeoutMapStr);
+               getSessionCommunication().clear(false);
+       }
+
+       public void timeoutSessions(HttpSession session) throws Exception {
+               String portalJSessionId = portalJSessionId(session);
+               if (onboardedAppList == null)
+                       return;
+
+               for (OnboardingApp app : onboardedAppList) {
+                       getSessionCommunication().timeoutSession(app, portalJSessionId);
+                       getSessionCommunication().clear(false);
+               }
+       }
+
+       protected static String portalJSessionId(HttpSession session) {
+               final Object attribute = session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID);
+               if (attribute == null)
+                       return "";
+               String jSessionKey = (String) attribute;
+               return jSessionKey.split("-")[0];
+       }
+
+       private static ApplicationContext applicationContext;
+
+       public static void setApplicationContext(ApplicationContext _applicationContext) {
+               applicationContext = _applicationContext;
+       }
+
+       public SessionCommunication getSessionCommunication() {
+               if(sessionCommunication == null){
+                       if (applicationContext != null)                         
+                               sessionCommunication = (SessionCommunication)applicationContext.getBean("sessionCommunication");
+               }
+               
+               return sessionCommunication;
+       }
+
+       public void setSessionCommunication(SessionCommunication sessionCommunication) {
+               this.sessionCommunication = sessionCommunication;
+       }
+
+}