001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.jetty6.cluster;
017:
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import javax.servlet.http.HttpServletRequest;
022: import javax.servlet.http.HttpSession;
023:
024: import org.apache.geronimo.clustering.SessionAlreadyExistException;
025: import org.apache.geronimo.clustering.SessionListener;
026: import org.apache.geronimo.clustering.SessionManager;
027: import org.mortbay.jetty.servlet.AbstractSessionManager;
028: import org.mortbay.jetty.servlet.HashSessionIdManager;
029:
030: /**
031: * @version $Rev$ $Date$
032: */
033: public class ClusteredSessionManager extends AbstractSessionManager {
034:
035: private final SessionManager sessionManager;
036: private final Map<String, ClusteredSession> idToSession = new HashMap<String, ClusteredSession>();
037:
038: public ClusteredSessionManager(SessionManager sessionManager) {
039: this .sessionManager = sessionManager;
040:
041: String workerName = sessionManager.getNode().getName();
042: workerName = workerName.replaceAll(" ", "");
043: HashSessionIdManager sessionIdManager = new HashSessionIdManager();
044: sessionIdManager.setWorkerName(workerName);
045: setIdManager(sessionIdManager);
046:
047: sessionManager.registerListener(new MigrationListener());
048: }
049:
050: @Override
051: protected Session newSession(HttpServletRequest request) {
052: return new ClusteredSession(request);
053: }
054:
055: @Override
056: public void complete(HttpSession session) {
057: ClusteredSession clusteredSession = (ClusteredSession) session;
058: clusteredSession.session.onEndAccess();
059: }
060:
061: @Override
062: protected void addSession(Session session) {
063: ClusteredSession clusteredSession = (ClusteredSession) session;
064: synchronized (idToSession) {
065: idToSession.put(clusteredSession.getClusterId(),
066: clusteredSession);
067: }
068: }
069:
070: @Override
071: protected void removeSession(String idInCluster) {
072: synchronized (idToSession) {
073: idToSession.remove(idInCluster);
074: }
075: }
076:
077: @Override
078: public Session getSession(String idInCluster) {
079: synchronized (idToSession) {
080: return idToSession.get(idInCluster);
081: }
082: }
083:
084: @Override
085: public int getSessions() {
086: synchronized (idToSession) {
087: return idToSession.size();
088: }
089: }
090:
091: @Override
092: public Map getSessionMap() {
093: throw new AssertionError("getSessionMap is never used.");
094: }
095:
096: @Override
097: protected void invalidateSessions() {
098: // We do not need to clear idToSession: when the SessionManager GBean is stopped, all the sessions
099: // it defines are migrated to other SessionManagers. These outbound session migrations will remove
100: // them from idToSession.
101: }
102:
103: private class MigrationListener implements SessionListener {
104:
105: public void notifyInboundSessionMigration(
106: org.apache.geronimo.clustering.Session session) {
107: addSession(new ClusteredSession(session), false);
108: }
109:
110: public void notifyOutboundSessionMigration(
111: org.apache.geronimo.clustering.Session session) {
112: ClusteredSession clusteredSession = getClusteredSession(session);
113: removeSession(clusteredSession, false);
114: }
115:
116: public void notifySessionDestruction(
117: org.apache.geronimo.clustering.Session session) {
118: ClusteredSession clusteredSession = getClusteredSession(session);
119: removeSession(clusteredSession, true);
120: }
121:
122: private ClusteredSession getClusteredSession(
123: org.apache.geronimo.clustering.Session session)
124: throws AssertionError {
125: ClusteredSession clusteredSession;
126: synchronized (idToSession) {
127: clusteredSession = idToSession.remove(session
128: .getSessionId());
129: }
130: if (null == clusteredSession) {
131: throw new AssertionError("Session [" + session
132: + "] is undefined");
133: }
134: return clusteredSession;
135: }
136:
137: }
138:
139: public class ClusteredSession extends Session {
140: private final org.apache.geronimo.clustering.Session session;
141:
142: protected ClusteredSession(HttpServletRequest request) {
143: super (request);
144: try {
145: this .session = sessionManager
146: .createSession(getClusterId());
147: } catch (SessionAlreadyExistException e) {
148: throw (IllegalStateException) new IllegalStateException()
149: .initCause(e);
150: }
151: initValues();
152: }
153:
154: protected ClusteredSession(
155: org.apache.geronimo.clustering.Session session) {
156: super (System.currentTimeMillis(), session.getSessionId());
157: this .session = session;
158: initValues();
159: }
160:
161: @Override
162: protected Map newAttributeMap() {
163: return session.getState();
164: }
165:
166: @Override
167: protected String getClusterId() {
168: return super .getClusterId();
169: }
170:
171: @Override
172: public void invalidate() throws IllegalStateException {
173: super.invalidate();
174: session.release();
175: }
176: }
177:
178: }
|