*/
package org.apache.catalina.ha.session;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Set;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
this.distributable = dist;
}
- @Override
- public boolean getDistributable() {
- return distributable;
- }
-
public void setName(String name) {
this.name = name;
}
}
return sb.toString();
}
+
+ public Set<String> getSessionIdsFull() {
+ Set<String> sessionIds = new HashSet<String>();
+ LazyReplicatedMap map = (LazyReplicatedMap)sessions;
+ @SuppressWarnings("unchecked") // sessions is of type Map<String, Session>
+ Iterator<String> keys = map.keySetFull().iterator();
+ while (keys.hasNext()) {
+ sessionIds.add(keys.next());
+ }
+ return sessionIds;
+ }
+
}
--- /dev/null
+package org.apache.catalina.manager;
+
+import java.security.Principal;
+import java.util.Iterator;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.SessionListener;
+
+public class DummyProxySession implements Session {
+
+ private String sessionId;
+
+ public DummyProxySession(String sessionId) {
+ this.sessionId = sessionId;
+ }
+
+ @Override
+ public void access() {
+ // NOOP
+ }
+
+ @Override
+ public void addSessionListener(SessionListener listener) {
+ // NOOP
+ }
+
+ @Override
+ public void endAccess() {
+ // NOOP
+ }
+
+ @Override
+ public void expire() {
+ // NOOP
+ }
+
+ @Override
+ public String getAuthType() {
+ return null;
+ }
+
+ @Override
+ public long getCreationTime() {
+ return 0;
+ }
+
+ @Override
+ public String getId() {
+ return sessionId;
+ }
+
+ @Override
+ public String getIdInternal() {
+ return sessionId;
+ }
+
+ @Override
+ public String getInfo() {
+ return null;
+ }
+
+ @Override
+ public long getLastAccessedTime() {
+ return 0;
+ }
+
+ @Override
+ public long getLastAccessedTimeInternal() {
+ return 0;
+ }
+
+ @Override
+ public Manager getManager() {
+ return null;
+ }
+
+ @Override
+ public int getMaxInactiveInterval() {
+ return 0;
+ }
+
+ @Override
+ public Object getNote(String name) {
+ return null;
+ }
+
+ @Override
+ public Iterator<String> getNoteNames() {
+ return null;
+ }
+
+ @Override
+ public Principal getPrincipal() {
+ return null;
+ }
+
+ @Override
+ public HttpSession getSession() {
+ return null;
+ }
+
+ @Override
+ public long getThisAccessedTime() {
+ return 0;
+ }
+
+ @Override
+ public long getThisAccessedTimeInternal() {
+ return 0;
+ }
+
+ @Override
+ public boolean isValid() {
+ return false;
+ }
+
+ @Override
+ public void recycle() {
+ // NOOP
+ }
+
+ @Override
+ public void removeNote(String name) {
+ // NOOP
+ }
+
+ @Override
+ public void removeSessionListener(SessionListener listener) {
+ // NOOP
+ }
+
+ @Override
+ public void setAuthType(String authType) {
+ // NOOP
+ }
+
+ @Override
+ public void setCreationTime(long time) {
+ // NOOP
+ }
+
+ @Override
+ public void setId(String id) {
+ this.sessionId = id;
+ }
+
+ @Override
+ public void setManager(Manager manager) {
+ // NOOP
+ }
+
+ @Override
+ public void setMaxInactiveInterval(int interval) {
+ // NOOP
+ }
+
+ @Override
+ public void setNew(boolean isNew) {
+ // NOOP
+ }
+
+ @Override
+ public void setNote(String name, Object value) {
+ // NOOP
+ }
+
+ @Override
+ public void setPrincipal(Principal principal) {
+ // NOOP
+ }
+
+ @Override
+ public void setValid(boolean isValid) {
+ // NOOP
+ }
+}
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
+import java.util.Set;
import java.util.TreeMap;
import javax.servlet.ServletException;
import org.apache.catalina.Context;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
+import org.apache.catalina.ha.session.BackupManager;
import org.apache.catalina.manager.util.BaseSessionComparator;
import org.apache.catalina.manager.util.ReverseComparator;
import org.apache.catalina.manager.util.SessionUtils;
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.util.URLEncoder;
+import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.http.fileupload.ParameterParser;
/**
}
private final Random randomSource = new Random();
+
+ private boolean showProxySessions = false;
// --------------------------------------------------------- Public Methods
args[4] = response.encodeURL
(request.getContextPath() +
"/html/sessions?path=" + URL_ENCODER.encode(displayPath));
- if (ctxt.getManager() != null) {
- args[5] = new Integer
- (ctxt.getManager().getActiveSessions());
+ Manager manager = ctxt.getManager();
+ if (manager instanceof BackupManager && showProxySessions) {
+ args[5] = new Integer(
+ ((BackupManager)manager).getActiveSessionsFull());
+ } else if (ctxt.getManager() != null){
+ args[5] = new Integer(manager.getActiveSessions());
} else {
args[5] = new Integer(0);
}
"/html/expire?path=" + URL_ENCODER.encode(displayPath));
args[9] = appsExpire;
args[10] = sm.getString("htmlManagerServlet.expire.explain");
- Manager manager = ctxt.getManager();
if (manager == null) {
args[11] = sm.getString("htmlManagerServlet.noManager");
} else {
@Override
public void init() throws ServletException {
super.init();
+
+ // Set our properties from the initialization parameters
+ String value = null;
+ try {
+ value = getServletConfig().getInitParameter("showProxySessions");
+ showProxySessions = Boolean.parseBoolean(value);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ }
+
}
// ------------------------------------------------ Sessions administration
displaySessionsListPage(path, req, resp);
}
- protected Session[] getSessionsForPath(String path) {
+ protected List<Session> getSessionsForPath(String path) {
if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
throw new IllegalArgumentException(sm.getString("managerServlet.invalidPath",
RequestUtil.filter(path)));
throw new IllegalArgumentException(sm.getString("managerServlet.noContext",
RequestUtil.filter(path)));
}
- Session[] sessions = ctxt.getManager().findSessions();
+ Manager manager = ctxt.getManager();
+ List<Session> sessions = new ArrayList<Session>();
+ sessions.addAll(Arrays.asList(manager.findSessions()));
+ if (manager instanceof BackupManager && showProxySessions) {
+ // Add dummy proxy sessions
+ Set<String> sessionIds =
+ ((BackupManager) manager).getSessionIdsFull();
+ // Remove active (primary and backup) session IDs from full list
+ for (Session session : sessions) {
+ sessionIds.remove(session.getId());
+ }
+ // Left with just proxy sessions - add them
+ for (String sessionId : sessionIds) {
+ sessions.add(new DummyProxySession(sessionId));
+ }
+ }
return sessions;
}
protected Session getSessionForPathAndId(String path, String id) throws IOException {
* @throws IOException
*/
protected void displaySessionsListPage(String path, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- List<Session> activeSessions = Arrays.asList(getSessionsForPath(path));
+ List<Session> sessions = getSessionsForPath(path);
String sortBy = req.getParameter("sort");
String orderBy = null;
if (null != sortBy && !"".equals(sortBy.trim())) {
//orderBy = "DESC";
}
try {
- Collections.sort(activeSessions, comparator);
+ Collections.sort(sessions, comparator);
} catch (IllegalStateException ise) {
// at least 1 of the sessions is invalidated
req.setAttribute(APPLICATION_ERROR, "Can't sort session list: one session is invalidated");
// keep sort order
req.setAttribute("sort", sortBy);
req.setAttribute("order", orderBy);
- req.setAttribute("activeSessions", activeSessions);
+ req.setAttribute("activeSessions", sessions);
//strong>NOTE</strong> - This header will be overridden
// automatically if a <code>RequestDispatcher.forward()</code> call is
// ultimately invoked.
public static String getDisplayCreationTimeForSession(Session in_session) {
try {
+ if (in_session.getCreationTime() == 0) {
+ return "";
+ }
DateFormat formatter = new SimpleDateFormat(DATE_TIME_FORMAT);
return formatter.format(new Date(in_session.getCreationTime()));
} catch (IllegalStateException ise) {
public static String getDisplayLastAccessedTimeForSession(Session in_session) {
try {
+ if (in_session.getLastAccessedTime() == 0) {
+ return "";
+ }
DateFormat formatter = new SimpleDateFormat(DATE_TIME_FORMAT);
return formatter.format(new Date(in_session.getLastAccessedTime()));
} catch (IllegalStateException ise) {
}
public static String getDisplayUsedTimeForSession(Session in_session) {
+ try {
+ if (in_session.getCreationTime() == 0) {
+ return "";
+ }
+ } catch (IllegalStateException ise) {
+ //ignore: invalidated session
+ return "";
+ }
return secondsToTimeString(SessionUtils.getUsedTimeForSession(in_session)/1000);
}
public static String getDisplayTTLForSession(Session in_session) {
+ try {
+ if (in_session.getCreationTime() == 0) {
+ return "";
+ }
+ } catch (IllegalStateException ise) {
+ //ignore: invalidated session
+ return "";
+ }
return secondsToTimeString(SessionUtils.getTTLForSession(in_session)/1000);
}
public static String getDisplayInactiveTimeForSession(Session in_session) {
+ try {
+ if (in_session.getCreationTime() == 0) {
+ return "";
+ }
+ } catch (IllegalStateException ise) {
+ //ignore: invalidated session
+ return "";
+ }
return secondsToTimeString(SessionUtils.getInactiveTimeForSession(in_session)/1000);
}
return in_session.getPrincipal().getName();
}
HttpSession httpSession = in_session.getSession();
+ if (httpSession == null)
+ return null;
+
try {
Object user = null;
// First search "known locations"
applications that redirect users to the html interface rather than
returning a 404. (markt)
</add>
+ <add>
+ Provide the HTML Manager application with the ability to differentiate
+ between primary, backup and proxy sessions. Note that proxy sessions are
+ only shown if enabled in web.xml. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Other">
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+
+<%@page import="org.apache.catalina.manager.DummyProxySession"%><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<% String path = (String) request.getAttribute("path");
String submitUrl = response.encodeURL(((HttpServletRequest)
pageContext.getRequest()).getRequestURI() + "?path=" + path);
} else {
type = "Backup";
}
+ } else if (currentSession instanceof DummyProxySession) {
+ type = "Proxy";
} else {
type = "Primary";
}
%>
<tr>
<td><input type="checkbox" name="sessionIds" value="<%= currentSessionId %>" />
+ <%
+ if ("Proxy".equals(type)) {
+ out.print(currentSessionId);
+ } else {
+ %>
<a href="<%= submitUrl %>&action=sessionDetail&sessionId=<%= currentSessionId %>&sessionType=<%= type %>"><%= JspHelper.escapeXml(currentSessionId) %></a>
+ <%
+ }
+ %>
</td>
<td style="text-align: center;"><%= type %></td>
<td style="text-align: center;"><%= JspHelper.guessDisplayLocaleFromSession(currentSession) %></td>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
+ <!-- Uncomment this to show proxy sessions from the Backup manager in the
+ sessions list for an application
+ <init-param>
+ <param-name>showProxySessions</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ -->
<multipart-config>
<!-- 50MB max -->
<max-file-size>52428800</max-file-size>