KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > tomcat > tc5 > session > JBossManager


1 /*
2  * JBoss, the OpenSource WebOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.web.tomcat.tc5.session;
8
9 import org.apache.catalina.*;
10 import org.jboss.mx.util.MBeanServerLocator;
11
12 import java.beans.PropertyChangeListener JavaDoc;
13 import java.beans.PropertyChangeSupport JavaDoc;
14
15 import java.io.IOException JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Collections JavaDoc;
20 import java.beans.PropertyChangeEvent JavaDoc;
21 import javax.management.MBeanServer JavaDoc;
22 import javax.management.ObjectName JavaDoc;
23 import javax.servlet.http.HttpServletResponse JavaDoc;
24 import javax.servlet.http.Cookie JavaDoc;
25
26 import org.jboss.logging.Logger;
27 import org.jboss.metadata.WebMetaData;
28 import org.jboss.web.tomcat.statistics.ReplicationStatistics;
29 import org.apache.catalina.Container;
30 import org.apache.catalina.Context;
31 import org.apache.catalina.Lifecycle;
32 import org.apache.catalina.LifecycleException;
33 import org.apache.catalina.LifecycleListener;
34 import org.apache.catalina.Session;
35 import org.apache.catalina.util.LifecycleSupport;
36
37 /**
38  * Base abstract implementation of Tomcat manager without the concept of
39  * session operations, e.g., add, remove, etc.
40  *
41  * @author Ben Wang
42  * @version $Revision: 1.5.2.4 $
43  */

