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.onap.portalsdk.core.onboarding.listener;
40 import java.util.Calendar;
41 import java.util.Hashtable;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpSession;
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49 import org.onap.portalsdk.core.onboarding.crossapi.SessionCommunicationService;
50 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
51 import org.onap.portalsdk.core.restful.domain.PortalTimeoutVO;
53 import com.fasterxml.jackson.core.JsonProcessingException;
54 import com.fasterxml.jackson.core.type.TypeReference;
55 import com.fasterxml.jackson.databind.ObjectMapper;
58 * Invoked by listeners (UserContextListener and UserSessionListener) to track
61 public class PortalTimeoutHandler {
63 protected static final SessionCommInf sessionComm = new SessionComm();
65 public interface SessionCommInf {
66 public Integer fetchSessionSlotCheckInterval(String... params);
68 public void extendSessionTimeOuts(String... sessionMap);
71 public static class SessionComm implements SessionCommInf {
72 public Integer fetchSessionSlotCheckInterval(String... params) {
74 String ecompRestURL = params[0];
75 String userName = params[1];
76 String pwd = params[2];
77 String uebKey = params[3];
79 String sessionSlot = SessionCommunicationService.getSessionSlotCheckInterval(ecompRestURL, userName, pwd,
81 if (sessionSlot == null)
83 return Integer.parseInt(sessionSlot);
86 public void extendSessionTimeOuts(String... params) {
88 String ecompRestURL = params[0];
89 String userName = params[1];
90 String pwd = params[2];
91 String uebKey = params[3];
92 String sessionTimeoutMap = params[4];
94 SessionCommunicationService.requestPortalSessionTimeoutExtension(ecompRestURL, userName, pwd, uebKey,
99 public static final Map<String, HttpSession> sessionMap = new Hashtable<String, HttpSession>();
100 public static final Integer repeatInterval = 15 * 60; // 15 minutes
101 protected static final Log logger = LogFactory.getLog(PortalTimeoutHandler.class);
102 static ObjectMapper mapper = new ObjectMapper();
103 private static PortalTimeoutHandler timeoutHandler;
105 public static PortalTimeoutHandler getInstance() {
106 if (timeoutHandler == null)
107 timeoutHandler = new PortalTimeoutHandler();
109 return timeoutHandler;
113 * TODO: remove static
115 * @param portalJSessionId
116 * Portal (remote) session ID
122 public static void sessionCreated(String portalJSessionId, String jSessionId, HttpSession session) {
124 storeMaxInactiveTime(session);
126 // this key is a combination of portal jsession id and app session id
127 String jSessionKey = jSessionKey(jSessionId, portalJSessionId);
128 Object jSessionKeySessionVal = session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID);
130 // do not reset the attributes if the same values have already been set
131 // because that will cause PortalTimeoutBindingListener to unbound the
133 if (jSessionKeySessionVal != null && jSessionKeySessionVal.equals(jSessionKey)) {
134 logger.debug(" Session Values already exist in te map for sessionKey " + jSessionKey);
138 session.setAttribute(PortalApiConstants.PORTAL_JSESSION_ID, jSessionKey);
140 // session binding listener will add this value to the static map
141 // and with session replication the listener will fire in all tomcat
143 session.setAttribute(PortalApiConstants.PORTAL_JSESSION_BIND, new PortalTimeoutBindingListener());
144 // sessionMap.put((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID),
150 * TODO: remove static
154 protected static void storeMaxInactiveTime(HttpSession session) {
155 if (session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null)
156 session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME, session.getMaxInactiveInterval());
160 * TODO: remove static
165 public static void sessionDestroyed(HttpSession session) {
167 logger.info(" Session getting destroyed - id: " + session.getId());
168 session.removeAttribute(PortalApiConstants.PORTAL_JSESSION_BIND);
169 // sessionMap.remove((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID));
170 } catch (Exception e) {
171 logger.error("sessionDestroyed failed", e);
176 * TODO: remove static
178 * @param portalJSessionId
180 * @return true on success, false if the session cannot be found, etc.
182 public static boolean invalidateSession(String portalJSessionId) {
183 boolean result = false;
184 logger.debug("Session Management: request from Portal to invalidate the session: " + portalJSessionId);
185 for (String jSessionKey : sessionMap.keySet()) {
187 HttpSession session = sessionMap.get(jSessionKey);
188 if (portalJSessionId(jSessionKey).equals(portalJSessionId)) {
189 session.invalidate();
192 } catch (Exception e) {
193 logger.error("invalidateSession failed", e);
200 * TODO: remove static
202 * @return json version of the timeout map: session ID -> timeout object
204 public static String gatherSessionExtensions() {
205 logger.debug("Session Management: gatherSessionExtensions");
207 Map<String, PortalTimeoutVO> sessionTimeoutMap = new Hashtable<String, PortalTimeoutVO>();
210 for (String jSessionKey : sessionMap.keySet()) {
213 // get the expirytime in seconds
214 HttpSession session = sessionMap.get(jSessionKey);
216 Long lastAccessedTimeMilliSec = session.getLastAccessedTime();
217 Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L;
218 // Long currentTimeMilliSec =
219 // Calendar.getInstance().getTimeInMillis() ;
220 // (maxIntervalMilliSec - (currentTimeMilliSec -
221 // lastAccessedTimeMilliSec) + ;
222 Calendar instance = Calendar.getInstance();
223 instance.setTimeInMillis(session.getLastAccessedTime());
224 logger.debug("Session Management: Last Accessed time for " + jSessionKey + ": " + instance.getTime());
226 Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec;
228 sessionTimeoutMap.put(portalJSessionId(jSessionKey),
229 getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec));
230 logger.debug("Session Management: putting session in map " + jSessionKey + " sessionTimoutSec"
231 + (int) (sessionTimOutMilliSec / 1000));
233 jsonMap = mapper.writeValueAsString(sessionTimeoutMap);
235 } catch (Exception e) {
236 logger.error("gatherSessionExtensions failed", e);
246 * TODO: remove static
248 * @param sessionTimeoutMapStr
249 * Session timeout map as string
250 * @return true on success, false otherwise
252 public static boolean updateSessionExtensions(String sessionTimeoutMapStr) {
253 logger.debug("Session Management: updateSessionExtensions");
254 // Map<String,Object> sessionTimeoutMap =
255 // mapper.readValue(sessionTimeoutMapStr, Map.class);
256 Map<String, PortalTimeoutVO> sessionTimeoutMap = null;
259 TypeReference<Hashtable<String, PortalTimeoutVO>> typeRef = new TypeReference<Hashtable<String, PortalTimeoutVO>>() {
261 sessionTimeoutMap = mapper.readValue(sessionTimeoutMapStr, typeRef);
262 } catch (Exception e) {
263 logger.error("updateSessionExtensions failed to parse the sessionTimeoutMap from portal", e);
267 boolean result = true;
268 for (String jPortalSessionId : sessionTimeoutMap.keySet()) {
270 PortalTimeoutVO extendedTimeoutVO = mapper.readValue(
271 mapper.writeValueAsString(sessionTimeoutMap.get(jPortalSessionId)), PortalTimeoutVO.class);
272 HttpSession session = sessionMap.get(jSessionKey(extendedTimeoutVO.getjSessionId(), jPortalSessionId));
274 if (session == null) {
278 Long lastAccessedTimeMilliSec = session.getLastAccessedTime();
279 Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L;
280 Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec;
282 Long maxTimeoutTimeMilliSec = extendedTimeoutVO.getSessionTimOutMilliSec();
283 if (maxTimeoutTimeMilliSec > sessionTimOutMilliSec) {
284 session.setMaxInactiveInterval((int) (maxTimeoutTimeMilliSec - lastAccessedTimeMilliSec) / 1000);
285 logger.debug("Session Management: extended session for :" + session.getId() + " to :"
286 + (int) (maxTimeoutTimeMilliSec / 1000));
287 // System.out.println("!!!!!!!!!extended session for :" +
288 // session.getId() + " to :" +
289 // (int)(maxTimeoutTimeMilliSec/1000));
291 } catch (Exception e) {
292 logger.error("updateSessionExtensions failed to update session timeouts", e);
293 // Signal a problem if any one of them fails
302 * TODO: Remove static
311 * UEB key (application ID)
312 * @param ecompRestURL
314 * @param _sessionComm
315 * Session communication information
317 public static void handleSessionUpdatesNative(HttpServletRequest request, String userName, String pwd,
318 String uebKey, String ecompRestURL, SessionCommInf _sessionComm) {
320 if (_sessionComm == null) {
321 _sessionComm = sessionComm;
324 synchronizeSessionForLastMinuteRequests(request, ecompRestURL, userName, pwd, uebKey, _sessionComm);
325 } catch (Exception e) {
326 logger.error("handleSesionUpdatesNative failed", e);
328 resetSessionMaxIdleTimeOut(request);
332 * TODO: remove Static
336 * @param ecompRestURL
344 * @param _sessionComm
345 * session information
346 * @throws JsonProcessingException
347 * On failure to serialize
349 public static void synchronizeSessionForLastMinuteRequests(HttpServletRequest request, String ecompRestURL,
350 String userName, String pwd, String uebKey, SessionCommInf _sessionComm) throws JsonProcessingException {
352 HttpSession session = request.getSession(false);
356 Object portalSessionSlotCheckObj = session.getServletContext()
357 .getAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK);
358 Integer portalSessionSlotCheckinMilliSec = 5 * 60 * 1000; // (5 minutes)
359 if (portalSessionSlotCheckObj != null) {
360 portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString());
362 portalSessionSlotCheckObj = _sessionComm
363 .fetchSessionSlotCheckInterval(new String[] { ecompRestURL, userName, pwd, uebKey });
364 logger.debug("Fetching Portal Session Slot Object: " + portalSessionSlotCheckObj);
365 if (portalSessionSlotCheckObj != null) {
366 portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString());
367 session.getServletContext().setAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK,
368 portalSessionSlotCheckinMilliSec);
372 Object previousToLastAccessTimeObj = session.getAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME);
373 final long lastAccessedTimeMilliSec = session.getLastAccessedTime();
374 if (previousToLastAccessTimeObj == null) {
375 previousToLastAccessTimeObj = lastAccessedTimeMilliSec;
376 session.setAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME, previousToLastAccessTimeObj);
378 Long previousToLastAccessTime = (Long) previousToLastAccessTimeObj;
379 final int maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000;
380 if (maxIntervalMilliSec
381 - (lastAccessedTimeMilliSec - previousToLastAccessTime) <= portalSessionSlotCheckinMilliSec) {
383 String jSessionKey = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID);
384 Map<String, PortalTimeoutVO> sessionTimeoutMap = new Hashtable<String, PortalTimeoutVO>();
385 Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec;
387 sessionTimeoutMap.put(PortalTimeoutHandler.portalJSessionId(jSessionKey),
388 PortalTimeoutHandler.getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec));
389 String jsonMap = mapper.writeValueAsString(sessionTimeoutMap);
390 logger.debug("Extension requested for all the Apps and Portal; JessionKey: " + jSessionKey
391 + "; SessionMap: " + sessionTimeoutMap);
392 _sessionComm.extendSessionTimeOuts(new String[] { ecompRestURL, userName, pwd, uebKey, jsonMap });
399 * TODO: remove static
404 public static void resetSessionMaxIdleTimeOut(HttpServletRequest request) {
406 HttpSession session = request.getSession(false);
409 final Object maxIdleAttribute = session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME);
410 if (maxIdleAttribute != null) {
411 session.setMaxInactiveInterval(Integer.parseInt(maxIdleAttribute.toString()));
413 } catch (Exception e) {
414 logger.error("resetSessionMaxIdleTimeout failed", e);
422 * @param sessionTimOutMilliSec
425 private static PortalTimeoutVO getSingleSessionTimeoutObj(String jSessionKey, Long sessionTimOutMilliSec) {
426 return new PortalTimeoutVO(jSessionId(jSessionKey), sessionTimOutMilliSec);
432 * @param portalJSessionId
435 private static String jSessionKey(String jSessionId, String portalJSessionId) {
436 return portalJSessionId + "-" + jSessionId;
444 private static String portalJSessionId(String jSessionKey) {
445 return jSessionKey.split("-")[0];
453 private static String jSessionId(String jSessionKey) {
454 return jSessionKey.split("-")[1];