2 * ================================================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ================================================================================
20 package org.openecomp.portalsdk.core.onboarding.listener;
22 import java.util.Calendar;
23 import java.util.Hashtable;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpSession;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.openecomp.portalsdk.core.onboarding.crossapi.SessionCommunicationService;
32 import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants;
33 import org.openecomp.portalsdk.core.restful.domain.PortalTimeoutVO;
35 import com.fasterxml.jackson.core.JsonProcessingException;
36 import com.fasterxml.jackson.core.type.TypeReference;
37 import com.fasterxml.jackson.databind.ObjectMapper;
40 * Invoked by listeners (UserContextListener and UserSessionListener) to track
43 public class PortalTimeoutHandler {
45 protected static final SessionCommInf sessionComm = new SessionComm();
47 public interface SessionCommInf {
48 public Integer fetchSessionSlotCheckInterval(String... params) throws Exception;
50 public void extendSessionTimeOuts(String... sessionMap) throws Exception;
53 public static class SessionComm implements SessionCommInf {
54 public Integer fetchSessionSlotCheckInterval(String... params) throws Exception {
56 String ecompRestURL = params[0];
57 String userName = params[1];
58 String pwd = params[2];
59 String uebKey = params[3];
61 String sessionSlot = SessionCommunicationService.getSessionSlotCheckInterval(ecompRestURL, userName, pwd,
63 if (sessionSlot == null)
65 return Integer.parseInt(sessionSlot);
68 public void extendSessionTimeOuts(String... params) throws Exception {
70 String ecompRestURL = params[0];
71 String userName = params[1];
72 String pwd = params[2];
73 String uebKey = params[3];
74 String sessionTimeoutMap = params[4];
76 SessionCommunicationService.requestPortalSessionTimeoutExtension(ecompRestURL, userName, pwd, uebKey,
81 public static final Map<String, HttpSession> sessionMap = new Hashtable<String, HttpSession>();
82 public static final Integer repeatInterval = 15 * 60; // 15 minutes
83 protected static final Log logger = LogFactory.getLog(PortalTimeoutHandler.class);
84 static ObjectMapper mapper = new ObjectMapper();
85 private static PortalTimeoutHandler timeoutHandler;
87 public static PortalTimeoutHandler getInstance() {
88 if (timeoutHandler == null)
89 timeoutHandler = new PortalTimeoutHandler();
91 return timeoutHandler;
97 * @param portalJSessionId
101 public static void sessionCreated(String portalJSessionId, String jSessionId, HttpSession session) {
103 storeMaxInactiveTime(session);
105 // this key is a combination of portal jsession id and app session id
106 String jSessionKey = jSessionKey(jSessionId, portalJSessionId);
107 Object jSessionKeySessionVal = session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID);
109 // do not reset the attributes if the same values have already been set
110 // because that will cause PortalTimeoutBindingListener to unbound the
112 if (jSessionKeySessionVal != null && jSessionKeySessionVal.equals(jSessionKey)) {
113 logger.debug(" Session Values already exist in te map for sessionKey " + jSessionKey);
117 session.setAttribute(PortalApiConstants.PORTAL_JSESSION_ID, jSessionKey);
119 // session binding listener will add this value to the static map
120 // and with session replication the listener will fire in all tomcat
122 session.setAttribute(PortalApiConstants.PORTAL_JSESSION_BIND, new PortalTimeoutBindingListener());
123 // sessionMap.put((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID),
129 * TODO: remove static
133 protected static void storeMaxInactiveTime(HttpSession session) {
134 if (session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null)
135 session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME, session.getMaxInactiveInterval());
139 * TODO: remove static
143 public static void sessionDestroyed(HttpSession session) {
145 logger.info(" Session getting destroyed - id: " + session.getId());
146 session.removeAttribute(PortalApiConstants.PORTAL_JSESSION_BIND);
147 // sessionMap.remove((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID));
148 } catch (Exception e) {
149 logger.error("sessionDestroyed failed", e);
154 * TODO: remove static
156 * @param portalJSessionId
157 * @return true on success, false if the session cannot be found, etc.
159 public static boolean invalidateSession(String portalJSessionId) {
160 boolean result = false;
161 logger.debug("Session Management: request from Portal to invalidate the session: " + portalJSessionId);
162 for (String jSessionKey : sessionMap.keySet()) {
164 HttpSession session = sessionMap.get(jSessionKey);
165 if (portalJSessionId(jSessionKey).equals(portalJSessionId)) {
166 session.invalidate();
169 } catch (Exception e) {
170 logger.error("invalidateSession failed", e);
177 * TODO: remove static
179 * @return json version of the timeout map: session ID -> timeout object
181 public static String gatherSessionExtensions() {
182 logger.debug("Session Management: gatherSessionExtensions");
184 Map<String, PortalTimeoutVO> sessionTimeoutMap = new Hashtable<String, PortalTimeoutVO>();
187 for (String jSessionKey : sessionMap.keySet()) {
190 // get the expirytime in seconds
191 HttpSession session = sessionMap.get(jSessionKey);
193 Long lastAccessedTimeMilliSec = session.getLastAccessedTime();
194 Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L;
195 // Long currentTimeMilliSec =
196 // Calendar.getInstance().getTimeInMillis() ;
197 // (maxIntervalMilliSec - (currentTimeMilliSec -
198 // lastAccessedTimeMilliSec) + ;
199 Calendar instance = Calendar.getInstance();
200 instance.setTimeInMillis(session.getLastAccessedTime());
201 logger.debug("Session Management: Last Accessed time for " + jSessionKey + ": " + instance.getTime());
203 Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec;
205 sessionTimeoutMap.put(portalJSessionId(jSessionKey),
206 getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec));
207 logger.debug("Session Management: putting session in map " + jSessionKey + " sessionTimoutSec"
208 + (int) (sessionTimOutMilliSec / 1000));
210 jsonMap = mapper.writeValueAsString(sessionTimeoutMap);
212 } catch (Exception e) {
213 logger.error("gatherSessionExtensions failed", e);
223 * TODO: remove static
225 * @param sessionTimeoutMapStr
226 * @return true on success, false otherwise
229 public static boolean updateSessionExtensions(String sessionTimeoutMapStr) throws Exception {
230 logger.debug("Session Management: updateSessionExtensions");
231 // Map<String,Object> sessionTimeoutMap =
232 // mapper.readValue(sessionTimeoutMapStr, Map.class);
233 Map<String, PortalTimeoutVO> sessionTimeoutMap = null;
236 TypeReference<Hashtable<String, PortalTimeoutVO>> typeRef = new TypeReference<Hashtable<String, PortalTimeoutVO>>() {
238 sessionTimeoutMap = mapper.readValue(sessionTimeoutMapStr, typeRef);
239 } catch (Exception e) {
240 logger.error("updateSessionExtensions failed to parse the sessionTimeoutMap from portal", e);
244 boolean result = true;
245 for (String jPortalSessionId : sessionTimeoutMap.keySet()) {
247 PortalTimeoutVO extendedTimeoutVO = mapper.readValue(
248 mapper.writeValueAsString(sessionTimeoutMap.get(jPortalSessionId)), PortalTimeoutVO.class);
249 HttpSession session = sessionMap.get(jSessionKey(extendedTimeoutVO.getjSessionId(), jPortalSessionId));
251 if (session == null) {
255 Long lastAccessedTimeMilliSec = session.getLastAccessedTime();
256 Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L;
257 Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec;
259 Long maxTimeoutTimeMilliSec = extendedTimeoutVO.getSessionTimOutMilliSec();
260 if (maxTimeoutTimeMilliSec > sessionTimOutMilliSec) {
261 session.setMaxInactiveInterval((int) (maxTimeoutTimeMilliSec - lastAccessedTimeMilliSec) / 1000);
262 logger.debug("Session Management: extended session for :" + session.getId() + " to :"
263 + (int) (maxTimeoutTimeMilliSec / 1000));
264 // System.out.println("!!!!!!!!!extended session for :" +
265 // session.getId() + " to :" +
266 // (int)(maxTimeoutTimeMilliSec/1000));
268 } catch (Exception e) {
269 logger.error("updateSessionExtensions failed to update session timeouts", e);
270 // Signal a problem if any one of them fails
279 * TODO: Remove static
284 * @param ecompRestURL
285 * @param _sessionComm
287 public static void handleSessionUpdatesNative(HttpServletRequest request, String userName, String pwd,
288 String uebKey, String ecompRestURL, SessionCommInf _sessionComm) {
290 if (_sessionComm == null) {
291 _sessionComm = sessionComm;
294 synchronizeSessionForLastMinuteRequests(request, ecompRestURL, userName, pwd, uebKey, _sessionComm);
295 } catch (Exception e) {
296 logger.error("handleSesionUpdatesNative failed", e);
298 resetSessionMaxIdleTimeOut(request);
302 * TODO: remove Static
305 * @param ecompRestURL
308 * @param _sessionComm
309 * @throws JsonProcessingException
312 public static void synchronizeSessionForLastMinuteRequests(HttpServletRequest request, String ecompRestURL,
313 String userName, String pwd, String uebKey, SessionCommInf _sessionComm)
314 throws JsonProcessingException, Exception {
316 HttpSession session = request.getSession(false);
320 Object portalSessionSlotCheckObj = session.getServletContext()
321 .getAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK);
322 Integer portalSessionSlotCheckinMilliSec = 5 * 60 * 1000; // (5 minutes)
323 if (portalSessionSlotCheckObj != null) {
324 portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString());
326 portalSessionSlotCheckObj = _sessionComm
327 .fetchSessionSlotCheckInterval(new String[] { ecompRestURL, userName, pwd, uebKey });
328 logger.debug("Fetching Portal Session Slot Object: " + portalSessionSlotCheckObj);
329 if (portalSessionSlotCheckObj != null) {
330 portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString());
331 session.getServletContext().setAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK,
332 portalSessionSlotCheckinMilliSec);
336 Object previousToLastAccessTimeObj = session.getAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME);
337 final long lastAccessedTimeMilliSec = session.getLastAccessedTime();
338 if (previousToLastAccessTimeObj == null) {
339 previousToLastAccessTimeObj = lastAccessedTimeMilliSec;
340 session.setAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME, previousToLastAccessTimeObj);
342 Long previousToLastAccessTime = (Long) previousToLastAccessTimeObj;
343 final int maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000;
344 if (maxIntervalMilliSec
345 - (lastAccessedTimeMilliSec - previousToLastAccessTime) <= portalSessionSlotCheckinMilliSec) {
347 String jSessionKey = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID);
348 Map<String, PortalTimeoutVO> sessionTimeoutMap = new Hashtable<String, PortalTimeoutVO>();
349 Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec;
351 sessionTimeoutMap.put(PortalTimeoutHandler.portalJSessionId(jSessionKey),
352 PortalTimeoutHandler.getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec));
353 String jsonMap = mapper.writeValueAsString(sessionTimeoutMap);
354 logger.debug("Extension requested for all the Apps and Portal; JessionKey: " + jSessionKey
355 + "; SessionMap: " + sessionTimeoutMap);
356 _sessionComm.extendSessionTimeOuts(new String[] { ecompRestURL, userName, pwd, uebKey, jsonMap });
363 * TODO: remove static
367 public static void resetSessionMaxIdleTimeOut(HttpServletRequest request) {
369 HttpSession session = request.getSession(false);
372 final Object maxIdleAttribute = session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME);
373 if (maxIdleAttribute != null) {
374 session.setMaxInactiveInterval(Integer.parseInt(maxIdleAttribute.toString()));
376 } catch (Exception e) {
377 logger.error("resetSessionMaxIdleTimeout failed", e);
385 * @param sessionTimOutMilliSec
388 private static PortalTimeoutVO getSingleSessionTimeoutObj(String jSessionKey, Long sessionTimOutMilliSec) {
389 return new PortalTimeoutVO(jSessionId(jSessionKey), sessionTimOutMilliSec);
395 * @param portalJSessionId
398 private static String jSessionKey(String jSessionId, String portalJSessionId) {
399 return portalJSessionId + "-" + jSessionId;
407 private static String portalJSessionId(String jSessionKey) {
408 return jSessionKey.split("-")[0];
416 private static String jSessionId(String jSessionKey) {
417 return jSessionKey.split("-")[1];