44 public abstract class JBossManager
45    implements AbstractJBossManager, Lifecycle,
46       JBossManagerMBean, PropertyChangeListener JavaDoc
47 {
48
49    // -- Constants ----------------------------------------
50
/**
51     * Informational name for this Catalina component
52     */

53    private static final String JavaDoc info_ = "JBossManager/1.0";
54
55    // -- Class attributes ---------------------------------
56
protected ReplicationStatistics stats_ = new ReplicationStatistics();
57
58    /**
59     * Policy to determine if a session is dirty
60     */

61    protected int invalidateSessionPolicy_ = WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET;
62    /**
63     * Replication granulairty.
64     */

65    protected int replicationGranularity_ = WebMetaData.REPLICATION_GRANULARITY_SESSION;
66    /**
67     * The lifecycle_ event support for this component.
68     */

69    protected LifecycleSupport lifecycle_ = new LifecycleSupport(this);
70    /**
71     * Has this component been started_ yet?
72     */

73    protected boolean started_ = false;
74    /**
75     * The objectname this Manager is associated with
76     */

77    protected ObjectName JavaDoc objectName_;
78    /**
79     * The Log-object for this class
80     */

81    protected Logger log_ = Logger.getLogger(this.getClass().getName());
82    /**
83     * The Container with which this Manager is associated.
84     */

85    protected Container container_;
86   /**
87    /**
88     * The distributable flag for Sessions created by this Manager. If this
89     * flag is set to <code>true</code>, any user attributes added to a
90     * session controlled by this Manager must be Serializable.
91     */

92    protected boolean distributable_;
93    /**
94     * The default maximum inactive interval for Sessions created by
95     * this Manager.
96     */

97    protected int maxInactiveInterval_ = 60;
98    /**
99     * The session id length of Sessions created by this Manager.
100     */

101    protected int sessionIdLength_ = 16;
102
103    // Maximum of ative sessions allowed. -1 is unlimited.
104
protected int maxActive_ = -1;
105
106    // Number of sessions created by this manager
107
protected int createdCounter_ = 0;
108
109    // number of rejected sessions because the number active sessions exceeds maxActive
110
protected int rejectedCounter_ = 0;
111
112    // Number of active sessions
113
protected int activeCounter_ = 0;
114
115    // number of expired session ids. Not sure what exactly does it mean in our clustered case.
116
protected int expiredCounter_ = 0;
117
118    protected long timeSinceLastReset_ = 0;
119
120    /**
121     * Store the local sessions.
122     */

123    protected Map JavaDoc sessions_;
124
125    /**
126     * If set to true, it will not replicate the access time stamp unless attributes are dirty.
127     */

128    protected boolean useLocalCache_ = false;
129
130    /**
131     * The property change support for this component.
132     */

133    protected PropertyChangeSupport JavaDoc support_ = new PropertyChangeSupport JavaDoc(this);
134
135    protected SessionIDGenerator sessionIDGenerator_;
136
137    // TODO Need a string manager to handle exception localization
138

139    public JBossManager()
140    {
141       sessionIDGenerator_ = SessionIDGenerator.getInstance();
142       sessions_ = Collections.synchronizedMap(new HashMap JavaDoc());
143    }
144
145    public void init(String JavaDoc name, WebMetaData webMetaData, boolean useJK, boolean useLocalCache) throws ClusteringNotSupportedException
146    {
147       replicationGranularity_ = webMetaData.getReplicationGranularity();
148       invalidateSessionPolicy_ = webMetaData.getInvalidateSessionPolicy();
149       useLocalCache_ = useLocalCache;
150       log_.info("init(): replicationGranularity_ is " + replicationGranularity_ +
151          " and invaldateSessionPolicy is " + invalidateSessionPolicy_);
152
153       try
154       {
155          // Give this manager a name
156
objectName_ = new ObjectName JavaDoc("jboss.web:service=ClusterManager,WebModule=" + name);
157       }
158       catch (Throwable JavaDoc e)
159       {
160          log_.error("Could not create ObjectName", e);
161          throw new ClusteringNotSupportedException(e.toString());
162       }
163    }
164
165    public int getInvalidateSessionPolicy()
166    {
167       return this.invalidateSessionPolicy_;
168    }
169
170    /**
171     * Retrieve the enclosing Engine for this Manager.
172     *
173     * @return an Engine object (or null).
174     */

175    public Engine getEngine()
176    {
177       Engine e = null;
178       for (Container c = getContainer(); e == null && c != null; c = c.getParent())
179       {
180          if (c != null && c instanceof Engine)
181          {
182             e = (Engine) c;
183          }
184       }
185       return e;
186    }
187
188    /**
189     * Retrieve the JvmRoute for the enclosing Engine.
190     *
191     * @return the JvmRoute or null.
192     */

193    public String JavaDoc getJvmRoute()
194    {
195       Engine e = getEngine();
196       return e == null ? null : e.getJvmRoute();
197    }
198
199    /**
200     * Get a new session-id from the distributed store
201     *
202     * @return new session-id
203     */

204    protected String JavaDoc getNextId()
205    {
206       return sessionIDGenerator_.getSessionId();
207    }
208
209    public boolean isUseLocalCache()
210    {
211       return useLocalCache_;
212    }
213
214    /**
215     * Sets a new cookie for the given session id and response
216     *
217     * @param sessionId The session id
218     */

219    public void setSessionCookie(String JavaDoc sessionId)
220    {
221       HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) ClusteredSessionValve.responseThreadLocal.get();
222       setNewSessionCookie(sessionId, response);
223    }
224
225    public void setNewSessionCookie(String JavaDoc sessionId, HttpServletResponse JavaDoc response)
226    {
227       if (response != null)
228       {
229          Context context = (Context) container_;
230          if (context.getCookies())
231          {
232             // set a new session cookie
233
Cookie JavaDoc newCookie = new Cookie JavaDoc(Globals.SESSION_COOKIE_NAME, sessionId);
234             if (log_.isDebugEnabled())
235             {
236                log_.debug("Setting cookie with session id:" + sessionId + " & name:" + Globals.SESSION_COOKIE_NAME);
237             }
238             newCookie.setMaxAge(-1);
239             newCookie.setPath(context.getPath());
240             response.addCookie(newCookie);
241          }
242       }
243    }
244
245    // JBossManagerMBean-methods -------------------------------------
246

