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 }