Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 39143 invoked from network); 15 Sep 2006 15:03:37 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 15 Sep 2006 15:03:37 -0000 Received: (qmail 24362 invoked by uid 500); 15 Sep 2006 15:03:37 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 24334 invoked by uid 500); 15 Sep 2006 15:03:36 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 24323 invoked by uid 99); 15 Sep 2006 15:03:36 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 15 Sep 2006 08:03:36 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 15 Sep 2006 08:03:33 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id E38131A9820; Fri, 15 Sep 2006 08:02:17 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r446624 [2/4] - in /geronimo/server/trunk: ./ assemblies/geronimo-jetty-j2ee/ configs/jetty-clustering-builder-wadi/ configs/jetty-clustering-builder-wadi/src/ configs/jetty-clustering-builder-wadi/src/plan/ configs/jetty-clustering-wadi/ c... Date: Fri, 15 Sep 2006 15:02:16 -0000 To: scm@geronimo.apache.org From: gdamour@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20060915150217.E38131A9820@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicReplicationManagerFactoryGBean.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicReplicationManagerFactoryGBean.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicReplicationManagerFactoryGBean.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicReplicationManagerFactoryGBean.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,50 @@ +package org.apache.geronimo.clustering.wadi; + +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; +import org.codehaus.wadi.group.Dispatcher; +import org.codehaus.wadi.replication.manager.ReplicationManager; +import org.codehaus.wadi.replication.manager.ReplicationManagerFactory; +import org.codehaus.wadi.replication.manager.basic.BasicReplicationManagerFactory; +import org.codehaus.wadi.replication.storage.ReplicaStorageFactory; +import org.codehaus.wadi.replication.strategy.BackingStrategyFactory; + +public class BasicReplicationManagerFactoryGBean implements ReplicationManagerFactory, GBeanLifecycle { + private ReplicationManagerFactory factory; + + public ReplicationManager factory(Dispatcher dispatcher, ReplicaStorageFactory replicaStoragefactory, + BackingStrategyFactory backingStrategyFactory) { + return factory.factory(dispatcher, replicaStoragefactory, backingStrategyFactory); + } + + public void doFail() { + factory = null; + } + + public void doStart() throws Exception { + factory = new BasicReplicationManagerFactory(); + } + + public void doStop() throws Exception { + factory = null; + } + + public static final GBeanInfo GBEAN_INFO; + + static { + GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(BasicReplicationManagerFactoryGBean.class, + NameFactory.GERONIMO_SERVICE); + + infoBuilder.addInterface(ReplicationManagerFactory.class); + + infoBuilder.setConstructor(new String[0]); + + GBEAN_INFO = infoBuilder.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicWADISessionManager.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicWADISessionManager.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicWADISessionManager.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/BasicWADISessionManager.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,387 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering.wadi; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.clustering.Node; +import org.apache.geronimo.clustering.Session; +import org.apache.geronimo.clustering.SessionAlreadyExistException; +import org.apache.geronimo.clustering.SessionListener; +import org.apache.geronimo.clustering.SessionManager; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; +import org.codehaus.wadi.Collapser; +import org.codehaus.wadi.Contextualiser; +import org.codehaus.wadi.Emoter; +import org.codehaus.wadi.Evicter; +import org.codehaus.wadi.Immoter; +import org.codehaus.wadi.Invocation; +import org.codehaus.wadi.InvocationException; +import org.codehaus.wadi.Manager; +import org.codehaus.wadi.ManagerConfig; +import org.codehaus.wadi.Motable; +import org.codehaus.wadi.PoolableInvocationWrapperPool; +import org.codehaus.wadi.SessionPool; +import org.codehaus.wadi.Streamer; +import org.codehaus.wadi.ValuePool; +import org.codehaus.wadi.group.Dispatcher; +import org.codehaus.wadi.impl.AbsoluteEvicter; +import org.codehaus.wadi.impl.ClusterContextualiser; +import org.codehaus.wadi.impl.ClusteredManager; +import org.codehaus.wadi.impl.DummyContextualiser; +import org.codehaus.wadi.impl.DummyReplicaterFactory; +import org.codehaus.wadi.impl.HashingCollapser; +import org.codehaus.wadi.impl.HybridRelocater; +import org.codehaus.wadi.impl.MemoryContextualiser; +import org.codehaus.wadi.impl.SerialContextualiser; +import org.codehaus.wadi.impl.SerialContextualiserFrontingMemory; +import org.codehaus.wadi.impl.SimpleSessionPool; +import org.codehaus.wadi.impl.SimpleStreamer; +import org.codehaus.wadi.impl.SimpleValuePool; +import org.codehaus.wadi.impl.StatelessContextualiser; +import org.codehaus.wadi.replication.manager.ReplicationManagerFactory; +import org.codehaus.wadi.replication.storage.ReplicaStorageFactory; +import org.codehaus.wadi.replication.strategy.BackingStrategyFactory; +import org.codehaus.wadi.web.AttributesFactory; +import org.codehaus.wadi.web.WebSession; +import org.codehaus.wadi.web.WebSessionPool; +import org.codehaus.wadi.web.WebSessionWrapperFactory; +import org.codehaus.wadi.web.impl.AtomicallyReplicableSessionFactory; +import org.codehaus.wadi.web.impl.DistributableAttributesFactory; +import org.codehaus.wadi.web.impl.DistributableValueFactory; +import org.codehaus.wadi.web.impl.DummyRouter; +import org.codehaus.wadi.web.impl.DummyStatefulHttpServletRequestWrapperPool; +import org.codehaus.wadi.web.impl.StandardSessionWrapperFactory; +import org.codehaus.wadi.web.impl.WebSessionToSessionPoolAdapter; + +import EDU.oswego.cs.dl.util.concurrent.Sync; + +/** + * + * @version $Rev$ $Date$ + */ +public class BasicWADISessionManager implements GBeanLifecycle, SessionManager, WADISessionManager { + private static final Log log = LogFactory.getLog(BasicWADISessionManager.class); + + private final int sweepInterval; + private final int numPartitions; + private final ReplicationManagerFactory replicationManagerFactory; + private final ReplicaStorageFactory replicaStorageFactory; + private final BackingStrategyFactory backingStrategyFactory; + private final DispatcherHolder dispatcherHolder; + private final Set listeners; + + private ClusteredManager manager; + + public BasicWADISessionManager(int sweepInterval, + int numPartitions, + ReplicationManagerFactory replicationManagerFactory, + ReplicaStorageFactory replicaStorageFactory, + BackingStrategyFactory backingStrategyFactory, + DispatcherHolder dispatcherHolder) { + this.sweepInterval = sweepInterval; + this.numPartitions = numPartitions; + this.dispatcherHolder = dispatcherHolder; + this.replicationManagerFactory = replicationManagerFactory; + this.replicaStorageFactory = replicaStorageFactory; + this.backingStrategyFactory = backingStrategyFactory; + + listeners = new HashSet(); + } + + public void doStart() throws Exception { + Dispatcher dispatcher = dispatcherHolder.getDispatcher(); + + boolean strictOrdering = true; + Streamer streamer = new SimpleStreamer(); + Collapser collapser = new HashingCollapser(1024, 10000); + Map mmap = Collections.synchronizedMap(new HashMap()); + + // end of contextualiser stack + Contextualiser contextualiser = new DummyContextualiser(); + + // replica aware contextualiser +// ReplicationManager replicationManager = replicationManagerFactory.factory(dispatcher, +// replicaStorageFactory, +// backingStrategyFactory); +// DistributableManagerRehydrater sessionRehydrater = new DistributableManagerRehydrater(); +// ReplicationManager sessionRepManager = new SessionReplicationManager(replicationManager, sessionRehydrater); +// contextualiser = new ReplicaAwareContextualiser(contextualiser, sessionRepManager); + + // cluster aware contextualiser + contextualiser = new ClusterContextualiser(contextualiser, collapser, new HybridRelocater(5000, 5000, true)); + + contextualiser = new StatelessContextualiser(contextualiser, Pattern.compile("GET|POST", 2), true, + Pattern.compile(".*\\.(JPG|JPEG|GIF|PNG|ICO|HTML|HTM)", 2), false); + + // serialize invocations bound to the same session id + contextualiser = new SerialContextualiser(contextualiser, collapser, mmap); + + // in-memory contextualiser + WebSessionPool sessionPool = new SimpleSessionPool(new AtomicallyReplicableSessionFactory()); + Evicter mevicter = new AbsoluteEvicter(sweepInterval, strictOrdering, 10); + SessionPool contextPool = new WebSessionToSessionPoolAdapter(sessionPool); + PoolableInvocationWrapperPool requestPool = new DummyStatefulHttpServletRequestWrapperPool(); + contextualiser = new MotionTracker(contextualiser, mevicter, mmap, streamer, contextPool, requestPool); + + contextualiser = new SerialContextualiserFrontingMemory(contextualiser, new HashingCollapser(1024, 10000)); + + // Manager + AttributesFactory attributesFactory = new DistributableAttributesFactory(); + ValuePool valuePool = new SimpleValuePool(new DistributableValueFactory()); + WebSessionWrapperFactory wrapperFactory = new StandardSessionWrapperFactory(); + manager = new ClusteredManager(sessionPool, + attributesFactory, + valuePool, + wrapperFactory, + null, + contextualiser, + mmap, + new DummyRouter(), + true, + streamer, + true, + new DummyReplicaterFactory(), +// new ReplicaterAdapterFactory(replicationManager), + null, + null, + dispatcher, + numPartitions, + collapser); +// sessionRehydrater.setManager(manager); + + manager.init(new ManagerConfig() { + public void callback(Manager manager) { + } + + public ServletContext getServletContext() { + return null; + } + }); + + manager.start(); + } + + public void doStop() throws Exception { + manager.stop(); + } + + public void doFail() { + try { + manager.stop(); + } catch (Exception e) { + log.error(e); + } + } + + public Session createSession(String sessionId) throws SessionAlreadyExistException { + WebSession session; + try { + session = manager.createWithName(sessionId); + } catch (org.codehaus.wadi.SessionAlreadyExistException e) { + throw new SessionAlreadyExistException(sessionId); + } + return new WADISessionAdaptor(session); + } + + public ClusteredManager getManager() { + return manager; + } + + public Node getNode() { + return dispatcherHolder.getNode(); + } + + public void registerListener(SessionListener listener) { + synchronized (listeners) { + listeners.add(listener); + } + } + + public void unregisterListener(SessionListener listener) { + synchronized (listeners) { + listeners.remove(listener); + } + } + + private void notifyInboundSessionMigration(WebSession webSession) { + synchronized (listeners) { + for (Iterator iter = listeners.iterator(); iter.hasNext();) { + SessionListener listener = (SessionListener) iter.next(); + listener.notifyInboundSessionMigration(new WADISessionAdaptor(webSession)); + } + } + } + + private WebSession notifyOutboundSessionMigration(WebSession webSession) { + synchronized (listeners) { + for (Iterator iter = listeners.iterator(); iter.hasNext();) { + SessionListener listener = (SessionListener) iter.next(); + listener.notifyOutboundSessionMigration(new WADISessionAdaptor(webSession)); + } + } + return webSession; + } + + private class MotionTracker extends MemoryContextualiser { + private final Immoter immoter; + private final Emoter emoter; + + public MotionTracker(Contextualiser next, Evicter evicter, Map map, Streamer streamer, SessionPool pool, + PoolableInvocationWrapperPool requestPool) { + super(next, evicter, map, streamer, pool, requestPool); + + Immoter immoterDelegate = super.getImmoter(); + immoter = new InboundSessionTracker(immoterDelegate); + + Emoter emoterDelegate = super.getEmoter(); + emoter = new OutboundSessionTracker(emoterDelegate); + } + + public Immoter getPromoter(Immoter immoter) { + Immoter delegate = super.getPromoter(immoter); + if (null == immoter) { + return new InboundSessionTracker(delegate); + } else { + return delegate; + } + } + + public Immoter getImmoter() { + return immoter; + } + + public Emoter getEmoter() { + return emoter; + } + } + + private class OutboundSessionTracker implements Emoter { + private final Emoter delegate; + + public OutboundSessionTracker(Emoter delegate) { + this.delegate = delegate; + } + + public void commit(String arg0, Motable arg1) { + notifyOutboundSessionMigration((WebSession) arg1); + delegate.commit(arg0, arg1); + } + + public String getInfo() { + return delegate.getInfo(); + } + + public boolean prepare(String arg0, Motable arg1, Motable arg2) { + return delegate.prepare(arg0, arg1, arg2); + } + + public void rollback(String arg0, Motable arg1) { + delegate.rollback(arg0, arg1); + } + } + + private class InboundSessionTracker implements Immoter { + private final Immoter delegate; + + public InboundSessionTracker(Immoter delegate) { + this.delegate = delegate; + } + + public void commit(String arg0, Motable arg1) { + notifyInboundSessionMigration((WebSession) arg1); + delegate.commit(arg0, arg1); + } + + public boolean contextualise(Invocation arg0, String arg1, Motable arg2, Sync arg3) throws InvocationException { + return delegate.contextualise(arg0, arg1, arg2, arg3); + } + + public String getInfo() { + return delegate.getInfo(); + } + + public Motable nextMotable(String arg0, Motable arg1) { + return delegate.nextMotable(arg0, arg1); + } + + public boolean prepare(String arg0, Motable arg1, Motable arg2) { + return delegate.prepare(arg0, arg1, arg2); + } + + public void rollback(String arg0, Motable arg1) { + delegate.rollback(arg0, arg1); + } + } + + + public static final GBeanInfo GBEAN_INFO; + + public static final String GBEAN_ATTR_SWEEP_INTERVAL = "sweepInterval"; + public static final String GBEAN_ATTR_NUM_PARTITIONS = "numPartitions"; + + public static final String GBEAN_REF_REPLICATION_MANAGER_FACTORY = "ReplicationManagerFactory"; + public static final String GBEAN_REF_REPLICA_STORAGE_FACTORY = "ReplicaStorageFactory"; + public static final String GBEAN_REF_BACKING_STRATEGY_FACTORY = "BackingStrategyFactory"; + public static final String GBEAN_REF_DISPATCHER_HOLDER = "DispatcherHolder"; + + static { + GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic("WADI Session Manager", + BasicWADISessionManager.class, + NameFactory.GERONIMO_SERVICE); + + infoBuilder.addAttribute(GBEAN_ATTR_SWEEP_INTERVAL, int.class, true); + infoBuilder.addAttribute(GBEAN_ATTR_NUM_PARTITIONS, int.class, true); + + infoBuilder.addReference(GBEAN_REF_REPLICATION_MANAGER_FACTORY, ReplicationManagerFactory.class, + NameFactory.GERONIMO_SERVICE); + infoBuilder.addReference(GBEAN_REF_REPLICA_STORAGE_FACTORY, ReplicaStorageFactory.class, + NameFactory.GERONIMO_SERVICE); + infoBuilder.addReference(GBEAN_REF_BACKING_STRATEGY_FACTORY, BackingStrategyFactory.class, + NameFactory.GERONIMO_SERVICE); + infoBuilder.addReference(GBEAN_REF_DISPATCHER_HOLDER, DispatcherHolder.class, NameFactory.GERONIMO_SERVICE); + + infoBuilder.addInterface(SessionManager.class); + infoBuilder.addInterface(WADISessionManager.class); + + infoBuilder.setConstructor(new String[]{GBEAN_ATTR_SWEEP_INTERVAL, + GBEAN_ATTR_NUM_PARTITIONS, + GBEAN_REF_REPLICATION_MANAGER_FACTORY, + GBEAN_REF_REPLICA_STORAGE_FACTORY, + GBEAN_REF_BACKING_STRATEGY_FACTORY, + GBEAN_REF_DISPATCHER_HOLDER}); + + GBEAN_INFO = infoBuilder.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/DispatcherHolder.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/DispatcherHolder.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/DispatcherHolder.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/DispatcherHolder.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,30 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering.wadi; + +import org.apache.geronimo.clustering.Node; +import org.codehaus.wadi.group.Dispatcher; + +/** + * + * @version $Rev$ $Date$ + */ +public interface DispatcherHolder { + Dispatcher getDispatcher(); + + Node getNode(); +} Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/RoundRobinBackingStrategyFactoryGBean.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/RoundRobinBackingStrategyFactoryGBean.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/RoundRobinBackingStrategyFactoryGBean.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/RoundRobinBackingStrategyFactoryGBean.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,77 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering.wadi; + +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; +import org.codehaus.wadi.replication.strategy.BackingStrategy; +import org.codehaus.wadi.replication.strategy.BackingStrategyFactory; +import org.codehaus.wadi.replication.strategy.RoundRobinBackingStrategyFactory; + +/** + * + * @version $Rev$ $Date$ + */ +public class RoundRobinBackingStrategyFactoryGBean implements BackingStrategyFactory, GBeanLifecycle { + private final int nbReplica; + + private BackingStrategyFactory strategyFactory; + + public RoundRobinBackingStrategyFactoryGBean(int nbReplica) { + this.nbReplica = nbReplica; + } + + public BackingStrategy factory() { + return strategyFactory.factory(); + } + + public void doFail() { + strategyFactory = null; + } + + public void doStart() throws Exception { + strategyFactory = new RoundRobinBackingStrategyFactory(nbReplica); + } + + public void doStop() throws Exception { + strategyFactory = null; + } + + + public static final GBeanInfo GBEAN_INFO; + + public static final String GBEAN_ATTR_NB_REPLICA = "nbReplica"; + + static { + GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(RoundRobinBackingStrategyFactoryGBean.class, + NameFactory.GERONIMO_SERVICE); + + infoBuilder.addAttribute(GBEAN_ATTR_NB_REPLICA, int.class, true); + + infoBuilder.addInterface(BackingStrategyFactory.class); + + infoBuilder.setConstructor(new String[] {GBEAN_ATTR_NB_REPLICA}); + + GBEAN_INFO = infoBuilder.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/TribesDispatcherHolder.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/TribesDispatcherHolder.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/TribesDispatcherHolder.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/TribesDispatcherHolder.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,104 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering.wadi; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.clustering.Node; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; +import org.codehaus.wadi.group.Dispatcher; +import org.codehaus.wadi.group.MessageExchangeException; +import org.codehaus.wadi.tribes.TribesDispatcher; + +/** + * + * @version $Rev$ $Date$ + */ +public class TribesDispatcherHolder implements GBeanLifecycle, DispatcherHolder { + private static final Log log = LogFactory.getLog(TribesDispatcherHolder.class); + + private final String clusterName; + private final long inactiveTime; + private final Node node; + + private TribesDispatcher dispatcher; + + public TribesDispatcherHolder(String clusterName, long inactiveTime, Node node) { + this.clusterName = clusterName; + this.inactiveTime = inactiveTime; + this.node = node; + } + + public void doStart() throws Exception { + dispatcher = new TribesDispatcher(clusterName, node.getName(), inactiveTime, null); + dispatcher.start(); + } + + public void doStop() throws Exception { + dispatcher.stop(); + } + + public void doFail() { + try { + dispatcher.stop(); + } catch (MessageExchangeException e) { + log.error(e); + } + } + + public Dispatcher getDispatcher() { + return dispatcher; + } + + public Node getNode() { + return node; + } + + + public static final GBeanInfo GBEAN_INFO; + + public static final String GBEAN_ATTR_CLUSTER_NAME = "clusterName"; + public static final String GBEAN_ATTR_CLUSTER_URI = "clusterUri"; + public static final String GBEAN_ATTR_INACTIVE_TIME = "inactiveTime"; + + public static final String GBEAN_REF_NODE = "Node"; + + static { + GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(TribesDispatcherHolder.class, + NameFactory.GERONIMO_SERVICE); + + infoBuilder.addAttribute(GBEAN_ATTR_CLUSTER_NAME, String.class, true); + infoBuilder.addAttribute(GBEAN_ATTR_INACTIVE_TIME, long.class, true); + + infoBuilder.addReference(GBEAN_REF_NODE, Node.class, NameFactory.GERONIMO_SERVICE); + + infoBuilder.addInterface(DispatcherHolder.class); + + infoBuilder.setConstructor(new String[] { GBEAN_ATTR_CLUSTER_NAME, + GBEAN_ATTR_INACTIVE_TIME, + GBEAN_REF_NODE }); + + GBEAN_INFO = infoBuilder.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADIClusteredHandleInterceptor.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADIClusteredHandleInterceptor.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADIClusteredHandleInterceptor.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADIClusteredHandleInterceptor.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,129 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering.wadi; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.apache.geronimo.clustering.ClusteredInvocation; +import org.apache.geronimo.clustering.ClusteredInvocationException; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; +import org.apache.geronimo.jetty.HandleInterceptor; +import org.apache.geronimo.jetty.cluster.AbstractClusteredHandleInterceptor; +import org.codehaus.wadi.InvocationException; +import org.codehaus.wadi.impl.ClusteredManager; +import org.codehaus.wadi.web.impl.WebInvocation; +import org.mortbay.http.HttpRequest; +import org.mortbay.http.HttpResponse; +import org.mortbay.jetty.servlet.ServletHttpRequest; +import org.mortbay.jetty.servlet.ServletHttpResponse; + + +/** + * + * @version $Rev$ $Date$ + */ +public class WADIClusteredHandleInterceptor extends AbstractClusteredHandleInterceptor implements GBeanLifecycle { + private final WADISessionManager sessionManager; + + private ClusteredManager wadiManager; + + public WADIClusteredHandleInterceptor(WADISessionManager sessionManager) { + this.sessionManager = sessionManager; + } + + public void doStart() throws Exception { + wadiManager = sessionManager.getManager(); + } + + public void doStop() throws Exception { + wadiManager = null; + } + + public void doFail() { + wadiManager = null; + } + + protected ClusteredInvocation newClusteredInvocation(String pathInContext, String pathParams, HttpRequest request, + HttpResponse response, HandleInterceptor end) { + return new WADIWebClusteredInvocation(pathInContext, pathParams, request, response, end); + } + + protected class WADIWebClusteredInvocation extends WebClusteredInvocation { + + public WADIWebClusteredInvocation(String pathInContext, String pathParams, HttpRequest request, + HttpResponse response, HandleInterceptor end) { + super(pathInContext, pathParams, request, response, end); + } + + public void invoke() throws ClusteredInvocationException { + ServletHttpRequest servletHttpRequest = (ServletHttpRequest) request.getWrapper(); + ServletHttpResponse servletHttpResponse = (ServletHttpResponse) response.getWrapper(); + + WebInvocation invocation = WebInvocation.getThreadLocalInstance(); + FilterChain chainAdapter = new FilterChain() { + public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { + try { + invokeLocally(); + } catch (ClusteredInvocationException e) { + throw (IOException) new IOException().initCause(e); + } + } + }; + invocation.init(servletHttpRequest, servletHttpResponse, chainAdapter); + try { + wadiManager.contextualise(invocation); + } catch (InvocationException e) { + Throwable throwable = e.getCause(); + if (throwable instanceof IOException) { + throw new ClusteredInvocationException(throwable); + } else if (throwable instanceof ServletException) { + throw new ClusteredInvocationException(throwable); + } else { + throw new ClusteredInvocationException(e); + } + } + } + } + + public static final GBeanInfo GBEAN_INFO; + + public static final String GBEAN_REF_WADI_SESSION_MANAGER = "WADISessionManager"; + + static { + GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic("WADI Clustered Handle Interceptor", + WADIClusteredHandleInterceptor.class, NameFactory.GERONIMO_SERVICE); + + infoBuilder.addReference(GBEAN_REF_WADI_SESSION_MANAGER, WADISessionManager.class, + NameFactory.GERONIMO_SERVICE); + + infoBuilder.setConstructor(new String[]{GBEAN_REF_WADI_SESSION_MANAGER}); + + GBEAN_INFO = infoBuilder.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionAdaptor.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionAdaptor.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionAdaptor.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionAdaptor.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,128 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering.wadi; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.apache.geronimo.clustering.Session; +import org.codehaus.wadi.web.WebSession; + +/** + * + * @version $Rev$ $Date$ + */ +public class WADISessionAdaptor implements Session { + private final WebSession session; + private final Map state; + + public WADISessionAdaptor(WebSession session) { + this.session = session; + + state = new StateMap(); + } + + public String getSessionId() { + return session.getId(); + } + + public void release() { + try { + session.destroy(); + } catch (Exception e) { + throw new IllegalStateException("Cannot release session " + session); + } + } + + public Object addState(String key, Object value) { + return session.setAttribute(key, value); + } + + public Object getState(String key) { + return session.getAttribute(key); + } + + public Object removeState(String key) { + return session.removeAttribute(key); + } + + public Map getState() { + return state; + } + + private class StateMap implements Map { + + public Object put(Object key, Object value) { + String wadiKey = ensureTypeAndCast(key); + return addState(wadiKey, value); + } + + public Object remove(Object key) { + String wadiKey = ensureTypeAndCast(key); + return removeState(wadiKey); + } + + public void clear() { + throw new UnsupportedOperationException(); + } + + public boolean containsKey(Object key) { + throw new UnsupportedOperationException(); + } + + public boolean containsValue(Object value) { + throw new UnsupportedOperationException(); + } + + public Set entrySet() { + throw new UnsupportedOperationException(); + } + + public Object get(Object key) { + String wadiKey = ensureTypeAndCast(key); + return getState(wadiKey); + } + + public boolean isEmpty() { + throw new UnsupportedOperationException(); + } + + public Set keySet() { + return session.getAttributeNameSet(); + } + + public void putAll(Map t) { + throw new UnsupportedOperationException(); + } + + public int size() { + return session.getAttributeNameSet().size(); + } + + public Collection values() { + throw new UnsupportedOperationException(); + } + + private String ensureTypeAndCast(Object key) { + if (!(key instanceof String)) { + throw new ClassCastException(String.class + " is expected."); + } + return (String) key; + } + } +} Added: geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionManager.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionManager.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionManager.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering-wadi/src/main/java/org/apache/geronimo/clustering/wadi/WADISessionManager.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,27 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering.wadi; + +import org.codehaus.wadi.impl.ClusteredManager; + +/** + * + * @version $Rev$ $Date$ + */ +public interface WADISessionManager { + ClusteredManager getManager(); +} \ No newline at end of file Added: geronimo/server/trunk/modules/geronimo-clustering/pom.xml URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/pom.xml?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/pom.xml (added) +++ geronimo/server/trunk/modules/geronimo-clustering/pom.xml Fri Sep 15 08:02:12 2006 @@ -0,0 +1,63 @@ + + + + + + + + 4.0.0 + + + org.apache.geronimo.modules + modules + 1.2-SNAPSHOT + ../pom.xml + + + geronimo-clustering + Geronimo Clustering + + + + scm:svn:https://svn.apache.org/repos/asf/geronimo/trunk/modules/clustering + scm:svn:https://${maven.username}@svn.apache.org/repos/asf/geronimo/trunk/modules/clustering + http://svn.apache.org/repos/asf/geronimo/trunk/modules/clustering + + + + + ${pom.groupId} + geronimo-system + ${pom.version} + + + + ${pom.groupId} + geronimo-j2ee + ${pom.version} + + + + + Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/BasicNode.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/BasicNode.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/BasicNode.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/BasicNode.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,57 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; + +/** + * + * @version $Rev$ $Date$ + */ +public class BasicNode implements Node { + private final String name; + + public BasicNode(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static final GBeanInfo GBEAN_INFO; + + public static final String GBEAN_ATTR_NODE_NAME = "nodeName"; + + static { + GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(BasicNode.class, NameFactory.GERONIMO_SERVICE); + + infoBuilder.addAttribute(GBEAN_ATTR_NODE_NAME, String.class, true); + + infoBuilder.addInterface(Node.class); + + infoBuilder.setConstructor(new String[] {GBEAN_ATTR_NODE_NAME}); + + GBEAN_INFO = infoBuilder.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocation.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocation.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocation.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocation.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,56 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + + +/** + * Represents a clustered invocation. + *

+ * A clustered invocation is intended to be a thin wrapper around an actual invocation enhancing this latter with + * an association to a local SessionManager. For instance, an HTTPRequest is an actual invocation. + *

+ * A clustered invocation is interposed between a client and the Session he wants to access to provide cluster wide + * access serialization to the requested Session. A clustered invocation is associated to a local SessionManager, even + * if no contract captures such a relationship. When a clustered invocation is executed one of the two following + * scenarios happen: + *

    + *
  • the clustered invocation is executed locally. A local execution implies that the local SessionManager associated + * to the clustered invocation is owning the Session (may be after a migration); or
  • + *
  • the clustered invocation is executed remotely on the Node where the Session is being owned.
  • + *
+ * + * @version $Rev$ $Date$ + */ +public interface ClusteredInvocation { + + /** + * Invokes the clustered invocation. + * + * @throws ClusteredInvocationException Thrown when the invocation cannot be successfully executed. This may + * be either due to the fact that the actual invocation has failed or the requestedSessionId is unknown by + * the associated local SessionManager and its remote peers. + */ + void invoke() throws ClusteredInvocationException; + + /** + * Gets the sessionId of the Session bound to the invocation represented by this instance. + * + * @return sessionId of the targeted Session. + */ + String getRequestedSessionId(); + +} Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocationException.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocationException.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocationException.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/ClusteredInvocationException.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,40 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + +/** + * + * @version $Rev$ $Date$ + */ +public class ClusteredInvocationException extends Exception { + + public ClusteredInvocationException() { + super(); + } + + public ClusteredInvocationException(String message, Throwable cause) { + super(message, cause); + } + + public ClusteredInvocationException(String message) { + super(message); + } + + public ClusteredInvocationException(Throwable cause) { + super(cause); + } +} Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Node.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Node.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Node.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Node.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,33 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + +/** + * Represents a node. + * + * @version $Rev$ $Date$ + */ +public interface Node { + + /** + * Gets the node name. + * + * @return Node name + */ + String getName(); + +} Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Session.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Session.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Session.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/Session.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,78 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + +import java.util.Map; + +/** + * Represents a clustered session. + *

+ * A Session is created by a SessionManager and is uniquely identified by its sessionId. More accurately, this + * sessionId is unique within the set of SessionManagers from which this Session has been sourced. If two Sessions + * have the same sessionId, then a client can be sure that they have been created from two distinct set of + * SessionManagers. + *

+ * A Session provides Map like contracts to manipulate state information. State information must be Serializable as + * it may be marshalled automatically by the underpinning local SessionManager. At any given point of time, a Session + * is uniquely "instantiated" once cluster wide. Also, cluster wide accesses to a given Session are + * ensured to be serialized by the set of SessionManagers from which the Session has been sourced. The interposition + * of a ClusteredInvocation between a client and the Session this client would like to access enforces unique + * instantiation and access serialization cluster wide for a given Session. + * + * @version $Rev$ $Date$ + */ +public interface Session { + + /** + * Gets the sessionId. + * + * @return sessionId. + */ + String getSessionId(); + + /** + * Map like contract to manipulate state information. + */ + Object addState(String key, Object value); + + /** + * Map like contract to manipulate state information. + */ + Object getState(String key); + + /** + * Map like contract to manipulate state information. + */ + Object removeState(String key); + + /** + * Map like contract to manipulate state information. + *

+ * The returned Map is mutable and is backed by the session. + */ + Map getState(); + + /** + * Releases the session. + *

+ * When a Session is released, it is released from the underlying set of SessionManagers. In other words, its + * sessionId is unknown and its state is permanently lost. After the release of a Session, the behavior of + * the other methods is undefined. + */ + void release(); + +} Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionAlreadyExistException.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionAlreadyExistException.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionAlreadyExistException.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionAlreadyExistException.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,40 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + +/** + * + * @version $Rev$ $Date$ + */ +public class SessionAlreadyExistException extends Exception { + + public SessionAlreadyExistException() { + super(); + } + + public SessionAlreadyExistException(String message, Throwable cause) { + super(message, cause); + } + + public SessionAlreadyExistException(String message) { + super(message); + } + + public SessionAlreadyExistException(Throwable cause) { + super(cause); + } +} Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionListener.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionListener.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionListener.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionListener.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,51 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + +/** + * Callback listener for inbound and outbound Session migration. + *

+ * A Session is preemptively moved between its associated set of SessionManagers. For instance, when a + * ClusteredInvocation for a given Session is invoked on a Node where the local SessionManager, RequestingSM, does not + * own the targeted Session, the SessionManager owning the Session, OwningSM, the Session may be moved from OwningSM + * to RequestingSM. OwningSM, prior to relinquish the Session, executes notifyOutboundSessionMigration and provides + * the Session under migration. RequestingRM, after having acquired the Session ownership, executes + * notifyInboundSessionMigration and provides the Session under migration. + *

+ * The typical usage of these migration callbacks are to allow a wrapping SessionManager, e.g. an HTTPSession manager, + * to perform bookkeeping operations. + * + * @version $Rev$ $Date$ + */ +public interface SessionListener { + + /** + * Calls when the ownership of the provided Session is acquired by the SessionManager to which this listener + * is attached. + * + * @param session New Session now owned by the attached SessionManager. + */ + void notifyInboundSessionMigration(Session session); + + /** + * Calls when the ownership of the provided Session is relinquished to another SessionManager. + * + * @param session Session now owned by another SessionManager. + */ + void notifyOutboundSessionMigration(Session session); + +} Added: geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionManager.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionManager.java?view=auto&rev=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionManager.java (added) +++ geronimo/server/trunk/modules/geronimo-clustering/src/main/java/org/apache/geronimo/clustering/SessionManager.java Fri Sep 15 08:02:12 2006 @@ -0,0 +1,61 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.clustering; + +/** + * Represents a local SessionManager. + *

+ * A local SessionManager works collaboratively with remote SessionManagers to manage Session instances. A local + * SessionMananger along with its associated remote SessionManagers are a single space where Session instances live. + * In this space, each Session is ensured to have a unique sessionId. This contract is enforced during creation of + * a Session instance by a local SessionManager. A Session in this space is preemptively migrated from one local + * SessionManager to another. The interposition of a ClusteredInvocation between a Client and the Session he wants to + * access ensures that at any point in time a Session is uniquely instantiated once cluster wide. Clients can + * receive migration callbacks via the registration of SessionListener. + * + * @version $Rev$ $Date$ + */ +public interface SessionManager { + + /** + * Creates a Session having the specified sessionId. + * + * @param sessionId Unique identifier of the Session instance. + * @return Session instance. + * @throws SessionAlreadyExistException Thrown when the provided sessiondId already exists in the Session space + * of this local SessionManager and its associated remote SessionManagers. + */ + Session createSession(String sessionId) throws SessionAlreadyExistException; + + /** + * Registers a migration listener. + */ + void registerListener(SessionListener listener); + + /** + * Unregisters a migration listener. + */ + void unregisterListener(SessionListener listener); + + /** + * Gets the Node hosting this local SessionManager. + * + * @return Hosting Node. + */ + Node getNode(); + +} Modified: geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilder.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilder.java?view=diff&rev=446624&r1=446623&r2=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilder.java (original) +++ geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilder.java Fri Sep 15 08:02:12 2006 @@ -22,11 +22,15 @@ import org.apache.xmlbeans.XmlObject; import org.apache.geronimo.common.DeploymentException; import org.apache.geronimo.gbean.AbstractName; +import org.apache.geronimo.kernel.repository.Environment; /** * @version $Rev$ $Date$ */ public interface NamespaceDrivenBuilder { + + void buildEnvironment(XmlObject container, Environment environment) throws DeploymentException; + void build(XmlObject container, DeploymentContext applicationContext, DeploymentContext moduleContext) throws DeploymentException; String getNamespace(); Modified: geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilderCollection.java URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilderCollection.java?view=diff&rev=446624&r1=446623&r2=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilderCollection.java (original) +++ geronimo/server/trunk/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/NamespaceDrivenBuilderCollection.java Fri Sep 15 08:02:12 2006 @@ -22,11 +22,13 @@ import java.util.Iterator; import java.util.Collection; import java.util.List; +import java.util.Collections; import org.apache.geronimo.gbean.ReferenceCollection; import org.apache.geronimo.gbean.ReferenceCollectionListener; import org.apache.geronimo.gbean.ReferenceCollectionEvent; import org.apache.geronimo.common.DeploymentException; +import org.apache.geronimo.kernel.repository.Environment; import org.apache.xmlbeans.XmlObject; /** @@ -38,7 +40,7 @@ private final Set namespaces = new HashSet(); public NamespaceDrivenBuilderCollection(Collection builders) { - this.builders = builders; + this.builders = builders == null? Collections.EMPTY_SET: builders; if (builders instanceof ReferenceCollection) { ((ReferenceCollection)builders).addReferenceCollectionListener(new ReferenceCollectionListener() { @@ -53,7 +55,7 @@ } }); } - for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + for (Iterator iterator = this.builders.iterator(); iterator.hasNext();) { Object builder = iterator.next(); addBuilder(builder); } @@ -64,7 +66,14 @@ if (namespaces.contains(namespace)) { throw new IllegalArgumentException("Duplicate namespace in builder set: " + namespace); } - namespaces.add(namespace); + namespaces.add(namespace); + } + + public void buildEnvironment(XmlObject container, Environment environment) throws DeploymentException { + for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + NamespaceDrivenBuilder builder = (NamespaceDrivenBuilder) iterator.next(); + builder.buildEnvironment(container, environment); + } } public void build(XmlObject container, DeploymentContext applicationContext, DeploymentContext moduleContext) throws DeploymentException { Modified: geronimo/server/trunk/modules/geronimo-j2ee-builder/src/main/schema/geronimo-application-1.2.xsd URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-j2ee-builder/src/main/schema/geronimo-application-1.2.xsd?view=diff&rev=446624&r1=446623&r2=446624 ============================================================================== --- geronimo/server/trunk/modules/geronimo-j2ee-builder/src/main/schema/geronimo-application-1.2.xsd (original) +++ geronimo/server/trunk/modules/geronimo-j2ee-builder/src/main/schema/geronimo-application-1.2.xsd Fri Sep 15 08:02:12 2006 @@ -84,6 +84,13 @@ + + + + + + +