247    public ReplicationStatistics getReplicationStatistics()
248    {
249       return stats_;
250    }
251
252    public void resetStats()
253    {
254       stats_.resetStats();
255       timeSinceLastReset_ = System.currentTimeMillis();
256       activeCounter_ = 0;
257       rejectedCounter_ = 0;
258       createdCounter_ = 0;
259       expiredCounter_ = 0;
260    }
261
262    public long timeInSecondsSinceLastReset()
263    {
264       return (System.currentTimeMillis() - timeSinceLastReset_) / (1000L);
265    }
266
267    public long getActiveSessionCount()
268    {
269       return getActiveSessions();
270    }
271
272    public long getCreatedSessionCount()
273    {
274       return createdCounter_;
275    }
276
277    public long getExpiredSessionCount()
278    {
279       return expiredCounter_;
280    }
281
282    public long getRejectedSessionCount()
283    {
284       return rejectedCounter_;
285    }
286
287    public int getSessionMaxAliveTime()
288    {
289        return 0;
290    }
291
292    public void setSessionMaxAliveTime(int sessionMaxAliveTime)
293    {
294    }
295
296    public int getSessionAverageAliveTime()
297    {
298        return 0;
299    }
300
301    public void setSessionAverageAliveTime(int sessionAverageAliveTime)
302    {
303    }
304
305    public String JavaDoc reportReplicationStatistics()
306    {
307       StringBuffer JavaDoc tmp = new StringBuffer JavaDoc();
308       HashMap JavaDoc copy = new HashMap JavaDoc(stats_.getStats());
309       Iterator JavaDoc iter = copy.entrySet().iterator();
310       tmp.append("<table><tr>");
311       tmp.append("<th>sessionID</th>");
312       tmp.append("<th>replicationCount</th>");
313       tmp.append("<th>minPassivationTime</th>");
314       tmp.append("<th>maxPassivationTime</th>");
315       tmp.append("<th>totalPassivationTime</th>");
316       tmp.append("<th>minReplicationTime</th>");
317       tmp.append("<th>maxReplicationTime</th>");
318       tmp.append("<th>totalReplicationlTime</th>");
319       tmp.append("<th>loadCount</th>");
320       tmp.append("<th>minLoadTime</th>");
321       tmp.append("<th>maxLoadTime</th>");
322       tmp.append("<th>totalLoadlTime</th>");
323       while (iter.hasNext())
324       {
325          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
326          ReplicationStatistics.TimeStatistic stat = (ReplicationStatistics.TimeStatistic) entry.getValue();
327          tmp.append("<tr><td>");
328          tmp.append(entry.getKey());
329          tmp.append("</td><td>");
330          tmp.append(stat.replicationCount);
331          tmp.append("</td><td>");
332          tmp.append(stat.minPassivationTime);
333          tmp.append("</td><td>");
334          tmp.append(stat.maxPassivationTime);
335          tmp.append("</td><td>");
336          tmp.append(stat.totalPassivationTime);
337          tmp.append("</td><td>");
338          tmp.append(stat.minReplicationTime);
339          tmp.append("</td><td>");
340          tmp.append(stat.maxReplicationTime);
341          tmp.append("</td><td>");
342          tmp.append(stat.totalReplicationlTime);
343          tmp.append("</td><td>");
344          tmp.append(stat.loadCount);
345          tmp.append("</td><td>");
346          tmp.append(stat.minLoadTime);
347          tmp.append("</td><td>");
348          tmp.append(stat.maxLoadTime);
349          tmp.append("</td><td>");
350          tmp.append(stat.totalLoadlTime);
351          tmp.append("</td></tr>");
352       }
353       tmp.append("</table>");
354       copy.clear();
355       return tmp.toString();
356
357    }
358
359    // Lifecycle-methods -------------------------------------
360

361    public void addLifecycleListener(LifecycleListener listener)
362    {
363       lifecycle_.addLifecycleListener(listener);
364    }
365
366    public LifecycleListener[] findLifecycleListeners()
367    {
368       return lifecycle_.findLifecycleListeners();
369    }
370
371    public void removeLifecycleListener(LifecycleListener listener)
372    {
373       lifecycle_.removeLifecycleListener(listener);
374    }
375
376    /**
377     * Start this Manager
378     *
379     * @throws org.apache.catalina.LifecycleException
380     *
381     */

382    public void start() throws LifecycleException
383    {
384       startManager();
385    }
386
387    /**
388     * Stop this Manager
389     *
390     * @throws org.apache.catalina.LifecycleException
391     *
392     */

