View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  package org.apache.geronimo.jetty.cluster;
19  
20  import java.io.BufferedReader;
21  import java.io.IOException;
22  import java.io.UnsupportedEncodingException;
23  import java.security.Principal;
24  import java.util.Enumeration;
25  import java.util.Locale;
26  import java.util.Map;
27  
28  import javax.servlet.RequestDispatcher;
29  import javax.servlet.ServletInputStream;
30  import javax.servlet.http.Cookie;
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpSession;
33  
34  import org.apache.geronimo.clustering.SessionAlreadyExistException;
35  import org.apache.geronimo.clustering.SessionListener;
36  import org.apache.geronimo.clustering.SessionManager;
37  import org.mortbay.jetty.servlet.AbstractSessionManager;
38  
39  
40  /**
41   *
42   * @version $Rev$ $Date$
43   */
44  public class ClusteredSessionManager extends AbstractSessionManager {
45      private static final Object ALL_SESSION_PLACEHOLDER = new Object();
46      
47      private final SessionManager sessionManager;
48      
49      public ClusteredSessionManager(SessionManager sessionManager) {
50          this.sessionManager = sessionManager;
51  
52          String workerName = sessionManager.getNode().getName();
53          workerName = workerName.replaceAll(" ", "");
54          setWorkerName(workerName);
55          // implementation note: enables cross context session id such that a mock HttpServletRequest having a defined 
56          // requestedSessionId attribute can be used to re-create an HttpSession with a defined session ID in this
57          // manager.
58          setCrossContextSessionIDs(true);
59          
60          sessionManager.registerListener(new MigrationListener());
61  
62          // sessions are not removed by this manager. They are invalidated via a callback mechanism
63          setMaxInactiveInterval(-1);
64      }
65  
66      protected Session newSession(HttpServletRequest request) {
67          return new ClusteredSession(request);
68      }
69  
70      private class MigrationListener implements SessionListener {
71          
72          public void notifyInboundSessionMigration(org.apache.geronimo.clustering.Session session) {
73              String sessionId = session.getSessionId();
74              synchronized (__allSessions) {
75                  if (__allSessions.containsKey(sessionId)) {
76                      throw new IllegalStateException("ID [" + sessionId + "] is already defined.");
77                  }
78                  __allSessions.add(sessionId, ALL_SESSION_PLACEHOLDER);
79                  newHttpSession(new RequestWithBoundSession(session));
80                  __allSessions.removeValue(sessionId, ALL_SESSION_PLACEHOLDER);
81              }
82          }
83          
84          public void notifyOutboundSessionMigration(org.apache.geronimo.clustering.Session session) {
85              String sessionId = session.getSessionId();
86              synchronized (__allSessions) {
87                  __allSessions.remove(sessionId);
88              }
89  
90              synchronized (_sessions) {
91                  _sessions.remove(sessionId);
92              } 
93          }
94      }
95  
96      protected class ClusteredSession extends Session {
97          private static final String FORCE_SET_VALUES = "$$$JETTY_FORCE_SET_VALUES$$$"; 
98  
99          private final org.apache.geronimo.clustering.Session session;
100 
101         protected ClusteredSession(HttpServletRequest request) {
102             super(request);
103             
104             if (request instanceof RequestWithBoundSession) {
105                 this.session = ((RequestWithBoundSession) request).session;
106                 // implementation note: set a dummy attribute such that the underlying attribute map is initialized
107                 // with the state of the inbound session.
108                 setAttribute(FORCE_SET_VALUES, FORCE_SET_VALUES);
109             } else {
110                 try {
111                     this.session = sessionManager.createSession(getId());
112                 } catch (SessionAlreadyExistException e) {
113                     throw (IllegalStateException) new IllegalStateException().initCause(e);
114                 }
115             }
116         }
117         
118         protected Map newAttributeMap() {
119             return session.getState();
120         }
121     }
122 
123     /**
124      * Implementation note: this is a mock HttpServletRequest which is used to create an HttpSession with the same
125      * session ID than the wrapped Session.
126      */
127     private class RequestWithBoundSession implements HttpServletRequest {
128         private final org.apache.geronimo.clustering.Session session;
129 
130         public RequestWithBoundSession(org.apache.geronimo.clustering.Session session) {
131             this.session = session;
132         }
133 
134         public void setAttribute(String arg0, Object arg1) {
135         }
136 
137         public Object getAttribute(String arg0) {
138             return null;
139         }
140 
141         public String getRequestedSessionId() {
142             return session.getSessionId();
143         }
144 
145         public String getAuthType() {
146             throw new UnsupportedOperationException();
147         }
148 
149         public String getContextPath() {
150             throw new UnsupportedOperationException();
151         }
152 
153         public Cookie[] getCookies() {
154             throw new UnsupportedOperationException();
155         }
156 
157         public long getDateHeader(String arg0) {
158             throw new UnsupportedOperationException();
159         }
160 
161         public String getHeader(String arg0) {
162             throw new UnsupportedOperationException();
163         }
164 
165         public Enumeration getHeaderNames() {
166             throw new UnsupportedOperationException();
167         }
168 
169         public Enumeration getHeaders(String arg0) {
170             throw new UnsupportedOperationException();
171         }
172 
173         public int getIntHeader(String arg0) {
174             throw new UnsupportedOperationException();
175         }
176 
177         public String getMethod() {
178             throw new UnsupportedOperationException();
179         }
180 
181         public String getPathInfo() {
182             throw new UnsupportedOperationException();
183         }
184 
185         public String getPathTranslated() {
186             throw new UnsupportedOperationException();
187         }
188 
189         public String getQueryString() {
190             throw new UnsupportedOperationException();
191         }
192 
193         public String getRemoteUser() {
194             throw new UnsupportedOperationException();
195         }
196 
197         public String getRequestURI() {
198             throw new UnsupportedOperationException();
199         }
200 
201         public StringBuffer getRequestURL() {
202             throw new UnsupportedOperationException();
203         }
204 
205         public String getServletPath() {
206             throw new UnsupportedOperationException();
207         }
208 
209         public HttpSession getSession() {
210             throw new UnsupportedOperationException();
211         }
212 
213         public HttpSession getSession(boolean arg0) {
214             throw new UnsupportedOperationException();
215         }
216 
217         public Principal getUserPrincipal() {
218             throw new UnsupportedOperationException();
219         }
220 
221         public boolean isRequestedSessionIdFromCookie() {
222             throw new UnsupportedOperationException();
223         }
224 
225         public boolean isRequestedSessionIdFromURL() {
226             throw new UnsupportedOperationException();
227         }
228 
229         public boolean isRequestedSessionIdFromUrl() {
230             throw new UnsupportedOperationException();
231         }
232 
233         public boolean isRequestedSessionIdValid() {
234             throw new UnsupportedOperationException();
235         }
236 
237         public boolean isUserInRole(String arg0) {
238             throw new UnsupportedOperationException();
239         }
240 
241         public Enumeration getAttributeNames() {
242             throw new UnsupportedOperationException();
243         }
244 
245         public String getCharacterEncoding() {
246             throw new UnsupportedOperationException();
247         }
248 
249         public int getContentLength() {
250             throw new UnsupportedOperationException();
251         }
252 
253         public String getContentType() {
254             throw new UnsupportedOperationException();
255         }
256 
257         public ServletInputStream getInputStream() throws IOException {
258             throw new UnsupportedOperationException();
259         }
260 
261         public String getLocalAddr() {
262             throw new UnsupportedOperationException();
263         }
264 
265         public String getLocalName() {
266             throw new UnsupportedOperationException();
267         }
268 
269         public int getLocalPort() {
270             throw new UnsupportedOperationException();
271         }
272 
273         public Locale getLocale() {
274             throw new UnsupportedOperationException();
275         }
276 
277         public Enumeration getLocales() {
278             throw new UnsupportedOperationException();
279         }
280 
281         public String getParameter(String arg0) {
282             throw new UnsupportedOperationException();
283         }
284 
285         public Map getParameterMap() {
286             throw new UnsupportedOperationException();
287         }
288 
289         public Enumeration getParameterNames() {
290             throw new UnsupportedOperationException();
291         }
292 
293         public String[] getParameterValues(String arg0) {
294             throw new UnsupportedOperationException();
295         }
296 
297         public String getProtocol() {
298             throw new UnsupportedOperationException();
299         }
300 
301         public BufferedReader getReader() throws IOException {
302             throw new UnsupportedOperationException();
303         }
304 
305         public String getRealPath(String arg0) {
306             throw new UnsupportedOperationException();
307         }
308 
309         public String getRemoteAddr() {
310             throw new UnsupportedOperationException();
311         }
312 
313         public String getRemoteHost() {
314             throw new UnsupportedOperationException();
315         }
316 
317         public int getRemotePort() {
318             throw new UnsupportedOperationException();
319         }
320 
321         public RequestDispatcher getRequestDispatcher(String arg0) {
322             throw new UnsupportedOperationException();
323         }
324 
325         public String getScheme() {
326             throw new UnsupportedOperationException();
327         }
328 
329         public String getServerName() {
330             throw new UnsupportedOperationException();
331         }
332 
333         public int getServerPort() {
334             throw new UnsupportedOperationException();
335         }
336 
337         public boolean isSecure() {
338             throw new UnsupportedOperationException();
339         }
340 
341         public void removeAttribute(String arg0) {
342             throw new UnsupportedOperationException();
343         }
344 
345         public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException {
346             throw new UnsupportedOperationException();
347         }
348     }
349 }