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 */
017 package org.apache.geronimo.clustering.wadi;
018
019 import java.util.HashMap;
020 import java.util.HashSet;
021 import java.util.Iterator;
022 import java.util.Map;
023 import java.util.Set;
024 import java.util.concurrent.CopyOnWriteArrayList;
025
026 import org.apache.commons.logging.Log;
027 import org.apache.commons.logging.LogFactory;
028 import org.apache.geronimo.clustering.Node;
029 import org.apache.geronimo.clustering.Session;
030 import org.apache.geronimo.clustering.SessionAlreadyExistException;
031 import org.apache.geronimo.clustering.SessionListener;
032 import org.apache.geronimo.clustering.SessionManager;
033 import org.apache.geronimo.gbean.GBeanInfo;
034 import org.apache.geronimo.gbean.GBeanInfoBuilder;
035 import org.apache.geronimo.gbean.GBeanLifecycle;
036 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
037 import org.codehaus.wadi.aop.replication.AOPStackContext;
038 import org.codehaus.wadi.core.assembler.StackContext;
039 import org.codehaus.wadi.core.manager.Manager;
040 import org.codehaus.wadi.core.manager.SessionMonitor;
041 import org.codehaus.wadi.group.Dispatcher;
042 import org.codehaus.wadi.group.Peer;
043 import org.codehaus.wadi.replication.strategy.BackingStrategyFactory;
044 import org.codehaus.wadi.servicespace.ServiceSpace;
045 import org.codehaus.wadi.servicespace.ServiceSpaceName;
046
047 /**
048 *
049 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
050 */
051 public class BasicWADISessionManager implements GBeanLifecycle, SessionManager, WADISessionManager {
052 private static final Log log = LogFactory.getLog(BasicWADISessionManager.class);
053
054 private final ClassLoader cl;
055 private final WADICluster cluster;
056 private final WADISessionManagerConfigInfo configInfo;
057 private final BackingStrategyFactory backingStrategyFactory;
058 private final CopyOnWriteArrayList<SessionListener> listeners;
059
060 private Manager manager;
061 private SessionMonitor sessionMonitor;
062 private ServiceSpace serviceSpace;
063
064
065 public BasicWADISessionManager(ClassLoader cl,
066 WADISessionManagerConfigInfo configInfo,
067 WADICluster cluster,
068 BackingStrategyFactory backingStrategyFactory) {
069 this.cl = cl;
070 this.configInfo = configInfo;
071 this.cluster = cluster;
072 this.backingStrategyFactory = backingStrategyFactory;
073
074 listeners = new CopyOnWriteArrayList<SessionListener>();
075 }
076
077 public void doStart() throws Exception {
078 Dispatcher underlyingDisp = cluster.getCluster().getDispatcher();
079
080 ServiceSpaceName serviceSpaceName = new ServiceSpaceName(configInfo.getServiceSpaceURI());
081 StackContext stackContext;
082 if (configInfo.isDeltaReplication()) {
083 stackContext = new AOPStackContext(cl,
084 serviceSpaceName,
085 underlyingDisp,
086 configInfo.getSessionTimeoutSeconds(),
087 configInfo.getNumPartitions(),
088 configInfo.getSweepInterval(),
089 backingStrategyFactory);
090 } else {
091 stackContext = new StackContext(cl,
092 serviceSpaceName,
093 underlyingDisp,
094 configInfo.getSessionTimeoutSeconds(),
095 configInfo.getNumPartitions(),
096 configInfo.getSweepInterval(),
097 backingStrategyFactory);
098 }
099 stackContext.setDisableReplication(configInfo.isDisableReplication());
100 stackContext.build();
101
102 serviceSpace = stackContext.getServiceSpace();
103 manager = stackContext.getManager();
104
105 sessionMonitor = stackContext.getSessionMonitor();
106 sessionMonitor.addSessionListener(new SessionListenerAdapter());
107
108 serviceSpace.start();
109 }
110
111 public void doStop() throws Exception {
112 serviceSpace.stop();
113 }
114
115 public void doFail() {
116 try {
117 serviceSpace.stop();
118 } catch (Exception e) {
119 log.error(e);
120 }
121 }
122
123 public Session createSession(String sessionId) throws SessionAlreadyExistException {
124 org.codehaus.wadi.core.session.Session session;
125 try {
126 session = manager.createWithName(sessionId);
127 } catch (org.codehaus.wadi.core.manager.SessionAlreadyExistException e) {
128 throw new SessionAlreadyExistException("Session " + sessionId + " already exists", e);
129 }
130 return new WADISessionAdaptor(session);
131 }
132
133 public Manager getManager() {
134 return manager;
135 }
136
137 public Node getNode() {
138 return cluster.getLocalNode();
139 }
140
141 public Set<Node> getRemoteNodes() {
142 Map<Peer, RemoteNode> peerToRemoteNode = new HashMap<Peer, RemoteNode>();
143 Set<Node> clusterNodes = cluster.getRemoteNodes();
144 for (Iterator<Node> iterator = clusterNodes.iterator(); iterator.hasNext();) {
145 RemoteNode remoteNode = (RemoteNode) iterator.next();
146 peerToRemoteNode.put(remoteNode.getPeer(), remoteNode);
147 }
148
149 Set<Node> nodes = new HashSet<Node>();
150 Set<Peer> peers = serviceSpace.getHostingPeers();
151 for (Peer peer : peers) {
152 RemoteNode remoteNode = peerToRemoteNode.get(peer);
153 if (null == remoteNode) {
154 throw new AssertionError("remoteNode is null");
155 }
156 nodes.add(remoteNode);
157 }
158 return nodes;
159 }
160
161 public void registerListener(SessionListener listener) {
162 listeners.add(listener);
163 }
164
165 public void unregisterListener(SessionListener listener) {
166 listeners.remove(listener);
167 }
168
169 private void notifyInboundSessionMigration(org.codehaus.wadi.core.session.Session session) {
170 for (SessionListener listener : listeners) {
171 listener.notifyInboundSessionMigration(new WADISessionAdaptor(session));
172 }
173 }
174
175 private void notifyOutboundSessionMigration(org.codehaus.wadi.core.session.Session session) {
176 for (SessionListener listener : listeners) {
177 listener.notifyOutboundSessionMigration(new WADISessionAdaptor(session));
178 }
179 }
180
181 private void notifySessionDestruction(org.codehaus.wadi.core.session.Session session) {
182 for (SessionListener listener : listeners) {
183 listener.notifySessionDestruction(new WADISessionAdaptor(session));
184 }
185 }
186
187 private class SessionListenerAdapter implements org.codehaus.wadi.core.manager.SessionListener {
188
189 public void onSessionCreation(org.codehaus.wadi.core.session.Session session) {
190 }
191
192 public void onSessionDestruction(org.codehaus.wadi.core.session.Session session) {
193 notifySessionDestruction(session);
194 }
195
196 public void onInboundSessionMigration(org.codehaus.wadi.core.session.Session session) {
197 notifyInboundSessionMigration(session);
198 }
199
200 public void onOutbountSessionMigration(org.codehaus.wadi.core.session.Session session) {
201 notifyOutboundSessionMigration(session);
202 }
203
204 }
205
206 public static final GBeanInfo GBEAN_INFO;
207
208 public static final String GBEAN_ATTR_WADI_CONFIG_INFO = "wadiConfigInfo";
209
210 public static final String GBEAN_REF_CLUSTER = "Cluster";
211 public static final String GBEAN_REF_BACKING_STRATEGY_FACTORY = "BackingStrategyFactory";
212
213 static {
214 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic("WADI Session Manager",
215 BasicWADISessionManager.class, NameFactory.GERONIMO_SERVICE);
216
217 infoBuilder.addAttribute("classLoader", ClassLoader.class, false);
218 infoBuilder.addAttribute(GBEAN_ATTR_WADI_CONFIG_INFO, WADISessionManagerConfigInfo.class, true);
219
220 infoBuilder.addReference(GBEAN_REF_CLUSTER, WADICluster.class, NameFactory.GERONIMO_SERVICE);
221 infoBuilder.addReference(GBEAN_REF_BACKING_STRATEGY_FACTORY, BackingStrategyFactory.class,
222 NameFactory.GERONIMO_SERVICE);
223
224 infoBuilder.addInterface(SessionManager.class);
225 infoBuilder.addInterface(WADISessionManager.class);
226
227 infoBuilder.setConstructor(new String[] { "classLoader",
228 GBEAN_ATTR_WADI_CONFIG_INFO,
229 GBEAN_REF_CLUSTER,
230 GBEAN_REF_BACKING_STRATEGY_FACTORY });
231
232 GBEAN_INFO = infoBuilder.getBeanInfo();
233 }
234
235 public static GBeanInfo getGBeanInfo() {
236 return GBEAN_INFO;
237 }
238
239 }