393    public void stop() throws LifecycleException
394    {
395       resetStats();
396       stopManager();
397    }
398
399    /**
400     * Prepare for the beginning of active use of the public methods of this
401     * component. This method should be called after <code>configure()</code>,
402     * and before any of the public methods of the component are utilized.
403     *
404     * @throws IllegalStateException if this component has already been
405     * started_
406     * @throws org.apache.catalina.LifecycleException
407     * if this component detects a fatal error
408     * that prevents this component from being used
409     */

410    protected void startManager() throws LifecycleException
411    {
412       log_.info("Starting JBossManager");
413
414       // Validate and update our current component state
415
if (started_)
416          throw new LifecycleException
417             ("JBossManager alreadyStarted");
418       lifecycle_.fireLifecycleEvent(START_EVENT, null);
419       started_ = true;
420
421       // register ClusterManagerMBean to the MBeanServer
422
try
423       {
424          MBeanServer JavaDoc server = MBeanServerLocator.locateJBoss();
425          server.registerMBean(this, objectName_);
426       }
427       catch (Exception JavaDoc e)
428       {
429          log_.error("Could not register ClusterManagerMBean to MBeanServer", e);
430       }
431    }
432
433    /**
434     * Gracefully terminate the active use of the public methods of this
435     * component. This method should be the last one called on a given
436     * instance of this component.
437     *
438     * @throws IllegalStateException if this component has not been started_
439     * @throws org.apache.catalina.LifecycleException
440     * if this component detects a fatal error
441     * that needs to be reported
442     */

443    protected void stopManager() throws LifecycleException
444    {
445       log_.info("Stopping JBossManager");
446
447       // Validate and update our current component state
448
if (!started_)
449          throw new LifecycleException
450             ("JBossManager notStarted");
451       lifecycle_.fireLifecycleEvent(STOP_EVENT, null);
452       started_ = false;
453
454       // unregister ClusterManagerMBean from the MBeanServer
455
try
456       {
457          MBeanServer JavaDoc server = MBeanServerLocator.locateJBoss();
458          server.unregisterMBean(objectName_);
459       }
460       catch (Exception JavaDoc e)
461       {
462          log_.error("Could not unregister ClusterManagerMBean from MBeanServer", e);
463       }
464    }
465
466    // Manager-methods -------------------------------------
467
public Container getContainer()
468    {
469       return container_;
470    }
471
472    public void setContainer(Container container)
473    {
474
475       // De-register from the old Container (if any)
476
if ((this.container_ != null) && (this.container_ instanceof Context))
477          ((Context) this.container_).removePropertyChangeListener(this);
478
479       // Default processing provided by our superclass
480
this.container_ = container;
481
482       // Register with the new Container (if any)
483
if ((this.container_ != null) && (this.container_ instanceof Context))
484       {
485          setMaxInactiveInterval
486             (((Context) this.container_).getSessionTimeout() * 60);
487          ((Context) this.container_).addPropertyChangeListener(this);
488       }
489    }
490
491    public boolean getDistributable()
492    {
493       return distributable_;
494    }
495
496    public void setDistributable(boolean distributable)
497    {
498       this.distributable_ = distributable;
499    }
500
501    public String JavaDoc getInfo()
502    {
503       return info_;
504    }
505
506    public int getMaxInactiveInterval()
507    {
508       return maxInactiveInterval_;
509    }
510
511    public void setMaxInactiveInterval(int interval)
512    {
513       this.maxInactiveInterval_ = interval;
514    }
515
516    public int getSessionIdLength()
517    {
518       return sessionIdLength_;
519    }
520
521    public void setSessionIdLength(int idLength)
522    {
523       this.sessionIdLength_ = idLength;
524    }
525
526    public int getSessionCounter()
527    {
528       return createdCounter_;
529    }
530
531    public void setSessionCounter(int sessionCounter)
532    {
533       this.createdCounter_ = sessionCounter;
534    }
535
536    public int getMaxActive()
537    {
538       return maxActive_;
539    }
540
541    public void setMaxActive(int maxActive)
542    {
543       this.maxActive_ = maxActive;
544    }
545
546    public int getExpiredSessions()
547    {
548       return expiredCounter_;
549    }
550
551    public void setExpiredSessions(int expiredSessions)
552    {
553       this.expiredCounter_ = expiredSessions;
554    }
555
556    public int getRejectedSessions()
557    {
558       return rejectedCounter_;
559    }
560
561    public void setRejectedSessions(int rejectedSessions)
562    {
563       this.rejectedCounter_ = rejectedSessions;
564    }
565
566    public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener)
567    {
568       support_.addPropertyChangeListener(listener);
569    }
570
571    /**
572     * Remove the active session locally from the manager without replicating to the cluster. This can be
573     * useful when the session is exipred, for example, where there is not need to propagate the expiration.
574     *
575     * @param session
576     */

