You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wadi-commits@incubator.apache.org by bd...@apache.org on 2005/12/14 23:36:16 UTC
svn commit: r356933 [11/35] - in /incubator/wadi/trunk: ./ etc/ modules/
modules/assembly/ modules/assembly/src/ modules/assembly/src/bin/
modules/assembly/src/conf/ modules/assembly/src/main/
modules/assembly/src/main/assembly/ modules/core/ modules/c...
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableManager.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableManager.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableManager.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableManager.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,133 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.codehaus.wadi.AttributesFactory;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.DistributableContextualiserConfig;
+import org.codehaus.wadi.ManagerConfig;
+import org.codehaus.wadi.ReplicableSessionConfig;
+import org.codehaus.wadi.Replicater;
+import org.codehaus.wadi.ReplicaterFactory;
+import org.codehaus.wadi.Router;
+import org.codehaus.wadi.SessionIdFactory;
+import org.codehaus.wadi.SessionPool;
+import org.codehaus.wadi.SessionWrapperFactory;
+import org.codehaus.wadi.Streamer;
+import org.codehaus.wadi.StreamerConfig;
+import org.codehaus.wadi.ValueHelper;
+import org.codehaus.wadi.ValuePool;
+import org.codehaus.wadi.impl.ClusteredManager.HelperPair;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
+
+/**
+ * @author jules
+ * A StandardManager that knows how to Serialise HttpSessions.
+ */
+public class DistributableManager extends StandardManager implements ReplicableSessionConfig, DistributableContextualiserConfig, StreamerConfig {
+
+ protected final List _helpers = new ArrayList();
+ protected final SynchronizedBoolean _shuttingDown = new SynchronizedBoolean(false);
+ protected final Streamer _streamer;
+ protected final boolean _accessOnLoad;
+ protected final ReplicaterFactory _replicaterFactory;
+
+ public DistributableManager(SessionPool sessionPool, AttributesFactory attributesFactory, ValuePool valuePool, SessionWrapperFactory sessionWrapperFactory, SessionIdFactory sessionIdFactory, Contextualiser contextualiser, Map map, Router router, boolean errorIfSessionNotAcquired, Streamer streamer, boolean accessOnLoad, ReplicaterFactory replicaterFactory) {
+ super(sessionPool, attributesFactory, valuePool, sessionWrapperFactory, sessionIdFactory, contextualiser, map, router, errorIfSessionNotAcquired);
+ (_streamer=streamer).init(this);
+ _accessOnLoad=accessOnLoad;
+ _replicaterFactory=replicaterFactory;
+ }
+
+ protected ClassLoader _classLoader;
+
+ public void init(ManagerConfig config) {
+ _classLoader= Thread.currentThread().getContextClassLoader();
+ super.init(config);
+ }
+
+ public ClassLoader getClassLoader() {
+ return _classLoader;
+ }
+
+ /**
+ * Register a ValueHelper for a particular type. During [de]serialisation
+ * Objects flowing in/out of the persistance medium will be passed through this
+ * Helper, which will have the opportunity to convert them between Serializable
+ * and non-Serializable representations. Helpers will be returned in their registration
+ * order, so this is significant (as an Object may implement more than one interface
+ * or registered type).
+ *
+ * @param type
+ * @param helper
+ */
+ public void registerHelper(Class type, ValueHelper helper) {
+ _helpers.add(new HelperPair(type, helper));
+ }
+
+ public boolean deregisterHelper(Class type) {
+ int l=_helpers.size();
+ for (int i=0; i<l; i++)
+ if (type.equals(((HelperPair)_helpers.get(i))._type)) {
+ _helpers.remove(i);
+ return true;
+ }
+ return false;
+ }
+
+ public ValueHelper findHelper(Class type) {
+ int l=_helpers.size();
+ for (int i=0; i<l; i++) {
+ HelperPair p=(HelperPair)_helpers.get(i);
+ if (p._type.isAssignableFrom(type))
+ return p._helper;
+ }
+ return null;
+ }
+
+ public boolean getHttpSessionAttributeListenersRegistered() {
+ return _attributeListeners.length>0;
+ }
+
+ public boolean getDistributable() {
+ return true;
+ }
+
+ public boolean getAccessOnLoad() {
+ return _accessOnLoad;
+ }
+
+ public SynchronizedBoolean getShuttingDown() {
+ return _shuttingDown;
+ }
+
+ public Streamer getStreamer() {
+ return _streamer;
+ }
+
+ // ReplicableSessionConfig
+
+ public Replicater getReplicater() {
+ return _replicaterFactory.create();
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSession.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSession.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSession.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSession.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,69 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Set;
+
+import org.codehaus.wadi.DistributableAttributesConfig;
+import org.codehaus.wadi.DistributableSessionConfig;
+import org.codehaus.wadi.Streamer;
+import org.codehaus.wadi.ValueHelper;
+
+/**
+ * A Standard Session enhanced with functionality associated with [de]serialisation - necessary to allow the movement of the session from jvm to jvm/storage.
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.4 $
+ */
+
+public class DistributableSession extends StandardSession implements DistributableAttributesConfig {
+
+ public DistributableSession(DistributableSessionConfig config) {
+ super(config);
+ }
+
+ public Streamer getStreamer() {
+ return ((DistributableSessionConfig)_config).getStreamer();
+ }
+
+ public void readContent(ObjectInput oi) throws IOException, ClassNotFoundException {
+ super.readContent(oi);
+ ((DistributableAttributes)_attributes).readContent(oi);
+ }
+
+ public void writeContent(ObjectOutput oo) throws IOException {
+ super.writeContent(oo);
+ ((DistributableAttributes)_attributes).writeContent(oo);
+ }
+
+ public byte[] getBodyAsByteArray() throws Exception {
+ return Utils.getContent(this, getStreamer());
+ }
+
+ public void setBodyAsByteArray(byte[] bytes) throws IOException, ClassNotFoundException {
+ Utils.setContent(this, bytes, getStreamer());
+ }
+
+ public ValueHelper findHelper(Class type){return ((DistributableSessionConfig)_config).findHelper(type);}
+ public Set getListenerNames(){return ((DistributableAttributes)_attributes).getListenerNames();}
+
+ // Lazy
+ public boolean getHttpSessionAttributeListenersRegistered(){return ((DistributableSessionConfig)_config).getHttpSessionAttributeListenersRegistered();}
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSessionFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSessionFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSessionFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableSessionFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,29 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.codehaus.wadi.DistributableSessionConfig;
+import org.codehaus.wadi.Session;
+import org.codehaus.wadi.SessionConfig;
+import org.codehaus.wadi.SessionFactory;
+
+public class DistributableSessionFactory implements SessionFactory {
+
+ public Session create(SessionConfig config) {
+ return new DistributableSession((DistributableSessionConfig)config);
+ }
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValue.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValue.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValue.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValue.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,83 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+
+import javax.servlet.http.HttpSessionActivationListener;
+
+import org.codehaus.wadi.DistributableValueConfig;
+import org.codehaus.wadi.SerializableContent;
+import org.codehaus.wadi.ValueHelper;
+
+/**
+ * An attribute Value that supports the notification of HttpSessionActivationListeners at the correct
+ * times as well as the substition of non-Serializable content with the results of pluggable Helpers.
+ * This allows us to deal with the special cases mentioned in J2EE.6.4 in a non
+ * app-server specific manner. In other words, we can deal with attributes that
+ * are non-serialisable, provided that the application writer provides a mechanism
+ * for their persistance. Types such as EJBHome, EJBObject etc. are likely to be placed
+ * into distributable Sessions.
+ * It does not expect to be accessed after serialisation, until a fresh deserialisation has occurred.
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.2 $
+ */
+
+public class DistributableValue extends StandardValue implements SerializableContent {
+
+ public DistributableValue(DistributableValueConfig config) {super(config);}
+
+ protected ValueHelper _helper;
+
+ public synchronized Object setValue(Object newValue) {
+ // set up helper if needed or warn if needed but not available...
+ if (newValue!=null && !(newValue instanceof Serializable) && (_helper=((DistributableValueConfig)_config).findHelper(newValue.getClass()))==null)
+ throw new IllegalArgumentException("Distributable HttpSession attribute values must be Serializable or of other designated type (see SRV.7.7.2)");
+
+ return super.setValue(newValue);
+ }
+
+ public synchronized void writeContent(ObjectOutput oo) throws IOException {
+ // make necessary notification
+ if (_value!=null && _value instanceof HttpSessionActivationListener) {
+ ((HttpSessionActivationListener)_value).sessionWillPassivate(_config==null?null:((DistributableValueConfig)_config).getHttpSessionEvent());
+ }
+
+ // use helper, if present, to serialise
+ Object value=(_helper==null?_value:_helper.replace(_value));
+
+ oo.writeObject(value);
+ }
+
+ public synchronized void readContent(ObjectInput oi) throws IOException, ClassNotFoundException {
+ _value=oi.readObject();
+
+ // reinstate helper, if one was used.
+ if (_value!=null && !(_value instanceof Serializable))
+ _helper=((DistributableValueConfig)_config).findHelper(_value.getClass());
+
+ // make necessary notification
+ if (_value!=null && _value instanceof HttpSessionActivationListener) {
+ ((HttpSessionActivationListener)_value).sessionDidActivate(_config==null?null:((DistributableValueConfig)_config).getHttpSessionEvent());
+ }
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValueFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValueFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValueFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DistributableValueFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.codehaus.wadi.DistributableValueConfig;
+import org.codehaus.wadi.Value;
+import org.codehaus.wadi.ValueConfig;
+import org.codehaus.wadi.ValueFactory;
+
+/**
+ * TODO - JavaDoc this type
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class DistributableValueFactory implements ValueFactory {
+
+ public DistributableValueFactory() {
+ super();
+ }
+
+ public Value create(ValueConfig config) {
+ return new DistributableValue((DistributableValueConfig)config);
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiser.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiser.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiser.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiser.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,87 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Emoter;
+import org.codehaus.wadi.Evictable;
+import org.codehaus.wadi.Evicter;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.InvocationException;
+import org.codehaus.wadi.Motable;
+
+import EDU.oswego.cs.dl.util.concurrent.Sync;
+
+/**
+ * A Contextualiser that does no contextualising
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.2 $
+ */
+public class DummyContextualiser extends AbstractContextualiser {
+
+ public DummyContextualiser() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.codehaus.wadi.sandbox.context.Contextualiser#contextualise(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain, java.lang.String, org.codehaus.wadi.sandbox.context.Contextualiser)
+ */
+ public boolean contextualise(InvocationContext invocationContext, String id, Immoter immoter, Sync motionLock, boolean exclusiveOnly) throws InvocationException {
+ return false;
+ }
+
+ protected final Evicter _evicter=new DummyEvicter();
+ public Evicter getEvicter(){return _evicter;}
+
+ public boolean isExclusive(){return false;}
+
+ public class DummyImmoter implements Immoter {
+ public Motable nextMotable(String id, Motable emotable){return null;}
+ public String getInfo(){return "dummy";}
+
+ public boolean prepare(String name, Motable emotable, Motable immotable) {return true;}
+
+ public void commit(String name, Motable immotable) {
+ // throw away incoming state...
+ }
+
+ public void rollback(String name, Motable immotable) {
+ // nothing to do...
+ }
+
+ public boolean contextualise(InvocationContext invocationContext, String id, Motable immotable, Sync motionLock) throws InvocationException {
+ return false;
+ }
+ }
+
+ protected final Immoter _immoter=new DummyImmoter();
+ public Immoter getDemoter(String name, Motable motable) {return _immoter;}
+ public Immoter getSharedDemoter(){return _immoter;}
+
+ public void promoteToExclusive(Immoter immoter){/* empty */}
+ public void load(Emoter emoter, Immoter immoter) {/* empty */}
+
+ public void setLastAccessedTime(Evictable evictable, long oldTime, long newTime) {/* do nothing */}
+ public void setMaxInactiveInterval(Evictable evictable, int oldInterval, int newInterval) {/* do nothing */}
+
+
+ public int getLocalSessionCount() {
+ return 0;
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiserConfig.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiserConfig.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiserConfig.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyContextualiserConfig.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,73 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.util.Timer;
+
+import org.codehaus.wadi.ContextualiserConfig;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.Motable;
+import org.codehaus.wadi.Router;
+import org.codehaus.wadi.SessionPool;
+
+public class DummyContextualiserConfig implements ContextualiserConfig {
+
+ public DummyContextualiserConfig() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public int getMaxInactiveInterval() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public void expire(Motable motable) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Immoter getEvictionImmoter() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Timer getTimer() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public SessionPool getSessionPool() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Router getRouter() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void notifySessionInsertion(String name) {
+ }
+
+ public void notifySessionDeletion(String name) {
+ }
+
+ public void notifySessionRelocation(String name) {
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyDistributableContextualiserConfig.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyDistributableContextualiserConfig.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyDistributableContextualiserConfig.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyDistributableContextualiserConfig.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,110 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.DistributableContextualiserConfig;
+import org.codehaus.wadi.dindex.impl.DIndex;
+import org.codehaus.wadi.gridstate.Dispatcher;
+import org.codehaus.wadi.gridstate.ExtendedCluster;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
+
+public class DummyDistributableContextualiserConfig extends DummyContextualiserConfig implements DistributableContextualiserConfig {
+
+ protected final ExtendedCluster _cluster;
+
+ public DummyDistributableContextualiserConfig(ExtendedCluster cluster) {
+ super();
+ _cluster=cluster;
+ }
+
+ public ClassLoader getClassLoader() {
+ return getClass().getClassLoader();
+ }
+
+ public ExtendedCluster getCluster() {
+ return _cluster;
+ }
+
+ public String getNodeName() {
+ return "dummy";
+ }
+
+ public InetSocketAddress getHttpAddress() {
+ return null;
+ }
+
+ protected Map _state=new HashMap();
+
+ public Object getDistributedState(Object key) {
+ return _state.get(key);
+ }
+
+ public Object putDistributedState(Object key, Object newValue) {
+ return _state.put(key, newValue);
+ }
+
+ public Object removeDistributedState(Object key) {
+ return _state.remove(key);
+ }
+
+ public void distributeState() {
+ }
+
+ public boolean getAccessOnLoad() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public SynchronizedBoolean getShuttingDown() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Map getDistributedState() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public long getInactiveTime() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getNumPartitions() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public Dispatcher getDispatcher() {
+ return null;
+ }
+
+ public DIndex getDIndex() {
+ return null;
+ }
+
+ public Contextualiser getContextualiser() {
+ return null;
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyEvicter.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyEvicter.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyEvicter.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyEvicter.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,31 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Evictable;
+
+public class DummyEvicter extends AbstractEvicter {
+
+ public void evict() {/* do nothing */}
+ public boolean test(Evictable evictable, long time, long ttl) {return false;}
+
+ public void setLastAccessedTime(Evictable evictable, long oldTime, long newTime) {/* do nothing */}
+ public void setMaxInactiveInterval(Evictable evictable, int oldInterval,int newInterval) {/* do nothing */}
+ public void insert(Evictable evictable) {/* do nothing */}
+ public void remove(Evictable evictable) {/* do nothing */}
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyHttpServletRequest.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyHttpServletRequest.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyHttpServletRequest.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyHttpServletRequest.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,96 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.io.BufferedReader;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Since HttpServletRequestWrapper insists on having a valid delegate at
+ * all times, we need a dummy to use in our cached ThreadLocal whilst it is
+ * not being used - yeugh !
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class DummyHttpServletRequest implements HttpServletRequest {
+
+ public String getAuthType(){throw new UnsupportedOperationException();}
+ public Cookie[] getCookies(){throw new UnsupportedOperationException();}
+ public long getDateHeader(String name){throw new UnsupportedOperationException();}
+ public String getHeader(String name){throw new UnsupportedOperationException();}
+ public Enumeration getHeaders(String name){throw new UnsupportedOperationException();}
+ public Enumeration getHeaderNames(){throw new UnsupportedOperationException();}
+ public int getIntHeader(String name){throw new UnsupportedOperationException();}
+ public String getMethod(){throw new UnsupportedOperationException();}
+ public String getPathInfo(){throw new UnsupportedOperationException();}
+ public String getPathTranslated(){throw new UnsupportedOperationException();}
+ public String getContextPath(){throw new UnsupportedOperationException();}
+ public String getQueryString(){throw new UnsupportedOperationException();}
+ public String getRemoteUser(){throw new UnsupportedOperationException();}
+ public boolean isUserInRole(String role){throw new UnsupportedOperationException();}
+ public Principal getUserPrincipal(){throw new UnsupportedOperationException();}
+ public String getRequestedSessionId(){throw new UnsupportedOperationException();}
+ public String getRequestURI(){throw new UnsupportedOperationException();}
+ public StringBuffer getRequestURL(){throw new UnsupportedOperationException();}
+ public String getServletPath(){throw new UnsupportedOperationException();}
+ public HttpSession getSession(boolean create){throw new UnsupportedOperationException();}
+ public HttpSession getSession(){throw new UnsupportedOperationException();}
+ public boolean isRequestedSessionIdValid(){throw new UnsupportedOperationException();}
+ public boolean isRequestedSessionIdFromCookie(){throw new UnsupportedOperationException();}
+ public boolean isRequestedSessionIdFromURL(){throw new UnsupportedOperationException();}
+ public boolean isRequestedSessionIdFromUrl(){throw new UnsupportedOperationException();}
+ public Object getAttribute(String name){throw new UnsupportedOperationException();}
+ public Enumeration getAttributeNames(){throw new UnsupportedOperationException();}
+ public String getCharacterEncoding(){throw new UnsupportedOperationException();}
+ public void setCharacterEncoding(String en){throw new UnsupportedOperationException();}
+ public int getContentLength(){throw new UnsupportedOperationException();}
+ public String getContentType(){throw new UnsupportedOperationException();}
+ public ServletInputStream getInputStream(){throw new UnsupportedOperationException();}
+ public String getParameter(String name){throw new UnsupportedOperationException();}
+ public Enumeration getParameterNames(){throw new UnsupportedOperationException();}
+ public String[] getParameterValues(String name){throw new UnsupportedOperationException();}
+ public Map getParameterMap(){throw new UnsupportedOperationException();}
+ public String getProtocol(){throw new UnsupportedOperationException();}
+ public String getScheme(){throw new UnsupportedOperationException();}
+ public String getServerName(){throw new UnsupportedOperationException();}
+ public int getServerPort(){throw new UnsupportedOperationException();}
+ public BufferedReader getReader(){throw new UnsupportedOperationException();}
+ public String getRemoteAddr(){throw new UnsupportedOperationException();}
+ public String getRemoteHost(){throw new UnsupportedOperationException();}
+ public void setAttribute(String name, Object o){throw new UnsupportedOperationException();}
+ public void removeAttribute(String name){throw new UnsupportedOperationException();}
+ public Locale getLocale(){throw new UnsupportedOperationException();}
+ public Enumeration getLocales(){throw new UnsupportedOperationException();}
+ public boolean isSecure(){throw new UnsupportedOperationException();}
+ public RequestDispatcher getRequestDispatcher(String path){throw new UnsupportedOperationException();}
+ public String getRealPath(String path){throw new UnsupportedOperationException();}
+ public int getRemotePort(){throw new UnsupportedOperationException();}
+ public String getLocalName(){throw new UnsupportedOperationException();}
+ public String getLocalAddr(){throw new UnsupportedOperationException();}
+ public int getLocalPort(){throw new UnsupportedOperationException();}
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRelocater.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRelocater.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRelocater.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRelocater.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.InvocationException;
+import org.codehaus.wadi.Relocater;
+import org.codehaus.wadi.RelocaterConfig;
+
+import EDU.oswego.cs.dl.util.concurrent.Sync;
+
+public class DummyRelocater implements Relocater {
+
+ public void init(RelocaterConfig config) {
+ // empty
+ }
+
+ public void destroy() {
+ // empty
+ }
+
+ public boolean relocate(InvocationContext invocationContext, String name, Immoter immoter, Sync motionLock) throws InvocationException {
+ return true;
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicater.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicater.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicater.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicater.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Replicater;
+
+public class DummyReplicater implements Replicater {
+
+ public boolean getReusingStore() {
+ return false;
+ }
+
+ public void create(Object tmp) {
+ // empty
+ }
+
+ public void update(Object tmp) { //TODO
+ // empty
+ }
+
+ public void destroy(Object tmp) { //TODO
+ // empty
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicaterFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicaterFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicaterFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyReplicaterFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,25 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+public class DummyReplicaterFactory extends StatelessReplicaterFactory {
+
+ public DummyReplicaterFactory() {
+ super(new DummyReplicater());
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRouter.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRouter.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRouter.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyRouter.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,74 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.Router;
+import org.codehaus.wadi.RouterConfig;
+
+public class DummyRouter implements Router {
+
+ protected RouterConfig _config;
+
+ public void init(RouterConfig config) {
+ _config=config;
+ }
+
+ public void destroy() {
+ _config=null;
+ }
+
+ public String strip(String session) {
+ return session;
+ }
+
+ public String augment(String session) {
+ return session;
+ }
+
+ public String getInfo() {
+ return "";
+ }
+
+ public boolean canReroute() {
+ return false;
+ }
+
+ public boolean reroute(InvocationContext invocationContext) {
+ return false;
+ }
+
+ public boolean rerouteCookie(HttpServletRequest req, HttpServletResponse res, String id) {
+ return false;
+ }
+
+ public boolean rerouteCookie(HttpServletRequest req, HttpServletResponse res, String id, String route) {
+ return false;
+ }
+
+ public boolean rerouteURL() {
+ return false;
+ }
+
+ public boolean rerouteURL(String target) {
+ return false;
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummySessionWrapperFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummySessionWrapperFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummySessionWrapperFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummySessionWrapperFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,28 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import javax.servlet.http.HttpSession;
+
+import org.codehaus.wadi.Session;
+import org.codehaus.wadi.SessionWrapperFactory;
+
+public class DummySessionWrapperFactory implements SessionWrapperFactory {
+
+ public HttpSession create(Session session) {return new SessionWrapper(session);}
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyStatefulHttpServletRequestWrapperPool.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyStatefulHttpServletRequestWrapperPool.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyStatefulHttpServletRequestWrapperPool.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/DummyStatefulHttpServletRequestWrapperPool.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,32 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.codehaus.wadi.PoolableInvocationWrapper;
+import org.codehaus.wadi.PoolableInvocationWrapperPool;
+
+public class DummyStatefulHttpServletRequestWrapperPool implements PoolableInvocationWrapperPool {
+
+ public PoolableInvocationWrapper take() {
+ return new StatefulHttpServletRequestWrapper();
+ }
+
+ public void put(PoolableInvocationWrapper wrapper) {
+ // just drop it...
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/ExclusiveStoreContextualiser.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/ExclusiveStoreContextualiser.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/ExclusiveStoreContextualiser.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/ExclusiveStoreContextualiser.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,141 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.io.File;
+import java.util.Map;
+
+import org.codehaus.wadi.Collapser;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.ContextualiserConfig;
+import org.codehaus.wadi.DistributableContextualiserConfig;
+import org.codehaus.wadi.Emoter;
+import org.codehaus.wadi.Evicter;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.Motable;
+import org.codehaus.wadi.Store;
+import org.codehaus.wadi.StoreMotable;
+import org.codehaus.wadi.Streamer;
+
+// TODO - a JDBC-based equivalent
+
+/**
+ * Maps id:File where file contains Context content...
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.5 $
+ */
+public class ExclusiveStoreContextualiser extends AbstractExclusiveContextualiser {
+
+ protected final Store _store;
+ protected final Immoter _immoter;
+ protected final Emoter _emoter;
+
+ public ExclusiveStoreContextualiser(Contextualiser next, Collapser collapser, boolean clean, Evicter evicter, Map map, Streamer streamer, File dir) throws Exception {
+ super(next, new CollapsingLocker(collapser), clean, evicter, map);
+ _store=new DiscStore(streamer, dir, true, false);
+ _immoter=new ExclusiveStoreImmoter(_map);
+ _emoter=new ExclusiveStoreEmoter(_map);
+ }
+
+ public void init(ContextualiserConfig config) {
+ super.init(config);
+ // perhaps this should be done in start() ?
+ if (_clean)
+ _store.clean();
+ }
+
+ public String getStartInfo() {
+ return "["+_store.getStartInfo()+"]";
+ }
+
+ public boolean isExclusive(){return true;}
+
+ public Immoter getImmoter(){return _immoter;}
+ public Emoter getEmoter(){return _emoter;}
+
+ /**
+ * An Immoter that deals in terms of StoreMotables
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.5 $
+ */
+ public class ExclusiveStoreImmoter extends AbstractMappedImmoter {
+
+ public ExclusiveStoreImmoter(Map map) {
+ super(map);
+ }
+
+ public Motable nextMotable(String name, Motable emotable) {
+ StoreMotable motable=_store.create();
+ motable.init(_store);
+ return motable; // TODO - Pool, maybe as ThreadLocal
+ }
+
+ public String getInfo() {
+ return _store.getDescription();
+ }
+ }
+
+ /**
+ * An Emmoter that deals in terms of StoreMotables
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.5 $
+ */
+ class ExclusiveStoreEmoter extends AbstractMappedEmoter {
+
+ public ExclusiveStoreEmoter(Map map) {super(map);}
+
+ public String getInfo(){return _store.getDescription();}
+ }
+
+ public void start() throws Exception {
+ Store.Putter putter=new Store.Putter() {
+ public void put(String name, Motable motable) {
+ _map.put(name, motable);
+ }
+ };
+ _store.load(putter, ((DistributableContextualiserConfig)_config).getAccessOnLoad());
+ super.start(); // continue down chain...
+ }
+
+ // this should move up.....
+ public void expire(Motable motable) {
+ // decide whether session needs promotion
+ boolean needsLoading=true; // FIXME
+ // if so promote to top and expire there
+ String id=motable.getName();
+ if (_log.isTraceEnabled()) _log.trace("expiring from disc: "+id);
+ if (needsLoading) {
+ _map.remove(id);
+ Motable loaded=_config.getSessionPool().take();
+ try {
+ loaded.copy(motable);
+ motable=null;
+ _config.expire(loaded);
+ } catch (Exception e) {
+ _log.error("unexpected problem expiring from disc", e);
+ }
+ loaded=null;
+ } else {
+ // else, just drop it off the disc here...
+ throw new UnsupportedOperationException(); // FIXME
+ }
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/Filter.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/Filter.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/Filter.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/Filter.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,140 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.InvocationException;
+import org.codehaus.wadi.PoolableInvocationWrapper;
+import org.codehaus.wadi.PoolableInvocationWrapperPool;
+import org.codehaus.wadi.Router;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
+
+public class Filter implements javax.servlet.Filter {
+
+ protected final Log _log = LogFactory.getLog(getClass());
+
+ protected StandardManager _manager;
+ protected boolean _distributable;
+ protected Contextualiser _contextualiser;
+ protected Router _router;
+ protected PoolableInvocationWrapperPool _pool=new DummyStatefulHttpServletRequestWrapperPool(); // TODO - init from _manager
+ protected boolean _errorIfSessionNotAcquired;
+ protected SynchronizedBoolean _acceptingSessions;
+
+ // Filter Lifecycle
+
+ public void
+ init(FilterConfig filterConfig) throws ServletException
+ {
+ _manager=(StandardManager)filterConfig.getServletContext().getAttribute(StandardManager.class.getName());
+ if (_manager==null)
+ _log.fatal("Manager not found");
+ else
+ if (_log.isInfoEnabled())_log.info("Manager found: "+_manager);
+
+ _manager.setFilter(this);
+ _distributable=_manager.getDistributable();
+ _contextualiser=_manager.getContextualiser();
+ _router=_manager.getRouter();
+ _errorIfSessionNotAcquired=_manager.getErrorIfSessionNotAcquired();
+ _acceptingSessions=_manager.getAcceptingSessions();
+ }
+
+ public void setManager(StandardManager manager) {
+ _manager=manager;
+ }
+
+ public void
+ destroy()
+ {
+ _pool=null;
+ _contextualiser=null;
+ _distributable=false;
+ _manager=null;
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ if (request instanceof HttpServletRequest)
+ doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);
+ else // this one is not HTTP - therefore it is and will remain, stateless - not for us...
+ chain.doFilter(request, response);
+ }
+
+ public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+ String sessionId=request.getRequestedSessionId();
+ if (_log.isTraceEnabled()) _log.trace("potentially stateful request: "+sessionId);
+
+ InvocationContext invocationContext = new WebInvocationContext(request, response, chain);
+
+ try {
+ if (sessionId==null) {
+ processSessionlessRequest(invocationContext);
+ } else {
+ // already associated with a session...
+ String name=_router.strip(sessionId); // strip off any routing info...
+ if (!_contextualiser.contextualise(invocationContext, name, null, null, false)) {
+ if (_log.isErrorEnabled()) _log.error("could not acquire session: " + name);
+ if (_errorIfSessionNotAcquired) // send the client a 503...
+ response.sendError(503, "session "+name+" is not known"); // TODO - should we allow custom error page ?
+ else // process request without session - it may create a new one...
+ processSessionlessRequest(invocationContext);
+ }
+ }
+ } catch (InvocationException e) {
+ Throwable throwable = e.getCause();
+ if (throwable instanceof IOException) {
+ throw (IOException) throwable;
+ } else if (throwable instanceof ServletException) {
+ throw (ServletException) throwable;
+ } else {
+ throw new ServletException(e);
+ }
+ }
+ }
+
+ public void processSessionlessRequest(InvocationContext invocationContext) throws InvocationException {
+ // are we accepting sessions ? - otherwise proxy to another node...
+ // sync point - expensive, but will only hit sessionless requests...
+ if (!_acceptingSessions.get()) {
+ // think about what to do here... proxy or error page ?
+ _log.warn("sessionless request has arived during shutdown - permitting");
+ // TODO
+ }
+
+ // no session yet - but may initiate one...
+ PoolableInvocationWrapper wrapper=_pool.take();
+ wrapper.init(invocationContext, null);
+ invocationContext.invoke(wrapper);
+ wrapper.destroy();
+ _pool.put(wrapper);
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/FixedWidthSessionIdFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/FixedWidthSessionIdFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/FixedWidthSessionIdFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/FixedWidthSessionIdFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,171 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.util.Random;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.SessionIdFactory;
+import org.codehaus.wadi.gridstate.PartitionMapper;
+
+public class FixedWidthSessionIdFactory implements SessionIdFactory, PartitionMapper {
+
+ protected final Log _log=LogFactory.getLog(getClass().getName());
+
+ public String create() {
+ int width=_keyLength;
+ char[] buffer=new char[width];
+
+ int offset=width-1;
+ while ((offset=encode(Math.abs(_random.nextLong()), _sectLength, buffer, offset))>=0);
+
+ return new String(buffer);
+ }
+
+ public int getSessionIdLength() {
+ return _keyLength+_divider.length+_partitionLength;
+ }
+
+ public void setSessionIdLength(int l) {
+ //_width=l-_divider.length-_partitionSize;
+ }
+
+ //protected final static char[] _defaultChars="0123456789".toCharArray();
+ protected final static char[] _defaultChars="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+
+ protected final char[] _divider="-".toCharArray();
+ //protected final char[] _divider="".toCharArray();
+ protected Random _random=new Random();
+ protected final int[] _lookup=new int[Character.MAX_VALUE];
+
+ protected final int _keyLength;
+ protected final char[] _chars;
+ protected final int _base;
+ protected final int _sectLength;
+ protected final int _numPartitions;
+ protected final int _partitionLength;
+
+ public FixedWidthSessionIdFactory(int width, int numPartitions) {
+ this(width, _defaultChars, numPartitions);
+ }
+
+ public FixedWidthSessionIdFactory(int width, char[] chars, int numPartitions) {
+ _keyLength=width;
+ _chars=chars;
+ _base=_chars.length;
+ _numPartitions=numPartitions;
+ _partitionLength=size(_numPartitions);
+
+ // System.out.println("radix="+_radix);
+ // initialise reverse lookup table...
+ for (int i=0; i<_base; i++)
+ _lookup[_chars[i]]=i;
+
+ // calculate how many digits max-long would render in the given
+ // base...
+ // System.out.println("max="+Long.MAX_VALUE);
+ _sectLength=size(Long.MAX_VALUE);
+ // System.out.println("iters="+_iters);
+ }
+
+ public String create(int partition) {
+ int width=_keyLength+_divider.length+_partitionLength;
+ char[] buffer=new char[width];
+
+ int offset=width-1;
+ offset=encode(partition, _partitionLength, buffer, offset);
+
+ for (int i=_divider.length-1; i>=0; i--)
+ buffer[offset--]=_divider[i];
+
+ while ((offset=encode(Math.abs(_random.nextLong()), _sectLength, buffer, offset))>=0);
+
+ return new String(buffer);
+ }
+
+ protected int encode(long sect, int iters, char[] buffer, int offset) {
+ for (int i=0; i<iters && offset>=0; i++) {
+ // System.out.println(""+i+" - "+source);
+ buffer[offset--]=_chars[(int)(sect%_base)];
+ sect/=_base;
+ }
+ return offset;
+ }
+
+ public int getPartition(String key) {
+ return decode(key.toCharArray(), key.length()-_partitionLength, _partitionLength);
+ }
+
+ protected int decode(char[] buffer, int from, int length) {
+ int result=0;
+ int multiplier=1;
+ for (int i=from+length-1; i>=from; i--) {
+ // System.out.println(""+buffer[i]+" - "+_lookup[buffer[i]]);
+ result+=_lookup[buffer[i]]*multiplier;
+ multiplier*=_base;
+ }
+ return result;
+ }
+
+ protected int size(long l) {
+ int i=0;
+ while (l!=0) {
+ l/=_base;
+ i++;
+ }
+ return i;
+ }
+
+ protected int size(int n) {
+ int i=0;
+ while (n!=0) {
+ n/=_base;
+ i++;
+ }
+ return i;
+ }
+
+ public static void main(String[] args) {
+ int numPartitions=1024;
+ FixedWidthSessionIdFactory factory=new FixedWidthSessionIdFactory(32, numPartitions);
+ Random r=new Random();
+ for (int i=0; i<numPartitions; i++) {
+ int partition=Math.abs(r.nextInt())%numPartitions;
+ String key=factory.create(partition);
+ System.out.println(key+" - "+partition);
+ assert partition==factory.getPartition(key);
+ }
+ }
+
+ // PartitionMapper API
+
+ public int map(Object key) {
+ int index=getPartition((String)key);
+ _log.info("mapped "+key+" -> "+index);
+ return index;
+ }
+
+ // should we shuffle the _chars used for the key ?
+ // cannot shuffle _chars for partition - since must be the same on every node
+ // rename name->key where dealing with sessions...
+
+ // when we allocate a session, we need to decide which partition to put it in
+ // allocation and entry into partition must be atomic - I guess the entry could chase the partition...
+
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GZIPStreamer.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GZIPStreamer.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GZIPStreamer.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GZIPStreamer.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,64 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import org.codehaus.wadi.Streamer;
+import org.codehaus.wadi.StreamerConfig;
+
+/**
+ * Pluggable support for [un]GZIP-ing sessions as they are exchanged with
+ * peers or long-term storage mechanisms.
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.2 $
+ */
+public class GZIPStreamer implements Streamer {
+
+ protected StreamerConfig _config;
+
+ public void init(StreamerConfig config) {
+ _config=config;
+ }
+
+ public ObjectInput getInputStream(InputStream is) throws IOException {
+ return new ObjectInputStream(new GZIPInputStream(is), _config.getClassLoader());
+ }
+
+ public ObjectOutput getOutputStream(OutputStream os) throws IOException {
+ return new ObjectOutputStream(new GZIPOutputStream(os));
+ }
+
+ public String getSuffix() {
+ return "gz";
+ }
+
+ public String getSuffixWithDot() {
+ return ".gz";
+ }
+
+}
+
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GiannisContextualiser.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GiannisContextualiser.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GiannisContextualiser.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/GiannisContextualiser.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,163 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.codehaus.wadi.Collapser;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.ContextualiserConfig;
+import org.codehaus.wadi.DistributableContextualiserConfig;
+import org.codehaus.wadi.Emoter;
+import org.codehaus.wadi.Evicter;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.Motable;
+import org.codehaus.wadi.Store;
+import org.codehaus.wadi.StoreMotable;
+
+/**
+ * Maps id:File where file contains Context content...
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.8 $
+ */
+public class GiannisContextualiser extends AbstractExclusiveContextualiser {
+
+ protected final Immoter _immoter;
+ protected final Emoter _emoter;
+ protected final DatabaseStore _store;
+
+ public GiannisContextualiser(Contextualiser next, Collapser collapser, boolean clean, Evicter evicter, Map map, DatabaseStore dbstore) throws Exception {
+ super(next, new CollapsingLocker(collapser), clean, evicter, map);
+ _immoter=new GiannisImmoter(_map);
+ _emoter=new GiannisEmoter(_map);
+ _store=dbstore;
+ }
+
+ public void init(ContextualiserConfig config) {
+ super.init(config);
+ // perhaps this should be done in start() ?
+ if (_clean)
+ _store.clean();
+ }
+
+ public String getStartInfo() {
+ return "["+_store.getLabel()+"/"+_store.getTable()+"] : "+_map.size()+" sessions loaded";
+ }
+
+ public boolean isExclusive(){
+ return true;
+ }
+
+ public Immoter getImmoter() {
+ return _immoter;
+ }
+
+ public Emoter getEmoter(){
+ return _emoter;
+ }
+
+ class GiannisImmoter extends AbstractMappedImmoter {
+
+ public GiannisImmoter(Map map) {
+ super(map);
+ }
+
+ public Motable nextMotable(String name, Motable emotable) {
+ StoreMotable motable=_store.create();
+ motable.init(_store);
+ return motable; // TODO - Pool, maybe as ThreadLocal
+ }
+
+ public String getInfo() {
+ return _store.getDescription();
+ }
+ }
+
+ class GiannisEmoter extends AbstractMappedEmoter {
+
+ public GiannisEmoter(Map map) {super(map);}
+
+ public String getInfo() {
+ return _store.getDescription();
+ }
+ }
+
+ public void start() throws Exception {
+ // TODO - consider moving into load...
+ Store.Putter putter=new Store.Putter() {
+ public void put(String name, Motable motable) {
+ _map.put(name, motable);
+ }
+ };
+ _store.load(putter, ((DistributableContextualiserConfig)_config).getAccessOnLoad());
+
+ super.start(); // continue down chain...
+ }
+
+ // this should move up.....
+ public void expire(Motable motable) {
+ // decide whether session needs promotion
+ boolean needsLoading=true; // FIXME
+ // if so promote to top and expire there
+ String id=motable.getName();
+ if (_log.isTraceEnabled()) _log.trace("expiring from store: "+id);
+ if (needsLoading) {
+ _map.remove(id);
+ Motable loaded=_config.getSessionPool().take();
+ Connection connection=null;
+ DatabaseMotable dbm=(DatabaseMotable)motable;
+ try {
+ connection=_store.getDataSource().getConnection();
+ dbm.setConnection(connection);
+ loaded.copy(dbm);
+ dbm.setConnection(null);
+ _config.expire(loaded);
+ } catch (Exception e) {
+ _log.error("unexpected problem expiring from store", e);
+ } finally {
+ if (connection!=null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ _log.warn("unexpected problem closing connection", e);
+ }
+ }
+ }
+ loaded=null;
+ } else {
+ // else, just drop it off the disc here...
+ throw new UnsupportedOperationException(); // FIXME
+ }
+ }
+
+ public void load(Emoter emoter, Immoter immoter) { // - TODO - is this where we should do our own load ?
+ // MappedContextualisers are all Exclusive
+ }
+
+ protected void unload() {
+ if (_log.isInfoEnabled()) _log.info("unloaded sessions: " + _map.size());
+ _map.clear();
+ }
+
+ public Immoter getSharedDemoter() {
+ return getImmoter();
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HashingCollapser.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HashingCollapser.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HashingCollapser.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HashingCollapser.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,59 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.Collapser;
+
+import EDU.oswego.cs.dl.util.concurrent.Mutex;
+import EDU.oswego.cs.dl.util.concurrent.Sync;
+import EDU.oswego.cs.dl.util.concurrent.TimeoutSync;
+
+/**
+ * A lock Collapser that collapses according to hash code
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.1 $
+ */
+public class HashingCollapser implements Collapser {
+ protected final Log _log = LogFactory.getLog(getClass());
+ protected final int _numSyncs;
+ protected final Sync[] _syncs;
+ protected final long _timeout;
+
+ /**
+ *
+ */
+ public HashingCollapser(int numSyncs, long timeout) {
+ super();
+ _numSyncs=numSyncs;
+ _timeout=timeout;
+ _syncs=new Sync[_numSyncs];
+ for (int i=0; i<_numSyncs; i++)
+ _syncs[i]=new TimeoutSync(new Mutex(), _timeout);
+ }
+
+ /* (non-Javadoc)
+ * @see org.codehaus.wadi.sandbox.context.Collapser#getLock(java.lang.String)
+ */
+ public Sync getLock(String id) {
+ int index=Math.abs(id.hashCode()%_numSyncs); // Jetty seems to generate negative session id hashcodes...
+ if (_log.isTraceEnabled()) _log.trace("collapsed "+id+" to index: "+index);
+ return _syncs[index];
+ }
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HttpProxyLocation.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HttpProxyLocation.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HttpProxyLocation.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HttpProxyLocation.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,64 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import javax.jms.Destination;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.InvocationProxy;
+import org.codehaus.wadi.Location;
+import org.codehaus.wadi.ProxiedLocation;
+import org.codehaus.wadi.ProxyingException;
+
+/**
+ * A Location that includes a hostname/ip-address and HTTP port
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.2 $
+ */
+
+public class HttpProxyLocation extends SimpleEvictable implements Location {
+
+ protected final static Log _log = LogFactory.getLog(HttpProxyLocation.class);
+
+ protected ProxiedLocation _location;
+ protected InvocationProxy _proxy;
+
+ public HttpProxyLocation(Destination destination, ProxiedLocation location, InvocationProxy proxy) {
+ super();
+ _destination=destination;
+ _location=location;
+ _proxy=proxy;
+ }
+
+ public void proxy(InvocationContext invocationContext) throws ProxyingException {
+ _proxy.proxy(_location, invocationContext);
+ }
+
+ public String toString() {
+ return "<HttpProxyLocation:"+_location+">"; // we could include proxy strategy here...
+ }
+
+ protected final Destination _destination;
+
+ public Destination getDestination() {
+ return _destination;
+ }
+
+}
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HybridRelocater.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HybridRelocater.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HybridRelocater.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/HybridRelocater.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,375 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ * 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.codehaus.wadi.impl;
+
+import java.nio.ByteBuffer;
+
+import javax.jms.JMSException;
+import javax.jms.ObjectMessage;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.Emoter;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.InvocationException;
+import org.codehaus.wadi.InvocationProxy;
+import org.codehaus.wadi.Motable;
+import org.codehaus.wadi.ProxiedLocation;
+import org.codehaus.wadi.RelocaterConfig;
+import org.codehaus.wadi.dindex.messages.RelocationAcknowledgement;
+import org.codehaus.wadi.dindex.messages.RelocationRequest;
+import org.codehaus.wadi.dindex.messages.RelocationResponse;
+import org.codehaus.wadi.gridstate.Dispatcher;
+
+import EDU.oswego.cs.dl.util.concurrent.Sync;
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
+import EDU.oswego.cs.dl.util.concurrent.TimeoutException;
+
+/**
+ * Combine various RelocationStrategies to produce a cleverer one
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.23 $
+ */
+public class HybridRelocater extends AbstractRelocater {
+
+ protected final Log _log=LogFactory.getLog(getClass());
+ protected final long _requestHandOverTimeout=2000;// TODO - parameterise
+ protected final long _resTimeout;
+ protected final long _ackTimeout;
+ protected final boolean _sessionOrRequestPreferred; // true if relocation of session is preferred to relocation of request
+ protected final Log _lockLog=LogFactory.getLog("org.codehaus.wadi.LOCKS");
+
+ public HybridRelocater(long resTimeout, long ackTimeout, boolean sessionOrRequestPreferred) {
+ _resTimeout=resTimeout;
+ _ackTimeout=ackTimeout;
+ _sessionOrRequestPreferred=sessionOrRequestPreferred;
+ }
+
+ protected SynchronizedBoolean _shuttingDown;
+ protected Dispatcher _dispatcher;
+ protected String _nodeName;
+ protected Contextualiser _contextualiser;
+ protected InvocationProxy _proxy;
+
+ public void init(RelocaterConfig config) {
+ super.init(config);
+ _shuttingDown=_config.getShuttingDown();
+ _dispatcher=_config.getDispatcher();
+ _nodeName=_config.getNodeName();
+ _contextualiser=_config.getContextualiser();
+ _proxy=_config.getInvocationProxy();
+ _dispatcher.register(this, "onMessage", RelocationRequest.class);
+ _dispatcher.register(RelocationResponse.class, _resTimeout);
+ _dispatcher.register(RelocationAcknowledgement.class, _ackTimeout);
+ }
+
+ public boolean relocate(InvocationContext invocationContext, String name, Immoter immoter, Sync motionLock) throws InvocationException {
+ String sessionName=name;
+ String nodeName=_config.getNodeName();
+ boolean shuttingDown=_shuttingDown.get();
+ int concurrentRequestThreads=1;
+ RelocationResponse response=null;
+ ObjectMessage message2=null;
+
+ boolean useGridState=false;
+
+ if (useGridState) {
+ Motable immotable=null;
+ try {
+ immotable=_config.getDIndex().relocate2(sessionName, nodeName, concurrentRequestThreads, shuttingDown, _resTimeout);
+ } catch (Exception e) {
+ _log.error("unexpected error", e);
+ }
+
+ if (null==immotable) {
+ return false;
+ } else {
+ boolean answer=immoter.contextualise(invocationContext, name, immotable, motionLock);
+ return answer;
+ }
+ } else {
+
+ try {
+ message2=_config.getDIndex().relocate(sessionName, nodeName, concurrentRequestThreads, shuttingDown, _resTimeout);
+ if (message2==null || (response=(RelocationResponse)message2.getObject())==null)
+ return false;
+ } catch (Exception e) {
+ _log.warn("problem arranging relocation", e);
+ }
+
+ Motable emotable=response.getMotable();
+ if (emotable!=null) {
+ // relocate session...
+ if (!emotable.checkTimeframe(System.currentTimeMillis()))
+ if (_log.isWarnEnabled()) _log.warn("immigrating session has come from the future!: "+emotable.getName());
+
+ Emoter emoter=new RelocationEmoter(response.getNodeName(), message2);
+ Motable immotable=Utils.mote(emoter, immoter, emotable, name);
+ if (null==immotable)
+ return false;
+ else {
+ boolean answer=immoter.contextualise(invocationContext, name, immotable, motionLock);
+ return answer;
+ }
+
+ }
+
+ ProxiedLocation location = response.getProxiedLocation();
+ if (location!=null) {
+ // relocate request...
+ try {
+ //FIXME - API should not be in terms of HttpProxy but in terms of RequestRelocater...
+
+ _proxy.proxy(location, invocationContext);
+ _log.trace("PROXY WAS SUCCESSFUL");
+ motionLock.release();
+ return true;
+ } catch (Exception e) {
+ _log.error("problem proxying request", e);
+ return false;
+ }
+ }
+
+ // if we are still here - session could not be found
+ if (_log.isWarnEnabled()) _log.warn("session not found: " + sessionName);
+ return false;
+ }
+ }
+
+ /* We send a RelocationRequest out to fetch a Session. We receive a RelocationResponse containing the Session. We pass a RelocationEmoter
+ * down the Contextualiser stack. It passes the incoming Session out to the relevant Contextualiser and sends a RelocationAcknowledgment
+ * back to the src of the RelocationResponse. (could be done in a Motable like Immoter?)
+ */
+
+ class RelocationEmoter extends AbstractChainedEmoter {
+ protected final Log _log=LogFactory.getLog(getClass());
+
+ protected final String _nodeName;
+ protected final ObjectMessage _message;
+
+ public RelocationEmoter(String nodeName, ObjectMessage message) {
+ _nodeName=nodeName;
+ _message=message;
+ }
+
+ public boolean prepare(String name, Motable emotable, Motable immotable) {
+ try {
+ immotable.copy(emotable);
+ } catch (Exception e) {
+ _log.warn(e);
+ return false;
+ }
+ _config.notifySessionRelocation(name);
+
+ // TODO - move some of this to prepare()...
+ if (_log.isTraceEnabled()) _log.trace("sending RelocationAcknowledgement");
+ RelocationAcknowledgement ack=new RelocationAcknowledgement();//(name, _config.getLocation());
+ if (!_config.getDispatcher().reply(_message, ack)) {
+ if (_log.isErrorEnabled()) _log.error("could not send RelocationAcknowledgement: "+name);
+ return false;
+ }
+
+ return true;
+ }
+
+ public void commit(String name, Motable emotable) {
+ try {
+ emotable.destroy(); // remove copy in store
+ } catch (Exception e) {
+ throw new UnsupportedOperationException("NYI"); // NYI
+ }
+ }
+
+ public void rollback(String name, Motable motable) {
+ throw new RuntimeException("NYI");
+ }
+
+ public String getInfo() {
+ return "immigration:"+_nodeName;
+ }
+ }
+
+ boolean getSessionOrRequestPreferred() {
+ return _sessionOrRequestPreferred;
+ // check out LB's capabilities during init()....
+ }
+
+ // the request arrives ...
+
+ public void onMessage(ObjectMessage om, RelocationRequest request) {
+ if (_log.isTraceEnabled()) _log.trace("RelocationRequest received from " + request.getNodeName() + " for " + request.getSessionName() + " on " + _nodeName);
+ // both of these may be out of date immediately... :-(
+ boolean theyAreShuttingDown=request.getShuttingDown();
+ boolean weAreShuttingDown=_shuttingDown.get();
+ boolean sessionOrRequestPreferred=_sessionOrRequestPreferred;
+
+ if (!theyAreShuttingDown && (weAreShuttingDown || sessionOrRequestPreferred)) {
+ relocateSessionToThem(om, request.getSessionName(), request.getNodeName());
+ return;
+ }
+
+ if (!weAreShuttingDown && (theyAreShuttingDown || !sessionOrRequestPreferred)) {
+ relocateRequestToUs(om, request.getSessionName());
+ return;
+ }
+
+ if (weAreShuttingDown && theyAreShuttingDown) {
+ // yikes !
+ // we need to relocate both session and request to a third, safe node
+ // think about it....
+ throw new UnsupportedOperationException("both source and target node are shutting down");
+ }
+ }
+
+ // response is to relocate session back to sender...
+
+ protected void relocateSessionToThem(ObjectMessage om, String sessionName, String nodeName) {
+ if (_log.isTraceEnabled()) _log.trace("relocating "+sessionName+" from "+_nodeName+" to "+nodeName);
+
+ Sync invocationLock=_config.getCollapser().getLock(sessionName);
+ boolean invocationLockAcquired=false;
+ try {
+ Utils.acquireUninterrupted("Invocation", sessionName, invocationLock);
+ invocationLockAcquired=true;
+ } catch (TimeoutException e) {
+ if (_log.isErrorEnabled()) _log.error("exclusive access could not be guaranteed within timeframe: "+sessionName, e);
+ return;
+ }
+
+ try {
+ // reverse direction...
+ Immoter promoter=new RelocationImmoter(nodeName, om);
+ RankedRWLock.setPriority(RankedRWLock.EMIGRATION_PRIORITY);
+ boolean found=_contextualiser.contextualise(null,sessionName, promoter, invocationLock, true); // if we own session, this will send the correct response...
+ if (found)
+ invocationLockAcquired=false; // someone else has released the promotion lock...
+ } catch (Exception e) {
+ if (_log.isWarnEnabled()) _log.warn("problem handling relocation request: "+sessionName, e);
+ } finally {
+ RankedRWLock.setPriority(RankedRWLock.NO_PRIORITY);
+ if (invocationLockAcquired) {
+ Utils.release("Invocation", sessionName, invocationLock);
+ }
+ }
+ // N.B. - I don't think it is necessary to acquire the motionLock - consider...
+ // TODO - if we see a LocationRequest for a session that we know is Dead - we should respond immediately.
+ }
+
+ class ClusterEmotable extends AbstractMotable {
+
+ protected final String _name;
+ protected final String _tgtNodeName;
+ protected ObjectMessage _message;
+
+ public ClusterEmotable(String name, String nodeName, ObjectMessage message) {
+ _name=name;
+ _tgtNodeName=nodeName;
+ _message=message;
+ }
+ public byte[] getBodyAsByteArray() throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setBodyAsByteArray(byte[] bytes) throws Exception {
+ // send the message
+ if (_log.isTraceEnabled()) _log.trace("sending RelocationResponse");
+ Motable immotable=new SimpleMotable();
+ immotable.setBodyAsByteArray(bytes);
+ RelocationResponse response=new RelocationResponse(_name, _nodeName, immotable);
+ ObjectMessage message=_dispatcher.exchangeReply(_message, response, _ackTimeout);
+ RelocationAcknowledgement ack=null;
+ ack=message==null?null:(RelocationAcknowledgement)message.getObject();
+
+ if (ack==null) {
+ if (_log.isWarnEnabled()) _log.warn("no ack received for session RelocationResponse"); // TODO - increment a counter somewhere...
+ // TODO - who owns the session now - consider a syn link to old owner to negotiate this..
+ throw new Exception("no ack received for session RelocationResponse");
+ }
+ if (_log.isTraceEnabled()) _log.trace("received relocation ack");
+ }
+
+ public ByteBuffer getBodyAsByteBuffer() throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setBodyAsByteBuffer(ByteBuffer body) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+ /**
+ * We receive a RelocationRequest and pass a RelocationImmoter down the Contextualiser stack. The Session is passed to us
+ * through the Immoter and we pass it back to the Request-ing node...
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.23 $
+ */
+ class RelocationImmoter implements Immoter {
+ protected final Log _log=LogFactory.getLog(getClass());
+
+ protected final String _tgtNodeName;
+ protected ObjectMessage _message;
+
+ public RelocationImmoter(String nodeName, ObjectMessage message) {
+ _tgtNodeName=nodeName;
+ _message=message;
+ }
+
+ public Motable nextMotable(String name, Motable emotable) {
+ return new ClusterEmotable(name, _tgtNodeName, _message);
+ }
+
+ public boolean prepare(String name, Motable emotable, Motable immotable) {
+ // work is done in ClusterEmotable...
+ return true;
+ }
+
+ public void commit(String name, Motable immotable) {
+ // do nothing
+ }
+
+ public void rollback(String name, Motable immotable) {
+ // this probably has to by NYI... - nasty...
+ }
+
+ public boolean contextualise(InvocationContext invocationContext, String id, Motable immotable, Sync motionLock) throws InvocationException {
+ return false;
+ }
+
+ public String getInfo() {
+ return "emigration:"+_tgtNodeName;
+ }
+ }
+
+ // response is to relocate http request from sender to us...
+
+ protected void relocateRequestToUs(ObjectMessage om, String sessionName) {
+ try {
+ String src=_config.getDIndex().getNodeName(om.getJMSReplyTo());
+ if (_log.isTraceEnabled()) _log.trace("arranging for request to be relocated - sending response to: " + src);
+ RelocationResponse response=new RelocationResponse(sessionName, _nodeName, _config.getProxiedLocation());
+ _config.getDispatcher().reply(om, response);
+ } catch (JMSException e) {
+ if (_log.isErrorEnabled()) _log.error("could not send RelocationResponse: "+sessionName, e);
+ }
+ }
+
+}