001/* 002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.web.common.session; 023 024import java.util.ArrayList; 025import java.util.Collection; 026import java.util.Collections; 027import java.util.List; 028import java.util.Map; 029import java.util.concurrent.ConcurrentHashMap; 030 031import javax.servlet.http.HttpServletRequest; 032import javax.servlet.http.HttpSession; 033 034import org.apache.commons.logging.Log; 035import org.apache.commons.logging.LogFactory; 036import org.nuxeo.runtime.management.counters.CounterHelper; 037 038/** 039 * Singleton used to keep track of all HttpSessions. This Singleton is populated/updated either via the 040 * HttpSessionListener or via directedly via the Authentication filter 041 * 042 * @author Tiry (tdelprat@nuxeo.com) 043 * @since 5.4.2 044 */ 045public class NuxeoHttpSessionMonitor { 046 047 public static final String REQUEST_COUNTER = "org.nuxeo.web.requests"; 048 049 public static final String SESSION_COUNTER = "org.nuxeo.web.sessions"; 050 051 public static final long REQUEST_COUNTER_STEP = 5; 052 053 protected static final Log log = LogFactory.getLog(NuxeoHttpSessionMonitor.class); 054 055 protected static NuxeoHttpSessionMonitor instance = new NuxeoHttpSessionMonitor(); 056 057 protected long globalRequestCounter; 058 059 public static NuxeoHttpSessionMonitor instance() { 060 return instance; 061 } 062 063 protected Map<String, SessionInfo> sessionTracker = new ConcurrentHashMap<String, SessionInfo>(); 064 065 protected void increaseRequestCounter() { 066 globalRequestCounter += 1; 067 if (globalRequestCounter == 1 || globalRequestCounter % REQUEST_COUNTER_STEP == 0) { 068 CounterHelper.setCounterValue(REQUEST_COUNTER, globalRequestCounter); 069 } 070 } 071 072 public SessionInfo addEntry(HttpSession session) { 073 if (session == null || session.getId() == null) { 074 return null; 075 } 076 SessionInfo si = new SessionInfo(session.getId()); 077 sessionTracker.put(session.getId(), si); 078 return si; 079 } 080 081 public SessionInfo associatedUser(HttpServletRequest request) { 082 HttpSession session = request.getSession(false); 083 if (session != null && session.getId() != null) { 084 SessionInfo si = sessionTracker.get(session.getId()); 085 if (si == null) { 086 si = addEntry(session); 087 } 088 if (request.getUserPrincipal() != null && si.getLoginName() == null) { 089 si.setLoginName(request.getUserPrincipal().getName()); 090 CounterHelper.increaseCounter(SESSION_COUNTER); 091 } 092 si.setLastAccessUrl(request.getRequestURI()); 093 increaseRequestCounter(); 094 return si; 095 } 096 return null; 097 } 098 099 public SessionInfo associatedUser(HttpSession session, String userName) { 100 if (session == null || session.getId() == null) { 101 return null; 102 } 103 SessionInfo si = sessionTracker.get(session.getId()); 104 if (si == null) { 105 si = addEntry(session); 106 } 107 if (si.getLoginName() == null) { 108 si.setLoginName(userName); 109 CounterHelper.increaseCounter(SESSION_COUNTER); 110 } 111 return si; 112 } 113 114 public SessionInfo updateEntry(HttpServletRequest request) { 115 HttpSession session = request.getSession(false); 116 if (session != null && session.getId() != null) { 117 SessionInfo si = sessionTracker.get(session.getId()); 118 if (si != null) { 119 si.updateLastAccessTime(); 120 si.setLastAccessUrl(request.getRequestURI()); 121 increaseRequestCounter(); 122 return si; 123 } else { 124 return addEntry(session); 125 } 126 } 127 return null; 128 } 129 130 public void removeEntry(String sid) { 131 SessionInfo si = sessionTracker.remove(sid); 132 if (si != null && si.getLoginName() != null) { 133 CounterHelper.decreaseCounter(SESSION_COUNTER); 134 } 135 } 136 137 public Collection<SessionInfo> getTrackedSessions() { 138 return sessionTracker.values(); 139 } 140 141 public List<SessionInfo> getSortedSessions() { 142 143 List<SessionInfo> sortedSessions = new ArrayList<SessionInfo>(); 144 for (SessionInfo si : getTrackedSessions()) { 145 if (si.getLoginName() != null) { 146 sortedSessions.add(si); 147 } 148 } 149 Collections.sort(sortedSessions); 150 return sortedSessions; 151 } 152 153 public List<SessionInfo> getSortedSessions(long maxInactivity) { 154 List<SessionInfo> sortedSessions = new ArrayList<SessionInfo>(); 155 for (SessionInfo si : getTrackedSessions()) { 156 if (si.getLoginName() != null && si.getInactivityInS() < maxInactivity) { 157 sortedSessions.add(si); 158 } 159 } 160 Collections.sort(sortedSessions); 161 return sortedSessions; 162 } 163 164 public long getGlobalRequestCounter() { 165 return globalRequestCounter; 166 } 167 168}