KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > tomcat > tc6 > session > JvmRouteValve


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.web.tomcat.tc6.session;
23
24 import java.io.IOException JavaDoc;
25 import javax.servlet.http.HttpSession JavaDoc;
26 import javax.servlet.http.HttpServletResponse JavaDoc;
27 import javax.servlet.ServletException JavaDoc;
28
29 import org.apache.catalina.*;
30 import org.apache.catalina.connector.Request;
31 import org.apache.catalina.connector.Response;
32 import org.apache.catalina.util.LifecycleSupport;
33 import org.apache.catalina.valves.ValveBase;
34 import org.jboss.logging.Logger;
35
36 /**
37  * Web request valve to specifically handle Tomcat jvmRoute using mod_jk(2)
38  * module. We assume that the session is set by cookie only for now, i.e., no
39  * support of that from URL. Furthermore, the session id has a format of
40  * id.jvmRoute where jvmRoute is used by JK module to determine sticky session
41  * during load balancing.
42  *
43  * @author Ben Wang
44  * @version $Revision: 45726 $
45  */

46 public class JvmRouteValve extends ValveBase implements Lifecycle
47 {
48    // The info string for this Valve
49
private static final String JavaDoc info = "JvmRouteValve/1.0";
50
51    protected static Logger log_ = Logger.getLogger(JvmRouteValve.class);
52
53    // Valve-lifecycle_ helper object
54
protected LifecycleSupport support = new LifecycleSupport(this);
55
56    protected AbstractJBossManager manager_;
57
58    /**
59     * Create a new Valve.
60     *
61     */

62    public JvmRouteValve(AbstractJBossManager manager)
63    {
64       super();
65       manager_ = manager;
66    }
67
68    /**
69     * Get information about this Valve.
70     */

71    public String JavaDoc getInfo()
72    {
73       return info;
74    }
75
76    public void invoke(Request request, Response JavaDoc response) throws IOException JavaDoc, ServletException JavaDoc
77    {
78
79       // Need to check it before let it through. This is ok because this
80
// valve is inserted only when mod_jk option is configured.
81
checkJvmRoute(request, response);
82
83       // let the servlet invokation go through
84
getNext().invoke(request, response);
85    }
86
87    public void checkJvmRoute(Request req, Response JavaDoc res)
88       throws IOException JavaDoc, ServletException JavaDoc
89    {
90       HttpSession JavaDoc session = req.getSession(false);
91       if (session != null)
92       {
93          String JavaDoc sessionId = session.getId();
94
95          // Obtain JvmRoute
96
String JavaDoc jvmRoute = manager_.getJvmRoute();
97          if (log_.isDebugEnabled())
98          {
99             log_.debug("checkJvmRoute(): check if need to re-route based on JvmRoute. Session id: " +
100                sessionId + " jvmRoute: " + jvmRoute);
101          }
102
103          if (jvmRoute == null)
104          {
105             throw new RuntimeException JavaDoc("JvmRouteValve.checkJvmRoute(): Tomcat JvmRoute is null. " +
106                "Need to assign a value in Tomcat server.xml for load balancing.");
107          }
108
109          // Check if incoming session id has JvmRoute appended. If not, append it.
110
boolean setCookie = !req.isRequestedSessionIdFromURL();
111          handleJvmRoute(sessionId, jvmRoute, res, setCookie);
112       }
113    }
114
115    protected void handleJvmRoute(String JavaDoc sessionId,
116                                  String JavaDoc jvmRoute,
117                                  HttpServletResponse JavaDoc response,
118                                  boolean setCookie)
119    {
120       // Get requested jvmRoute.
121
// TODO. The current format is assumed to be id.jvmRoute. Can be generalized later.
122
String JavaDoc requestedJvmRoute = null;
123       int index = sessionId.lastIndexOf(".");
124       if (index > 0)
125       {
126          requestedJvmRoute = sessionId.substring(index + 1, sessionId.length());
127       }
128
129       String JavaDoc newId = sessionId;
130       if (!jvmRoute.equals(requestedJvmRoute))
131       {
132          if (requestedJvmRoute == null)
133          {
134             // If this valve is turned on, we assume we have an appendix of jvmRoute.
135
// So this request is new.
136
newId = sessionId + "." + jvmRoute;
137          }
138          else
139          {
140             // We just had a failover since jvmRoute does not match.
141
// We will replace the old one with the new one.
142
if (log_.isDebugEnabled())
143             {
144                log_.debug("handleJvmRoute(): We have detected a failover with different jvmRoute." +
145                   " old one: " + requestedJvmRoute + " new one: " + jvmRoute + ". Will reset the session id.");
146             }
147             
148             String JavaDoc base = sessionId.substring(0, index);
149             newId = base + "." + jvmRoute;
150          }
151          
152          resetSessionId(sessionId, newId);
153          
154          if (setCookie)
155             manager_.setNewSessionCookie(newId, response);
156       }
157    }
158    
159    private void resetSessionId(String JavaDoc oldId, String JavaDoc newId)
160    {
161       try
162       {
163          ClusteredSession session = (ClusteredSession)manager_.findSession(oldId);
164          // change session id with the new one using local jvmRoute.
165
if( session != null )
166          {
167             // Note this will trigger a session remove from the super Tomcat class.
168
session.resetIdWithRouteInfo(newId);
169             if (log_.isDebugEnabled())
170             {
171                log_.debug("resetSessionId(): changed catalina session to= [" + newId + "] old one= [" + oldId + "]");
172             }
173          }
174          else if (log_.isDebugEnabled())
175          {
176             log_.debug("resetSessionId(): no session with id " + newId + " found");
177          }
178       }
179       catch (IOException JavaDoc e)
180       {
181          if (log_.isDebugEnabled())
182          {
183             log_.debug("resetSessionId(): manager_.findSession() unable to find session= [" + oldId + "]", e);
184          }
185          throw new RuntimeException JavaDoc("JvmRouteValve.resetSessionId(): cannot find session [" + oldId + "]", e);
186       }
187    }
188
189    // Lifecycle Interface
190
public void addLifecycleListener(LifecycleListener listener)
191    {
192       support.addLifecycleListener(listener);
193    }
194
195    public void removeLifecycleListener(LifecycleListener listener)
196    {
197       support.removeLifecycleListener(listener);
198    }
199
200    public LifecycleListener[] findLifecycleListeners()
201    {
202       return support.findLifecycleListeners();
203    }
204
205    public void start() throws LifecycleException
206    {
207       support.fireLifecycleEvent(START_EVENT, this);
208    }
209
210    public void stop() throws LifecycleException
211    {
212       support.fireLifecycleEvent(STOP_EVENT, this);
213    }
214
215 }
216
Popular Tags