001/* 002 * 003 * (C) Copyright 2006-2009 Nuxeo SAS (http://nuxeo.com/) and contributors. 004 * 005 * All rights reserved. This program and the accompanying materials 006 * are made available under the terms of the GNU Lesser General Public License 007 * (LGPL) version 2.1 which accompanies this distribution, and is available at 008 * http://www.gnu.org/licenses/lgpl.html 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * Contributors: 016 * Nuxeo - initial API and implementation 017 * 018 * $Id$ 019 */ 020 021package org.nuxeo.ecm.platform.web.common.session; 022 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.List; 027import java.util.Map; 028import java.util.concurrent.ConcurrentHashMap; 029 030import javax.servlet.http.HttpServletRequest; 031import javax.servlet.http.HttpSession; 032 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.nuxeo.runtime.management.counters.CounterHelper; 036 037/** 038 * Singleton used to keep track of all HttpSessions. This Singleton is populated/updated either via the 039 * HttpSessionListener or via directedly via the Authentication filter 040 * 041 * @author Tiry (tdelprat@nuxeo.com) 042 * @since 5.4.2 043 */ 044public class NuxeoHttpSessionMonitor { 045 046 public static final String REQUEST_COUNTER = "org.nuxeo.web.requests"; 047 048 public static final String SESSION_COUNTER = "org.nuxeo.web.sessions"; 049 050 public static final long REQUEST_COUNTER_STEP = 5; 051 052 protected static final Log log = LogFactory.getLog(NuxeoHttpSessionMonitor.class); 053 054 protected static NuxeoHttpSessionMonitor instance = new NuxeoHttpSessionMonitor(); 055 056 protected long globalRequestCounter; 057 058 public static NuxeoHttpSessionMonitor instance() { 059 return instance; 060 } 061 062 protected Map<String, SessionInfo> sessionTracker = new ConcurrentHashMap<String, SessionInfo>(); 063 064 protected void increaseRequestCounter() { 065 globalRequestCounter += 1; 066 if (globalRequestCounter == 1 || globalRequestCounter % REQUEST_COUNTER_STEP == 0) { 067 CounterHelper.setCounterValue(REQUEST_COUNTER, globalRequestCounter); 068 } 069 } 070 071 public SessionInfo addEntry(HttpSession session) { 072 if (session == null || session.getId() == null) { 073 return null; 074 } 075 SessionInfo si = new SessionInfo(session.getId()); 076 sessionTracker.put(session.getId(), si); 077 return si; 078 } 079 080 public SessionInfo associatedUser(HttpServletRequest request) { 081 HttpSession session = request.getSession(false); 082 if (session != null && session.getId() != null) { 083 SessionInfo si = sessionTracker.get(session.getId()); 084 if (si == null) { 085 si = addEntry(session); 086 } 087 if (request.getUserPrincipal() != null && si.getLoginName() == null) { 088 si.setLoginName(request.getUserPrincipal().getName()); 089 CounterHelper.increaseCounter(SESSION_COUNTER); 090 } 091 si.setLastAccessUrl(request.getRequestURI()); 092 increaseRequestCounter(); 093 return si; 094 } 095 return null; 096 } 097 098 public SessionInfo associatedUser(HttpSession session, String userName) { 099 if (session == null || session.getId() == null) { 100 return null; 101 } 102 SessionInfo si = sessionTracker.get(session.getId()); 103 if (si == null) { 104 si = addEntry(session); 105 } 106 if (si.getLoginName() == null) { 107 si.setLoginName(userName); 108 CounterHelper.increaseCounter(SESSION_COUNTER); 109 } 110 return si; 111 } 112 113 public SessionInfo updateEntry(HttpServletRequest request) { 114 HttpSession session = request.getSession(false); 115 if (session != null && session.getId() != null) { 116 SessionInfo si = sessionTracker.get(session.getId()); 117 if (si != null) { 118 si.updateLastAccessTime(); 119 si.setLastAccessUrl(request.getRequestURI()); 120 increaseRequestCounter(); 121 return si; 122 } else { 123 return addEntry(session); 124 } 125 } 126 return null; 127 } 128 129 public void removeEntry(String sid) { 130 SessionInfo si = sessionTracker.remove(sid); 131 if (si != null && si.getLoginName() != null) { 132 CounterHelper.decreaseCounter(SESSION_COUNTER); 133 } 134 } 135 136 public Collection<SessionInfo> getTrackedSessions() { 137 return sessionTracker.values(); 138 } 139 140 public List<SessionInfo> getSortedSessions() { 141 142 List<SessionInfo> sortedSessions = new ArrayList<SessionInfo>(); 143 for (SessionInfo si : getTrackedSessions()) { 144 if (si.getLoginName() != null) { 145 sortedSessions.add(si); 146 } 147 } 148 Collections.sort(sortedSessions); 149 return sortedSessions; 150 } 151 152 public List<SessionInfo> getSortedSessions(long maxInactivity) { 153 List<SessionInfo> sortedSessions = new ArrayList<SessionInfo>(); 154 for (SessionInfo si : getTrackedSessions()) { 155 if (si.getLoginName() != null && si.getInactivityInS() < maxInactivity) { 156 sortedSessions.add(si); 157 } 158 } 159 Collections.sort(sortedSessions); 160 return sortedSessions; 161 } 162 163 public long getGlobalRequestCounter() { 164 return globalRequestCounter; 165 } 166 167}