KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > tomcat > tc5 > JvmRouteFilter


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;
8
9 import java.io.IOException JavaDoc;
10 import java.util.Enumeration JavaDoc;
11
12 import javax.servlet.Filter JavaDoc;
13 import javax.servlet.FilterChain JavaDoc;
14 import javax.servlet.FilterConfig JavaDoc;
15 import javax.servlet.ServletContext JavaDoc;
16 import javax.servlet.ServletException JavaDoc;
17 import javax.servlet.ServletRequest JavaDoc;
18 import javax.servlet.ServletResponse JavaDoc;
19 import javax.servlet.http.HttpServletRequest JavaDoc;
20 import javax.servlet.http.HttpServletResponse JavaDoc;
21 import javax.servlet.http.HttpSession JavaDoc;
22
23 import org.apache.catalina.Session;
24 import org.jboss.logging.Logger;
25 import org.jboss.util.NestedRuntimeException;
26 import org.jboss.web.tomcat.tc5.session.AbstractJBossManager;
27
28 /**
29  * Web request filter to specifically handle Tomcat jvmRoute using mod_jk(2)
30  * module. We assume that the session is set by cookie only for now, i.e., no
31  * support of that from URL. Furthermore, the session id has a format of
32  * id.jvmRoute where jvmRoute is used by JK module to determine sticky session
33  * during load balancing.
34  *
35  * @author Ben Wang
36  * @author Marco Antonioni
37  * @version $Revision: 1.3.2.3 $
38  */

39 public class JvmRouteFilter
40    implements Filter JavaDoc
41 {
42    protected AbstractJBossManager manager_;
43    protected static Logger log_ = Logger.getLogger(JvmRouteFilter.class);
44
45    public void init(FilterConfig JavaDoc filterConfig) throws ServletException JavaDoc
46    {
47       if (log_.isDebugEnabled())
48       {
49          ServletContext JavaDoc sc = filterConfig.getServletContext();
50          Enumeration JavaDoc names = sc.getAttributeNames();
51          while (names.hasMoreElements())
52          {
53             String JavaDoc name = (String JavaDoc) names.nextElement();
54             Object JavaDoc value = sc.getAttribute(name);
55             log_.debug("name=" + name + ", value.className: [" + value.getClass().getName() + "] value.toString: [" + value.toString() + "]");
56          }
57       }
58       manager_ = (AbstractJBossManager) filterConfig.getServletContext().getAttribute("AbstractJBossManager");
59       if (manager_ == null)
60       {
61          throw new RuntimeException JavaDoc("JvmRouteFilter.init(): No AbstractJBossManager found for clustering support.");
62       }
63
64       if (log_.isDebugEnabled())
65          log_.debug("JvmRouteFilter.init(): initializing JvmRouteFilter");
66    }
67
68    public void doFilter(ServletRequest JavaDoc request, ServletResponse JavaDoc response, FilterChain JavaDoc chain)
69       throws IOException JavaDoc, ServletException JavaDoc
70    {
71       // Check if request and response is valid
72
if (!(request instanceof HttpServletRequest JavaDoc && response instanceof HttpServletResponse JavaDoc))
73       {
74          // Don't know how to handle. There is a mistake.
75
throw new RuntimeException JavaDoc("JvmRouteFilter.doFilter(): Not a http request and response type.");
76       }
77
78       // get session id
79
HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) request;
80       HttpServletResponse JavaDoc res = (HttpServletResponse JavaDoc) response;
81       HttpSession JavaDoc session = req.getSession(false);
82       if (session != null)
83       {
84          String JavaDoc sessionId = session.getId();
85    
86          // Obtain JvmRoute
87
String JavaDoc jvmRoute = manager_.getJvmRoute();
88          if (log_.isDebugEnabled())
89          {
90             log_.debug("doFilter(): check if need to re-route based on JvmRoute. Session id: " +
91                sessionId + " jvmRoute: " + jvmRoute);
92          }
93
94          if (jvmRoute == null)
95          {
96             throw new RuntimeException JavaDoc("JvmRouteFilter.doFilter(): Tomcat JvmRoute is null. " +
97                "Need to assign a value in Tomcat server.xml for load balancing.");
98          }
99    
100          // Check if incoming session id has JvmRoute appended. If not, append it.
101
// TODO. We handle only get session id by cookie only
102
if (req.isRequestedSessionIdFromURL())
103          {
104             // Warning but do nothing
105
log_.error("JvmRouteFilter.doFilter(): Can't handle clustering where session id is from URL. Will skip.");
106          }
107          else
108          {
109             handleJvmRoute(sessionId, jvmRoute, res);
110          }
111       }
112       chain.doFilter(request, response);
113    }
114
115    protected void handleJvmRoute(String JavaDoc sessionId, String JavaDoc jvmRoute, HttpServletResponse JavaDoc response)
116    {
117       // get requested jvmRoute.
118
// TODO. The current format is assumed to be id.jvmRoute. Can be generalized later.
119
String JavaDoc requestedJvmRoute = null;
120       int ind = sessionId.indexOf(".");
121       if (ind > 0)
122       {
123          requestedJvmRoute = sessionId.substring(sessionId.indexOf(".") + 1, sessionId.length());
124       }
125
126       String JavaDoc sid = sessionId;
127       if (requestedJvmRoute == null)
128       {
129          // If this filter is turned on, we assume we have an appendix of jvmRoute. So this request is new.
130
sid = sessionId + "." + jvmRoute;
131          manager_.setNewSessionCookie(sid, response);
132       }
133       else if (requestedJvmRoute.equals(jvmRoute))
134       {
135          return; // Nothing more needs to be done.
136
}
137       else
138       {
139          // We just have a failover since jvmRoute does not match. We will replace the old one with the new one.
140
if (log_.isDebugEnabled())
141          {
142             log_.debug("handleJvmRoute(): We have detected a failover with differen jvmRoute." +
143                " old one: " + requestedJvmRoute + " new one: " + jvmRoute + ". Will reset the session id.");
144          }
145          int index = sessionId.indexOf(".");
146          if (index > 0)
147          {
148             String JavaDoc base = sessionId.substring(0, sessionId.indexOf("."));
149             sid = base + "." + jvmRoute;
150          }
151          else
152          {
153             throw new RuntimeException JavaDoc("JvmRouteFilter.handleJvmRoute(): session id doesn't JvmRoute.");
154          }
155
156          manager_.setNewSessionCookie(sid, response);
157          // Change the sessionId with the new one using local jvmRoute
158
Session JavaDoc catalinaSession = null;
159          try
160          {
161             catalinaSession = manager_.findSession(sessionId);
162             // change session id with the new one using local jvmRoute and update cluster if needed.
163
if( catalinaSession != null )
164             {
165                catalinaSession.setId(sid);
166                if (log_.isDebugEnabled())
167                {
168                   log_.debug("handleJvmRoute(): changed catalina session to= [" + sid + "] old one= [" + sessionId + "]");
169                }
170             }
171          }
172          catch (IOException JavaDoc e)
173          {
174             if (log_.isDebugEnabled())
175             {
176                log_.debug("handleJvmRoute(): manager_.findSession() unable to find session= [" + sessionId + "]", e);
177             }
178             throw new NestedRuntimeException("JvmRouteFilter.handleJvmRoute(): cannot find session [" + sessionId + "]", e);
179          }
180       }
181    }
182
183
184    public void destroy()
185    {
186       manager_ = null;
187    }
188 }
189
Popular Tags