package org.jboss.web.tomcat.tc5.session;
import org.apache.catalina.*;
import org.jboss.mx.util.MBeanServerLocator;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Collections;
import java.beans.PropertyChangeEvent;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import org.jboss.logging.Logger;
import org.jboss.metadata.WebMetaData;
import org.jboss.web.tomcat.statistics.ReplicationStatistics;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Session;
import org.apache.catalina.util.LifecycleSupport;
public abstract class JBossManager
implements AbstractJBossManager, Lifecycle,
JBossManagerMBean, PropertyChangeListener
{
private static final String info_ = "JBossManager/1.0";
protected ReplicationStatistics stats_ = new ReplicationStatistics();
protected int invalidateSessionPolicy_ = WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET;
protected int replicationGranularity_ = WebMetaData.REPLICATION_GRANULARITY_SESSION;
protected LifecycleSupport lifecycle_ = new LifecycleSupport(this);
protected boolean started_ = false;
protected ObjectName objectName_;
protected Logger log_ = Logger.getLogger(this.getClass().getName());
protected Container container_;
protected boolean distributable_;
protected int maxInactiveInterval_ = 60;
protected int sessionIdLength_ = 16;
protected int maxActive_ = -1;
protected int createdCounter_ = 0;
protected int rejectedCounter_ = 0;
protected int activeCounter_ = 0;
protected int expiredCounter_ = 0;
protected long timeSinceLastReset_ = 0;
protected Map sessions_;
protected boolean useLocalCache_ = false;
protected PropertyChangeSupport support_ = new PropertyChangeSupport(this);
protected SessionIDGenerator sessionIDGenerator_;
public JBossManager()
{
sessionIDGenerator_ = SessionIDGenerator.getInstance();
sessions_ = Collections.synchronizedMap(new HashMap());
}
public void init(String name, WebMetaData webMetaData, boolean useJK, boolean useLocalCache) throws ClusteringNotSupportedException
{
replicationGranularity_ = webMetaData.getReplicationGranularity();
invalidateSessionPolicy_ = webMetaData.getInvalidateSessionPolicy();
useLocalCache_ = useLocalCache;
log_.info("init(): replicationGranularity_ is " + replicationGranularity_ +
" and invaldateSessionPolicy is " + invalidateSessionPolicy_);
try
{
objectName_ = new ObjectName("jboss.web:service=ClusterManager,WebModule=" + name);
}
catch (Throwable e)
{
log_.error("Could not create ObjectName", e);
throw new ClusteringNotSupportedException(e.toString());
}
}
public int getInvalidateSessionPolicy()
{
return this.invalidateSessionPolicy_;
}
public Engine getEngine()
{
Engine e = null;
for (Container c = getContainer(); e == null && c != null; c = c.getParent())
{
if (c != null && c instanceof Engine)
{
e = (Engine) c;
}
}
return e;
}
public String getJvmRoute()
{
Engine e = getEngine();
return e == null ? null : e.getJvmRoute();
}
protected String getNextId()
{
return sessionIDGenerator_.getSessionId();
}
public boolean isUseLocalCache()
{
return useLocalCache_;
}
public void setSessionCookie(String sessionId)
{
HttpServletResponse response = (HttpServletResponse) ClusteredSessionValve.responseThreadLocal.get();
setNewSessionCookie(sessionId, response);
}
public void setNewSessionCookie(String sessionId, HttpServletResponse response)
{
if (response != null)
{
Context context = (Context) container_;
if (context.getCookies())
{
Cookie newCookie = new Cookie(Globals.SESSION_COOKIE_NAME, sessionId);
if (log_.isDebugEnabled())
{
log_.debug("Setting cookie with session id:" + sessionId + " & name:" + Globals.SESSION_COOKIE_NAME);
}
newCookie.setMaxAge(-1);
newCookie.setPath(context.getPath());
response.addCookie(newCookie);
}
}
}
public ReplicationStatistics getReplicationStatistics()
{
return stats_;
}
public void resetStats()
{
stats_.resetStats();
timeSinceLastReset_ = System.currentTimeMillis();
activeCounter_ = 0;
rejectedCounter_ = 0;
createdCounter_ = 0;
expiredCounter_ = 0;
}
public long timeInSecondsSinceLastReset()
{
return (System.currentTimeMillis() - timeSinceLastReset_) / (1000L);
}
public long getActiveSessionCount()
{
return getActiveSessions();
}
public long getCreatedSessionCount()
{
return createdCounter_;
}
public long getExpiredSessionCount()
{
return expiredCounter_;
}
public long getRejectedSessionCount()
{
return rejectedCounter_;
}
public int getSessionMaxAliveTime()
{
return 0;
}
public void setSessionMaxAliveTime(int sessionMaxAliveTime)
{
}
public int getSessionAverageAliveTime()
{
return 0;
}
public void setSessionAverageAliveTime(int sessionAverageAliveTime)
{
}
public String reportReplicationStatistics()
{
StringBuffer tmp = new StringBuffer();
HashMap copy = new HashMap(stats_.getStats());
Iterator iter = copy.entrySet().iterator();
tmp.append("<table><tr>");
tmp.append("<th>sessionID</th>");
tmp.append("<th>replicationCount</th>");
tmp.append("<th>minPassivationTime</th>");
tmp.append("<th>maxPassivationTime</th>");
tmp.append("<th>totalPassivationTime</th>");
tmp.append("<th>minReplicationTime</th>");
tmp.append("<th>maxReplicationTime</th>");
tmp.append("<th>totalReplicationlTime</th>");
tmp.append("<th>loadCount</th>");
tmp.append("<th>minLoadTime</th>");
tmp.append("<th>maxLoadTime</th>");
tmp.append("<th>totalLoadlTime</th>");
while (iter.hasNext())
{
Map.Entry entry = (Map.Entry) iter.next();
ReplicationStatistics.TimeStatistic stat = (ReplicationStatistics.TimeStatistic) entry.getValue();
tmp.append("<tr><td>");
tmp.append(entry.getKey());
tmp.append("</td><td>");
tmp.append(stat.replicationCount);
tmp.append("</td><td>");
tmp.append(stat.minPassivationTime);
tmp.append("</td><td>");
tmp.append(stat.maxPassivationTime);
tmp.append("</td><td>");
tmp.append(stat.totalPassivationTime);
tmp.append("</td><td>");
tmp.append(stat.minReplicationTime);
tmp.append("</td><td>");
tmp.append(stat.maxReplicationTime);
tmp.append("</td><td>");
tmp.append(stat.totalReplicationlTime);
tmp.append("</td><td>");
tmp.append(stat.loadCount);
tmp.append("</td><td>");
tmp.append(stat.minLoadTime);
tmp.append("</td><td>");
tmp.append(stat.maxLoadTime);
tmp.append("</td><td>");
tmp.append(stat.totalLoadlTime);
tmp.append("</td></tr>");
}
tmp.append("</table>");
copy.clear();
return tmp.toString();
}
public void addLifecycleListener(LifecycleListener listener)
{
lifecycle_.addLifecycleListener(listener);
}
public LifecycleListener[] findLifecycleListeners()
{
return lifecycle_.findLifecycleListeners();
}
public void removeLifecycleListener(LifecycleListener listener)
{
lifecycle_.removeLifecycleListener(listener);
}
public void start() throws LifecycleException
{
startManager();
}
public void stop() throws LifecycleException
{
resetStats();
stopManager();
}
protected void startManager() throws LifecycleException
{
log_.info("Starting JBossManager");
if (started_)
throw new LifecycleException
("JBossManager alreadyStarted");
lifecycle_.fireLifecycleEvent(START_EVENT, null);
started_ = true;
try
{
MBeanServer server = MBeanServerLocator.locateJBoss();
server.registerMBean(this, objectName_);
}
catch (Exception e)
{
log_.error("Could not register ClusterManagerMBean to MBeanServer", e);
}
}
protected void stopManager() throws LifecycleException
{
log_.info("Stopping JBossManager");
if (!started_)
throw new LifecycleException
("JBossManager notStarted");
lifecycle_.fireLifecycleEvent(STOP_EVENT, null);
started_ = false;
try
{
MBeanServer server = MBeanServerLocator.locateJBoss();
server.unregisterMBean(objectName_);
}
catch (Exception e)
{
log_.error("Could not unregister ClusterManagerMBean from MBeanServer", e);
}
}
public Container getContainer()
{
return container_;
}
public void setContainer(Container container)
{
if ((this.container_ != null) && (this.container_ instanceof Context))
((Context) this.container_).removePropertyChangeListener(this);
this.container_ = container;
if ((this.container_ != null) && (this.container_ instanceof Context))
{
setMaxInactiveInterval
(((Context) this.container_).getSessionTimeout() * 60);
((Context) this.container_).addPropertyChangeListener(this);
}
}
public boolean getDistributable()
{
return distributable_;
}
public void setDistributable(boolean distributable)
{
this.distributable_ = distributable;
}
public String getInfo()
{
return info_;
}
public int getMaxInactiveInterval()
{
return maxInactiveInterval_;
}
public void setMaxInactiveInterval(int interval)
{
this.maxInactiveInterval_ = interval;
}
public int getSessionIdLength()
{
return sessionIdLength_;
}
public void setSessionIdLength(int idLength)
{
this.sessionIdLength_ = idLength;
}
public int getSessionCounter()
{
return createdCounter_;
}
public void setSessionCounter(int sessionCounter)
{
this.createdCounter_ = sessionCounter;
}
public int getMaxActive()
{
return maxActive_;
}
public void setMaxActive(int maxActive)
{
this.maxActive_ = maxActive;
}
public int getExpiredSessions()
{
return expiredCounter_;
}
public void setExpiredSessions(int expiredSessions)
{
this.expiredCounter_ = expiredSessions;
}
public int getRejectedSessions()
{
return rejectedCounter_;
}
public void setRejectedSessions(int rejectedSessions)
{
this.rejectedCounter_ = rejectedSessions;
}
public void addPropertyChangeListener(PropertyChangeListener listener)
{
support_.addPropertyChangeListener(listener);
}
public abstract void removeLocal(Session session);
public abstract boolean storeSession(Session session);
public int getActiveSessions()
{
return activeCounter_;
}
public void load() throws ClassNotFoundException, IOException
{
throw new RuntimeException("JBossManager.load(): Method not implemented.");
}
public void removePropertyChangeListener(PropertyChangeListener listener)
{
support_.removePropertyChangeListener(listener);
}
public void unload() throws IOException
{
throw new RuntimeException("JBossManager.load(): Method not implemented.");
}
public void backgroundProcess()
{
processExpires();
}
protected void processExpires()
{
Session sessions[] = findSessions();
if (log_.isDebugEnabled())
{
log_.debug("Looking for sessions that have expired ...");
}
for (int i = 0; i < sessions.length; ++i)
{
ClusteredSession session = (ClusteredSession) sessions[i];
if (!session.isValid())
{
continue;
}
}
}
public void propertyChange(PropertyChangeEvent evt)
{
}
abstract public ClusteredSession[] findLocalSessions();
abstract public ClusteredSession findLocalSession(String realId);
}