577    public abstract void removeLocal(Session session);
578
579    /**
580     * Store the modified session.
581     *
582     * @param session
583     */

584    public abstract boolean storeSession(Session session);
585
586    public int getActiveSessions()
587    {
588       return activeCounter_;
589    }
590
591 /*
592    public void add(Session session)
593    {
594       //To change body of implemented methods use File | Settings | File Templates.
595    }
596
597    public Session createEmptySession()
598    {
599       return null; //To change body of implemented methods use File | Settings | File Templates.
600    }
601
602    public Session createSession()
603    {
604       return null; //To change body of implemented methods use File | Settings | File Templates.
605    }
606
607    public Session findSession(String id) throws IOException
608    {
609       return null; //To change body of implemented methods use File | Settings | File Templates.
610    }
611
612    public Session[] findSessions()
613    {
614       return new Session[0]; //To change body of implemented methods use File | Settings | File Templates.
615    }
616
617    public void remove(Session session)
618    {
619       //To change body of implemented methods use File | Settings | File Templates.
620    }
621 */

622
623    public void load() throws ClassNotFoundException JavaDoc, IOException JavaDoc
624    {
625       // TODO. Implement persistence layer.
626
throw new RuntimeException JavaDoc("JBossManager.load(): Method not implemented.");
627    }
628
629    public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener)
630    {
631       support_.removePropertyChangeListener(listener);
632    }
633
634    public void unload() throws IOException JavaDoc
635    {
636       // TODO. Implement persistence layer.
637
throw new RuntimeException JavaDoc("JBossManager.load(): Method not implemented.");
638    }
639
640
641    public void backgroundProcess()
642    {
643       // Called from Catalina StandardEngine for every 60 seconds.
644
processExpires();
645    }
646
647    /**
648     * Go through all sessions and look if they have expired
649     */

650    protected void processExpires()
651    {
652       // What's the time?
653
// long timeNow = System.currentTimeMillis();
654

655       // Get all sessions
656
Session sessions[] = findSessions();
657       if (log_.isDebugEnabled())
658       {
659          log_.debug("Looking for sessions that have expired ...");
660       }
661
662       for (int i = 0; i < sessions.length; ++i)
663       {
664          ClusteredSession session = (ClusteredSession) sessions[i];
665
666          // We only look at valid sessions. This will remove session if not valid already.
667
if (!session.isValid())
668          {
669             continue;
670          }
671
672          /* I don't think it is right to check idle time based on lastAccessedTime since it may
673          // remove some request that is currently in progress!!!
674          // How long are they allowed to be idle?
675          int maxInactiveInterval = session.getMaxInactiveInterval();
676
677          // Negative values = never expire
678          if( maxInactiveInterval < 0 )
679          {
680             continue;
681          }
682
683          // How long has this session been idle?
684          int timeIdle =
685             (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
686
687          // Too long?
688          if( timeIdle >= maxInactiveInterval )
689          {
690             try
691             {
692                log_.debug("Session with id = " + session.getId() + " has expired on local node");
693                remove(session);
694             }
695             catch(Throwable t)
696             {
697                log_.error("Problems while expiring session with id = " + session.getId(), t);
698             }
699          }
700          */

701       }
702    }
703
704    public void propertyChange(PropertyChangeEvent JavaDoc evt)
705    {
706       // TODO Need to handle it here.
707
}
708
709    /**
710     * Find in-memory sessions, if any.
711     * @return local session found. Sessions of size 0, if not found.
712     */

713    abstract public ClusteredSession[] findLocalSessions();
714
715    /**
716     * Find in-memory sessions, if any.
717     * @param realId the Session id without JvmRoute tag.
718     * @return local session found. Null if not found.
719     */

720    abstract public ClusteredSession findLocalSession(String JavaDoc realId);
721
722 }
723
Popular Tags