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
56
57
58 setCrossContextSessionIDs(true);
59
60 sessionManager.registerListener(new MigrationListener());
61
62
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
107
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 }