You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2015/12/29 22:11:01 UTC

[07/24] incubator-geode git commit: GEODE-14: Move GemFire Sessions module and relocate all packages to 'internal'

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/ListenerEventType.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/ListenerEventType.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/ListenerEventType.java
new file mode 100644
index 0000000..0060a89
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/ListenerEventType.java
@@ -0,0 +1,70 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.gemstone.gemfire.modules.session.internal.filter;
+
+/**
+ * Enumeration of all possible event types which can be listened for.
+ */
+public enum ListenerEventType {
+
+  /**
+   * HttpSessionAttributeListener
+   */
+  SESSION_ATTRIBUTE_ADDED,
+  SESSION_ATTRIBUTE_REMOVED,
+  SESSION_ATTRIBUTE_REPLACED,
+
+  /**
+   * HttpSessionBindingListener
+   */
+  SESSION_VALUE_BOUND,
+  SESSION_VALUE_UNBOUND,
+
+  /**
+   * HttpSessionListener
+   */
+  SESSION_CREATED,
+  SESSION_DESTROYED,
+
+  /**
+   * HttpSessionActivationListener
+   */
+  SESSION_WILL_ACTIVATE,
+  SESSION_DID_PASSIVATE,
+
+  /**
+   * ServletContextListener
+   */
+  SERVLET_CONTEXT_INITIALIZED,
+  SERVLET_CONTEXT_DESTROYED,
+
+  /**
+   * ServletContextAttributeListener
+   */
+  SERVLET_CONTEXT_ATTRIBUTE_ADDED,
+  SERVLET_CONTEXT_ATTRIBUTE_REMOVED,
+  SERVLET_CONTEXT_ATTRIBUTE_REPLACED,
+
+  /**
+   * ServletRequestListener
+   */
+  SERVLET_REQUEST_DESTROYED,
+  SERVLET_REQUEST_INITIALIZED,
+
+  /**
+   * ServletRequestAttributeListener
+   */
+  SERVLET_REQUEST_ATTRIBUTE_ADDED,
+  SERVLET_REQUEST_ATTRIBUTE_REMOVED,
+  SERVLET_REQUEST_ATTRIBUTE_REPLACED;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/SessionManager.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/SessionManager.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/SessionManager.java
new file mode 100644
index 0000000..a01c793
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/SessionManager.java
@@ -0,0 +1,101 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session.internal.filter;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * Interface to session management. This class would be responsible for creating
+ * new sessions.
+ */
+public interface SessionManager {
+
+  /**
+   * Start the manager possibly using the config passed in.
+   *
+   * @param config Config object specific to individual implementations.
+   * @param loader This is a hack. When the manager is started it wants to be
+   *               able to determine if the cache, which it would create, and
+   *               the filter which starts everything, are defined by the same
+   *               classloader. This is so that during shutdown, the manager can
+   *               decide whether or not to also stop the cache. This option
+   *               allows the filter's classloader to be passed in.
+   */
+  public void start(Object config, ClassLoader loader);
+
+  /**
+   * Stop the session manager and free up any resources.
+   */
+  public void stop();
+
+  /**
+   * Write the session to the region
+   *
+   * @param session the session to write
+   */
+  public void putSession(HttpSession session);
+
+  /**
+   * Return a session if it exists or null otherwise
+   *
+   * @param id The session id to attempt to retrieve
+   * @return a HttpSession object if a session was found otherwise null.
+   */
+  public HttpSession getSession(String id);
+
+  /**
+   * Create a new session, wrapping a container session.
+   *
+   * @param nativeSession
+   * @return the HttpSession object
+   */
+  public HttpSession wrapSession(HttpSession nativeSession);
+
+  /**
+   * Get the wrapped (GemFire) session from a native session id. This method
+   * would typically be used from within session/http event listeners which
+   * receive the original session id.
+   *
+   * @param nativeId
+   * @return the wrapped GemFire session which maps the native session
+   */
+  public HttpSession getWrappingSession(String nativeId);
+
+  /**
+   * Destroy the session associated with the given id.
+   *
+   * @param id The id of the session to destroy.
+   */
+  public void destroySession(String id);
+
+  /**
+   * Destroy the session associated with a given native session
+   *
+   * @param id the id of the native session
+   * @return the corresponding Gemfire session which wrapped the native session
+   * and was destroyed.
+   */
+  public String destroyNativeSession(String id);
+
+  /**
+   * Returns the cookie name used to hold the session id. By default this is
+   * JSESSIONID.
+   *
+   * @return the name of the cookie which contains the session id
+   */
+  public String getSessionCookieName();
+
+  /**
+   * Get the JVM Id - this is a unique string used internally to identify who
+   * last touched a session.
+   *
+   * @return the jvm id
+   */
+  public String getJvmId();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractDeltaSessionAttributes.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractDeltaSessionAttributes.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractDeltaSessionAttributes.java
new file mode 100644
index 0000000..096e63b
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractDeltaSessionAttributes.java
@@ -0,0 +1,97 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.Delta;
+import com.gemstone.gemfire.InvalidDeltaException;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This abstract class contains the structures and methods to handle delta
+ * updates to attributes.
+ */
+public abstract class AbstractDeltaSessionAttributes
+    extends AbstractSessionAttributes implements Delta {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(AbstractDeltaSessionAttributes.class.getName());
+
+  /**
+   * This map holds the updates to attributes
+   */
+  protected transient Map<String, DeltaEvent> deltas =
+      Collections.synchronizedMap(new HashMap<String, DeltaEvent>());
+
+  @Override
+  public boolean hasDelta() {
+    return true;
+  }
+
+  @Override
+  public void toDelta(DataOutput out) throws IOException {
+    out.writeInt(maxInactiveInterval);
+    out.writeLong(lastAccessedTime);
+
+    synchronized (deltas) {
+      DataSerializer.writeInteger(deltas.size(), out);
+      for (Map.Entry<String, DeltaEvent> e : deltas.entrySet()) {
+        DataSerializer.writeString(e.getKey(), out);
+        DataSerializer.writeObject(e.getValue(), out);
+      }
+      deltas.clear();
+    }
+
+    out.writeUTF(jvmOwnerId);
+  }
+
+  @Override
+  public void fromDelta(DataInput in)
+      throws IOException, InvalidDeltaException {
+    maxInactiveInterval = in.readInt();
+    lastAccessedTime = in.readLong();
+    Map<String, DeltaEvent> localDeltas = new HashMap<String, DeltaEvent>();
+    try {
+      int size = DataSerializer.readInteger(in);
+      for (int i = 0; i < size; i++) {
+        String key = DataSerializer.readString(in);
+        DeltaEvent evt = DataSerializer.readObject(in);
+        localDeltas.put(key, evt);
+      }
+    } catch (ClassNotFoundException ex) {
+      LOG.error("Unable to de-serialize delta events", ex);
+      return;
+    }
+
+    LOG.debug("Processing {} delta events for {}",
+        localDeltas.size(), session);
+    for (DeltaEvent e : localDeltas.values()) {
+      if (e.isUpdate()) {
+        attributes.put(e.getName(), e.getValue());
+        if (session.getNativeSession() != null) {
+          session.getNativeSession().setAttribute(e.getName(), e.getValue());
+        }
+      } else {
+        attributes.remove(e.getName());
+        if (session.getNativeSession() != null) {
+          session.getNativeSession().setAttribute(e.getName(), null);
+        }
+      }
+    }
+    jvmOwnerId = in.readUTF();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractSessionAttributes.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractSessionAttributes.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractSessionAttributes.java
new file mode 100644
index 0000000..b5effb4
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/AbstractSessionAttributes.java
@@ -0,0 +1,179 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.util.BlobHelper;
+import com.gemstone.gemfire.modules.session.internal.filter.GemfireHttpSession;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract implementation for attributes. Should be sub-classed to provide
+ * differing implementations for synchronous or delta propagation. The backing
+ * store used is defined by the session manager.
+ */
+public abstract class AbstractSessionAttributes implements SessionAttributes {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(AbstractSessionAttributes.class.getName());
+
+  /**
+   * Internal attribute store.
+   */
+  protected Map<String, Object> attributes =
+      Collections.synchronizedMap(new HashMap<String, Object>());
+
+  /**
+   * The session to which these attributes belong
+   */
+  protected transient GemfireHttpSession session;
+
+  /**
+   * The last accessed time
+   */
+  protected long lastAccessedTime;
+
+  /**
+   * The maximum inactive interval. Default is 1800 seconds.
+   */
+  protected int maxInactiveInterval = 60 * 30;
+
+  /**
+   * The JVM Id who last committed these attributes
+   */
+  protected String jvmOwnerId;
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void setSession(GemfireHttpSession session) {
+    this.session = session;
+  }
+
+  /**
+   * {@inheritDoc} The actual de-serialization of any domain objects is deferred
+   * until the point at which they are actually retrieved by the application
+   * layer.
+   */
+  @Override
+  public Object getAttribute(String name) {
+    Object value = attributes.get(name);
+
+    // If the value is a byte[] (meaning it came from the server),
+    // deserialize it and re-add it to attributes map before returning it.
+    if (value instanceof byte[]) {
+      try {
+        value = BlobHelper.deserializeBlob((byte[]) value);
+        attributes.put(name, value);
+      } catch (Exception iox) {
+        LOG.error("Attribute '" + name +
+            " contains a byte[] that cannot be deserialized due "
+            + "to the following exception", iox);
+      }
+    }
+
+    return value;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<String> getAttributeNames() {
+    return attributes.keySet();
+  }
+
+  /**
+   * {@inheritDoc} +
+   */
+  @Override
+  public void setMaxInactiveInterval(int interval) {
+    maxInactiveInterval = interval;
+  }
+
+  @Override
+  public int getMaxIntactiveInterval() {
+    return maxInactiveInterval;
+  }
+
+  @Override
+  public void setLastAccessedTime(long time) {
+    lastAccessedTime = time;
+  }
+
+  @Override
+  public long getLastAccessedTime() {
+    return lastAccessedTime;
+  }
+
+  /**
+   * {@inheritDoc} This method calls back into the session to flush the whole
+   * session including its attributes.
+   */
+  @Override
+  public void flush() {
+    session.putInRegion();
+  }
+
+  /**
+   * Use DeltaEvents to propagate the actual attribute data - DeltaEvents turn
+   * the values into byte arrays which means that the actual domain classes are
+   * not required on the server.
+   */
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    out.writeInt(maxInactiveInterval);
+    out.writeLong(lastAccessedTime);
+
+    synchronized (attributes) {
+      out.writeInt(attributes.size());
+      for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+        DeltaEvent delta = new DeltaEvent(true, entry.getKey(),
+            entry.getValue());
+        DataSerializer.writeObject(delta, out);
+      }
+    }
+
+    out.writeUTF(jvmOwnerId);
+  }
+
+  @Override
+  public void fromData(
+      DataInput in) throws IOException, ClassNotFoundException {
+    maxInactiveInterval = in.readInt();
+    lastAccessedTime = in.readLong();
+    int size = in.readInt();
+    while (size-- > 0) {
+      DeltaEvent event = DataSerializer.readObject(in);
+      attributes.put(event.getName(), event.getValue());
+    }
+    jvmOwnerId = in.readUTF();
+  }
+
+  @Override
+  public void setJvmOwnerId(String jvmId) {
+    this.jvmOwnerId = jvmId;
+  }
+
+  @Override
+  public String getJvmOwnerId() {
+    return jvmOwnerId;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaEvent.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaEvent.java
new file mode 100644
index 0000000..455ba59
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaEvent.java
@@ -0,0 +1,109 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.util.BlobHelper;
+import com.gemstone.gemfire.modules.session.internal.filter.GemfireHttpSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Capture the update to a particular name
+ */
+public class DeltaEvent implements DataSerializable {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(DeltaEvent.class.getName());
+  /**
+   * The event is either an update (true) or a remove (false)
+   */
+  private boolean update;
+
+  private String name;
+
+  private Object value = null;
+
+  private GemfireHttpSession session = null;
+
+  /**
+   * Constructor for de-serialization only
+   */
+  public DeltaEvent() {
+  }
+
+  /**
+   * Constructor which creates a 'deferred' event. This is used when the value
+   * should only be applied when the object is serialized.
+   *
+   * @param session   the session from which the value ultimately will be
+   *                  retrieved
+   * @param attribute the name of the attribute
+   */
+  public DeltaEvent(GemfireHttpSession session, String attribute) {
+    this.session = session;
+    this.name = attribute;
+    this.update = true;
+  }
+
+  public DeltaEvent(boolean update, String attribute, Object value) {
+    this.update = update;
+    this.name = attribute;
+    this.value = value;
+    blobifyValue();
+  }
+
+  private void blobifyValue() {
+    if (value instanceof byte[]) {
+      LOG.warn("Session attribute is already a byte[] - problems may "
+          + "occur transmitting this delta.");
+    }
+    try {
+      value = BlobHelper.serializeToBlob(value);
+    } catch (IOException iox) {
+      LOG.error("Attribute '" + name + "' value: " + value
+          + " cannot be serialized due to the following exception", iox);
+    }
+  }
+
+  public boolean isUpdate() {
+    return update;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Object getValue() {
+    return value;
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    if (session != null) {
+      value = session.getNativeSession().getAttribute(name);
+      blobifyValue();
+    }
+    out.writeBoolean(update);
+    DataSerializer.writeString(name, out);
+    DataSerializer.writeObject(value, out);
+  }
+
+  @Override
+  public void fromData(
+      DataInput in) throws IOException, ClassNotFoundException {
+    update = in.readBoolean();
+    name = DataSerializer.readString(in);
+    value = DataSerializer.readObject(in);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaQueuedSessionAttributes.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaQueuedSessionAttributes.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaQueuedSessionAttributes.java
new file mode 100644
index 0000000..0c8bd57
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaQueuedSessionAttributes.java
@@ -0,0 +1,84 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.Instantiator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements delayed attribute delta propagation. Updates to
+ * attributes are only propagated once the session goes out of scope - i.e. as
+ * the request is done being processed.
+ */
+public class DeltaQueuedSessionAttributes extends AbstractDeltaSessionAttributes {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(DeltaQueuedSessionAttributes.class.getName());
+
+  private Trigger trigger = Trigger.SET;
+
+  private enum Trigger {
+    SET,
+    SET_AND_GET;
+  }
+
+  /**
+   * Register ourselves for de-serialization
+   */
+  static {
+    Instantiator.register(
+        new Instantiator(DeltaQueuedSessionAttributes.class, 3479) {
+          @Override
+          public DataSerializable newInstance() {
+            return new DeltaQueuedSessionAttributes();
+          }
+        });
+  }
+
+  /**
+   * Default constructor
+   */
+  public DeltaQueuedSessionAttributes() {
+  }
+
+  public void setReplicationTrigger(String trigger) {
+    this.trigger = Trigger.valueOf(trigger.toUpperCase());
+  }
+
+  @Override
+  public Object getAttribute(String attr) {
+    if (trigger == Trigger.SET_AND_GET) {
+      deltas.put(attr, new DeltaEvent(session, attr));
+    }
+    return super.getAttribute(attr);
+  }
+
+  /**
+   * {@inheritDoc} Put an attribute, setting the dirty flag. The changes are
+   * flushed at the end of filter processing.
+   */
+  @Override
+  public Object putAttribute(String attr, Object value) {
+    Object obj = attributes.put(attr, value);
+    deltas.put(attr, new DeltaEvent(true, attr, value));
+    return obj;
+  }
+
+  /**
+   * {@inheritDoc} Remove an attribute, setting the dirty flag. The changes are
+   * flushed at the end of filter processing.
+   */
+  @Override
+  public Object removeAttribute(String attr) {
+    Object obj = attributes.remove(attr);
+    deltas.put(attr, new DeltaEvent(false, attr, null));
+    return obj;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaSessionAttributes.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaSessionAttributes.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaSessionAttributes.java
new file mode 100644
index 0000000..0c11c46
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/DeltaSessionAttributes.java
@@ -0,0 +1,65 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.Instantiator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements synchronous attribute delta propagation. Updates to
+ * attributes are immediately propagated.
+ */
+public class DeltaSessionAttributes extends AbstractDeltaSessionAttributes {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(DeltaSessionAttributes.class.getName());
+
+  /**
+   * Register ourselves for de-serialization
+   */
+  static {
+    Instantiator.register(new Instantiator(DeltaSessionAttributes.class, 347) {
+      @Override
+      public DataSerializable newInstance() {
+        return new DeltaSessionAttributes();
+      }
+    });
+  }
+
+  /**
+   * Default constructor
+   */
+  public DeltaSessionAttributes() {
+  }
+
+  /**
+   * {@inheritDoc} Put an attribute, setting the dirty flag and immediately
+   * flushing the delta queue.
+   */
+  @Override
+  public Object putAttribute(String attr, Object value) {
+    Object obj = attributes.put(attr, value);
+    deltas.put(attr, new DeltaEvent(true, attr, value));
+    flush();
+    return obj;
+  }
+
+  /**
+   * {@inheritDoc} Remove an attribute, setting the dirty flag and immediately
+   * flushing the delta queue.
+   */
+  @Override
+  public Object removeAttribute(String attr) {
+    Object obj = attributes.remove(attr);
+    deltas.put(attr, new DeltaEvent(false, attr, null));
+    flush();
+    return obj;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/ImmediateSessionAttributes.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/ImmediateSessionAttributes.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/ImmediateSessionAttributes.java
new file mode 100644
index 0000000..8bde765
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/ImmediateSessionAttributes.java
@@ -0,0 +1,58 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.Instantiator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements immediately transmitted attributes. All attributes are
+ * transmitted for every attribute update. This is bound to be a performance hit
+ * in some cases but ensures much higher data availability.
+ */
+public class ImmediateSessionAttributes extends AbstractSessionAttributes {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(ImmediateSessionAttributes.class.getName());
+
+  /**
+   * Register ourselves for de-serialization
+   */
+  static {
+    Instantiator.register(
+        new Instantiator(ImmediateSessionAttributes.class, 347) {
+          @Override
+          public DataSerializable newInstance() {
+            return new ImmediateSessionAttributes();
+          }
+        });
+  }
+
+  /**
+   * Default constructor
+   */
+  public ImmediateSessionAttributes() {
+  }
+
+  @Override
+  public Object putAttribute(String attr, Object value) {
+    Object obj = attributes.put(attr, value);
+    flush();
+    return obj;
+  }
+
+  @Override
+  public Object removeAttribute(String attr) {
+    Object obj = attributes.remove(attr);
+    flush();
+    return obj;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/QueuedSessionAttributes.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/QueuedSessionAttributes.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/QueuedSessionAttributes.java
new file mode 100644
index 0000000..85d19ab
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/QueuedSessionAttributes.java
@@ -0,0 +1,55 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.Instantiator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements an attribute container which delays sending updates
+ * until the session goes out of scope. All attributes are transmitted during
+ * the update.
+ */
+public class QueuedSessionAttributes extends AbstractSessionAttributes {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(QueuedSessionAttributes.class.getName());
+
+  /**
+   * Register ourselves for de-serialization
+   */
+  static {
+    Instantiator.register(new Instantiator(QueuedSessionAttributes.class, 347) {
+      @Override
+      public DataSerializable newInstance() {
+        return new QueuedSessionAttributes();
+      }
+    });
+  }
+
+  /**
+   * Default constructor
+   */
+  public QueuedSessionAttributes() {
+  }
+
+  @Override
+  public Object putAttribute(String attr, Object value) {
+    Object obj = attributes.put(attr, value);
+    return obj;
+  }
+
+  @Override
+  public Object removeAttribute(String attr) {
+    Object obj = attributes.remove(attr);
+    return obj;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/SessionAttributes.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/SessionAttributes.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/SessionAttributes.java
new file mode 100644
index 0000000..cf16e14
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/attributes/SessionAttributes.java
@@ -0,0 +1,111 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session.internal.filter.attributes;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.modules.session.internal.filter.GemfireHttpSession;
+
+import java.util.Set;
+
+/**
+ * Interface for session attribute storage. In reality, this interface is
+ * responsible for anything, in the session which needs to be propagated for
+ * caching - as such it also includes other 'attributes' such as
+ * maxInactiveInterval and lastAccessedTime
+ */
+public interface SessionAttributes extends DataSerializable {
+
+  /**
+   * Set the session to which these attributes belong.
+   *
+   * @param session the session to set
+   */
+  public void setSession(GemfireHttpSession session);
+
+  /**
+   * Set an attribute value.
+   *
+   * @param attr  the name of the attribute to set
+   * @param value the value for the attribute
+   * @return the value object
+   */
+  public Object putAttribute(String attr, Object value);
+
+  /**
+   * Retrieve an attribute's value.
+   *
+   * @param attr the name of the attribute
+   * @return the object associated with the attribute or null if none exists.
+   */
+  public Object getAttribute(String attr);
+
+  /**
+   * Remove the named attribute.
+   *
+   * @param attr the name of the attribute to remove
+   * @return the value of the attribute removed or null if the named attribute
+   * did not exist.
+   */
+  public Object removeAttribute(String attr);
+
+  /**
+   * Return a set of all attribute names.
+   *
+   * @return a set of all attribute names
+   */
+  public Set<String> getAttributeNames();
+
+  /**
+   * Set the max inactive interval for replication to other systems
+   *
+   * @param interval the time interval in seconds
+   */
+  public void setMaxInactiveInterval(int interval);
+
+  /**
+   * Retrieve the max inactive interval
+   *
+   * @return the max inactive interval in seconds
+   */
+  public int getMaxIntactiveInterval();
+
+  /**
+   * Set the last accessed time for replication to other systems
+   *
+   * @param time the last accessed time in milliseconds
+   */
+  public void setLastAccessedTime(long time);
+
+  /**
+   * Return the last accessed time in milliseconds
+   *
+   * @return the last accessed time
+   */
+  public long getLastAccessedTime();
+
+  /**
+   * Explicitly flush the attributes to backing store.
+   */
+  public void flush();
+
+  /**
+   * Return the last jvm which 'owned' these attributes
+   *
+   * @return the jvmId
+   */
+  public String getJvmOwnerId();
+
+  /**
+   * Set the jvmId. This is set every time the attributes are flushed to the
+   * cache.
+   *
+   * @param jvmId
+   */
+  public void setJvmOwnerId(String jvmId);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/NamedThreadFactory.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/NamedThreadFactory.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/NamedThreadFactory.java
new file mode 100644
index 0000000..4771f76
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/NamedThreadFactory.java
@@ -0,0 +1,59 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session.internal.filter.util;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Factory to create named threads for easy identification at runtime.
+ */
+public class NamedThreadFactory implements ThreadFactory {
+
+  private static final Logger LOG = Logger.getLogger(
+      NamedThreadFactory.class.getName());
+
+  private final String id;
+
+  private final AtomicLong serial = new AtomicLong();
+
+  /**
+   * Create a new thread factory, using the specified pool ID as a basis for
+   * naming each thread.
+   *
+   * @param poolID pool name/ID
+   */
+  public NamedThreadFactory(final String poolID) {
+    id = poolID;
+  }
+
+  /**
+   * {@inheritDoc}
+   * <p/>
+   * This implementation sets the name of the thread, sets the thread to be a
+   * daemon thread, and adds an uncaught exception handler.
+   */
+  @Override
+  public Thread newThread(Runnable r) {
+    Thread thr = new Thread(r);
+    thr.setDaemon(true);
+    thr.setName(id + " - " + serial.incrementAndGet());
+    thr.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+      @Override
+      public void uncaughtException(Thread t, Throwable e) {
+        LOG.log(Level.WARNING,
+            "Uncaught Exception in thread: " + t.getName(), e);
+      }
+    });
+    return thr;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/ThreadLocalSession.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/ThreadLocalSession.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/ThreadLocalSession.java
new file mode 100644
index 0000000..c0bc625
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/ThreadLocalSession.java
@@ -0,0 +1,29 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.internal.filter.util;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ */
+public class ThreadLocalSession {
+  private static ThreadLocal<HttpSession> threadLocal =
+      new ThreadLocal<HttpSession>();
+
+  public static HttpSession get() {
+    return threadLocal.get();
+  }
+
+  public static void set(HttpSession session) {
+    threadLocal.set(session);
+  }
+
+  public static void remove() {
+    threadLocal.remove();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/TypeAwareMap.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/TypeAwareMap.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/TypeAwareMap.java
new file mode 100644
index 0000000..e65245b
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/filter/util/TypeAwareMap.java
@@ -0,0 +1,45 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.gemstone.gemfire.modules.session.internal.filter.util;
+
+import com.gemstone.gemfire.modules.session.internal.common.CacheProperty;
+
+import java.util.HashMap;
+
+/**
+ *
+ */
+public class TypeAwareMap<K extends CacheProperty, Object> extends HashMap {
+
+  private Class<K> keyType;
+
+  public TypeAwareMap(Class<K> keyType) {
+    super();
+    this.keyType = keyType;
+  }
+
+  public Object put(K key, Object value) {
+    if (!key.getClazz().isAssignableFrom(value.getClass())) {
+      if (key.getClazz() == Boolean.class) {
+        return (Object) super.put(key, Boolean.valueOf((String) value));
+      } else if (key.getClazz() == Integer.class) {
+        return (Object) super.put(key, Integer.valueOf((String) value));
+      } else {
+        throw new IllegalArgumentException("Value is not of type " +
+            key.getClazz().getName());
+      }
+    }
+
+    return (Object) super.put(key, value);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatistics.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatistics.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatistics.java
new file mode 100644
index 0000000..0119e06
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatistics.java
@@ -0,0 +1,69 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session.internal.jmx;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Class to manage session statistics
+ */
+public class SessionStatistics implements SessionStatisticsMXBean {
+
+  private AtomicInteger activeSessions = new AtomicInteger(0);
+
+  private AtomicInteger totalSessions = new AtomicInteger(0);
+
+  private AtomicLong regionUpdates = new AtomicLong(0);
+
+  @Override
+  public int getActiveSessions() {
+    return activeSessions.get();
+  }
+
+  @Override
+  public int getTotalSessions() {
+    return totalSessions.get();
+  }
+
+  @Override
+  public long getRegionUpdates() {
+    return regionUpdates.get();
+  }
+
+  public void setActiveSessions(int sessions) {
+    activeSessions.set(sessions);
+  }
+
+  public void setTotalSessions(int sessions) {
+    totalSessions.set(sessions);
+  }
+
+  public void incActiveSessions() {
+    activeSessions.incrementAndGet();
+    totalSessions.incrementAndGet();
+  }
+
+  public void decActiveSessions() {
+    activeSessions.decrementAndGet();
+  }
+
+  public void incTotalSessions() {
+    totalSessions.incrementAndGet();
+  }
+
+  public void decTotalSessions() {
+    totalSessions.decrementAndGet();
+  }
+
+  public void incRegionUpdates() {
+    regionUpdates.incrementAndGet();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatisticsMXBean.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatisticsMXBean.java b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatisticsMXBean.java
new file mode 100644
index 0000000..a468320
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/internal/jmx/SessionStatisticsMXBean.java
@@ -0,0 +1,14 @@
+
+package com.gemstone.gemfire.modules.session.internal.jmx;
+
+/**
+ * MXBean interface to retrieve Session statistics
+ */
+public interface SessionStatisticsMXBean {
+
+  public int getActiveSessions();
+
+  public int getTotalSessions();
+
+  public long getRegionUpdates();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/extensions/gemfire-modules-session/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-session/src/test/resources/log4j.properties b/extensions/gemfire-modules-session/src/test/resources/log4j.properties
new file mode 100644
index 0000000..b346714
--- /dev/null
+++ b/extensions/gemfire-modules-session/src/test/resources/log4j.properties
@@ -0,0 +1,12 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionCachingFilter.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionCachingFilter.java b/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionCachingFilter.java
deleted file mode 100644
index 191eb49..0000000
--- a/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionCachingFilter.java
+++ /dev/null
@@ -1,639 +0,0 @@
-/*=========================================================================
- * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
- * This product is protected by U.S. and international copyright
- * and intellectual property laws. Pivotal products are covered by
- * one or more patents listed at http://www.pivotal.io/patents.
- *=========================================================================
- */
-package com.gemstone.gemfire.modules.session.filter;
-
-import com.gemstone.gemfire.modules.session.filter.util.ThreadLocalSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-import javax.servlet.http.HttpSession;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.security.Principal;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Primary class which orchestrates everything. This is the class which gets
- * configured in the web.xml.
- */
-public class SessionCachingFilter implements Filter {
-
-  /**
-   * Logger instance
-   */
-  private static final Logger LOG =
-      LoggerFactory.getLogger(SessionCachingFilter.class.getName());
-
-  /**
-   * The filter configuration object we are associated with.  If this value is
-   * null, this filter instance is not currently configured.
-   */
-  private FilterConfig filterConfig = null;
-
-  /**
-   * Some containers will want to instantiate multiple instances of this filter,
-   * but we only need one SessionManager
-   */
-  private static SessionManager manager = null;
-
-  /**
-   * Can be overridden during testing.
-   */
-  private static AtomicInteger started =
-      new AtomicInteger(
-          Integer.getInteger("gemfire.override.session.manager.count", 1));
-
-  private static int percentInactiveTimeTriggerRebuild =
-      Integer.getInteger("gemfire.session.inactive.trigger.rebuild", 80);
-
-  /**
-   * This latch ensures that at least one thread/instance has fired up the
-   * session manager before any other threads complete the init method.
-   */
-  private static CountDownLatch startingLatch = new CountDownLatch(1);
-
-  /**
-   * This request wrapper class extends the support class
-   * HttpServletRequestWrapper, which implements all the methods in the
-   * HttpServletRequest interface, as delegations to the wrapped request. You
-   * only need to override the methods that you need to change. You can get
-   * access to the wrapped request using the method getRequest()
-   */
-  public static class RequestWrapper extends HttpServletRequestWrapper {
-
-    private static final String URL_SESSION_IDENTIFIER = ";jsessionid=";
-
-    private ResponseWrapper response;
-
-    private boolean sessionFromCookie = false;
-
-    private boolean sessionFromURL = false;
-
-    private String requestedSessionId = null;
-
-    private GemfireHttpSession session = null;
-
-    private SessionManager manager;
-
-    private HttpServletRequest outerRequest = null;
-
-    /**
-     * Need to save this in case we need the original {@code RequestDispatcher}
-     */
-    private HttpServletRequest originalRequest;
-
-    public RequestWrapper(SessionManager manager,
-        HttpServletRequest request,
-        ResponseWrapper response) {
-
-      super(request);
-      this.response = response;
-      this.manager = manager;
-      this.originalRequest = request;
-
-      final Cookie[] cookies = request.getCookies();
-      if (cookies != null) {
-        for (final Cookie cookie : cookies) {
-          if (cookie.getName().equalsIgnoreCase(
-              manager.getSessionCookieName()) &&
-              cookie.getValue().endsWith("-GF")) {
-            requestedSessionId = cookie.getValue();
-            sessionFromCookie = true;
-
-            LOG.debug("Cookie contains sessionId: {}",
-                requestedSessionId);
-          }
-        }
-      }
-
-      if (requestedSessionId == null) {
-        requestedSessionId = extractSessionId();
-        LOG.debug("Extracted sessionId from URL {}", requestedSessionId);
-        if (requestedSessionId != null) {
-          sessionFromURL = true;
-        }
-      }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public HttpSession getSession() {
-      return getSession(true);
-    }
-
-    /**
-     * Create our own sessions. TODO: Handle invalidated sessions
-     *
-     * @return a HttpSession
-     */
-    @Override
-    public HttpSession getSession(boolean create) {
-      if (session != null && session.isValid()) {
-        session.setIsNew(false);
-        session.updateAccessTime();
-                /*
-                 * This is a massively gross hack. Currently, there is no way
-                 * to actually update the last accessed time for a session, so
-                 * what we do here is once we're into X% of the session's TTL
-                 * we grab a new session from the container.
-                 *
-                 * (inactive * 1000) * (pct / 100) ==> (inactive * 10 * pct)
-                 */
-        if (session.getLastAccessedTime() - session.getCreationTime() >
-            (session.getMaxInactiveInterval() * 10 * percentInactiveTimeTriggerRebuild)) {
-          HttpSession nativeSession = super.getSession();
-          session.failoverSession(nativeSession);
-        }
-        return session;
-      }
-
-      if (requestedSessionId != null) {
-        session = (GemfireHttpSession) manager.getSession(
-            requestedSessionId);
-        if (session != null) {
-          session.setIsNew(false);
-          // This means we've failed over to another node
-          if (session.getNativeSession() == null) {
-            try {
-              ThreadLocalSession.set(session);
-              HttpSession nativeSession = super.getSession();
-              session.failoverSession(nativeSession);
-              session.putInRegion();
-            } finally {
-              ThreadLocalSession.remove();
-            }
-          }
-        }
-      }
-
-      if (session == null || !session.isValid()) {
-        if (create) {
-          try {
-            session = (GemfireHttpSession) manager.wrapSession(null);
-            ThreadLocalSession.set(session);
-            HttpSession nativeSession = super.getSession();
-            if (session.getNativeSession() == null) {
-              session.setNativeSession(nativeSession);
-            } else {
-              assert (session.getNativeSession() == nativeSession);
-            }
-            session.setIsNew(true);
-            manager.putSession(session);
-          } finally {
-            ThreadLocalSession.remove();
-          }
-        } else {
-          // create is false, and session is either null or not valid.
-          // The spec says return a null:
-          return null;
-        }
-      }
-
-      if (session != null) {
-        addSessionCookie(response);
-        session.updateAccessTime();
-      }
-
-      return session;
-    }
-
-    private void addSessionCookie(HttpServletResponse response) {
-      // Don't bother if the response is already committed
-      if (response.isCommitted()) {
-        return;
-      }
-
-      // Get the existing cookies
-      Cookie[] cookies = getCookies();
-
-      Cookie cookie = new Cookie(manager.getSessionCookieName(),
-          session.getId());
-      cookie.setPath("".equals(getContextPath()) ? "/" : getContextPath());
-      // Clear out all old cookies and just set ours
-      response.addCookie(cookie);
-
-      // Replace all other cookies which aren't JSESSIONIDs
-      if (cookies != null) {
-        for (Cookie c : cookies) {
-          if (manager.getSessionCookieName().equals(c.getName())) {
-            continue;
-          }
-          response.addCookie(c);
-        }
-      }
-
-    }
-
-    private String getCookieString(Cookie c) {
-      StringBuilder cookie = new StringBuilder();
-      cookie.append(c.getName()).append("=").append(c.getValue());
-
-      if (c.getPath() != null) {
-        cookie.append("; ").append("Path=").append(c.getPath());
-      }
-      if (c.getDomain() != null) {
-        cookie.append("; ").append("Domain=").append(c.getDomain());
-      }
-      if (c.getSecure()) {
-        cookie.append("; ").append("Secure");
-      }
-
-      cookie.append("; HttpOnly");
-
-      return cookie.toString();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isRequestedSessionIdFromCookie() {
-      return sessionFromCookie;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isRequestedSessionIdFromURL() {
-      return sessionFromURL;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getRequestedSessionId() {
-      if (requestedSessionId != null) {
-        return requestedSessionId;
-      } else {
-        return super.getRequestedSessionId();
-      }
-    }
-
-        /*
-         * Hmmm... not sure if this is right or even good to do. So, in some
-         * cases - for ex. using a Spring security filter, we have 3 possible
-         * wrappers to deal with - the original, this one and one created by
-         * Spring. When a servlet or JSP is forwarded to the original request
-         * is passed in, but then this (the wrapped) request is used by the JSP.
-         * In some cases, the outer wrapper also contains information relevant
-         * to the request - in this case security info. So here we allow access
-         * to that. There's probably a better way....
-         */
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Principal getUserPrincipal() {
-      if (outerRequest != null) {
-        return outerRequest.getUserPrincipal();
-      } else {
-        return super.getUserPrincipal();
-      }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getRemoteUser() {
-      if (outerRequest != null) {
-        return outerRequest.getRemoteUser();
-      } else {
-        return super.getRemoteUser();
-      }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isUserInRole(String role) {
-      if (outerRequest != null) {
-        return outerRequest.isUserInRole(role);
-      } else {
-        return super.isUserInRole(role);
-      }
-    }
-
-    //////////////////////////////////////////////////////////////
-    // Non-API methods
-
-    void setOuterWrapper(HttpServletRequest outer) {
-      this.outerRequest = outer;
-    }
-
-    //////////////////////////////////////////////////////////////
-    // Private methods
-    private String extractSessionId() {
-      final int prefix = getRequestURL().indexOf(URL_SESSION_IDENTIFIER);
-      if (prefix != -1) {
-        final int start = prefix + URL_SESSION_IDENTIFIER.length();
-        int suffix = getRequestURL().indexOf("?", start);
-        if (suffix < 0) {
-          suffix = getRequestURL().indexOf("#", start);
-        }
-        if (suffix <= prefix) {
-          return getRequestURL().substring(start);
-        }
-        return getRequestURL().substring(start, suffix);
-      }
-      return null;
-    }
-  }
-
-  /**
-   * This response wrapper class extends the support class
-   * HttpServletResponseWrapper, which implements all the methods in the
-   * HttpServletResponse interface, as delegations to the wrapped response. You
-   * only need to override the methods that you need to change. You can get
-   * access to the wrapped response using the method getResponse()
-   */
-  class ResponseWrapper extends HttpServletResponseWrapper {
-
-    HttpServletResponse originalResponse;
-
-    public ResponseWrapper(HttpServletResponse response) throws IOException {
-      super(response);
-      originalResponse = response;
-    }
-
-    public HttpServletResponse getOriginalResponse() {
-      return originalResponse;
-    }
-
-    @Override
-    public void setHeader(String name, String value) {
-      super.setHeader(name, value);
-    }
-
-    @Override
-    public void setIntHeader(String name, int value) {
-      super.setIntHeader(name, value);
-    }
-  }
-
-
-  public SessionCachingFilter() {
-  }
-
-  /**
-   * @param request  The servlet request we are processing
-   * @param response The servlet response we are creating
-   * @param chain    The filter chain we are processing
-   * @throws IOException      if an input/output error occurs
-   * @throws ServletException if a servlet error occurs
-   */
-  @Override
-  public void doFilter(ServletRequest request, ServletResponse response,
-      FilterChain chain)
-      throws IOException, ServletException {
-
-    HttpServletRequest httpReq = (HttpServletRequest) request;
-    HttpServletResponse httpResp = (HttpServletResponse) response;
-
-    /**
-     * Early out if this isn't the right kind of request. We might see a
-     * RequestWrapper instance during a forward or include request.
-     */
-    if (request instanceof RequestWrapper ||
-        !(request instanceof HttpServletRequest)) {
-      LOG.debug("Handling already-wrapped request");
-      chain.doFilter(request, response);
-      return;
-    }
-
-    // Create wrappers for the request and response objects.
-    // Using these, you can extend the capabilities of the
-    // request and response, for example, allow setting parameters
-    // on the request before sending the request to the rest of the filter chain,
-    // or keep track of the cookies that are set on the response.
-    //
-    // Caveat: some servers do not handle wrappers very well for forward or
-    // include requests.
-
-    ResponseWrapper wrappedResponse = new ResponseWrapper(httpResp);
-    final RequestWrapper wrappedRequest =
-        new RequestWrapper(manager, httpReq, wrappedResponse);
-
-    Throwable problem = null;
-
-    try {
-      chain.doFilter(wrappedRequest, wrappedResponse);
-    } catch (Throwable t) {
-      // If an exception is thrown somewhere down the filter chain,
-      // we still want to execute our after processing, and then
-      // rethrow the problem after that.
-      problem = t;
-      LOG.error("Exception processing filter chain", t);
-    }
-
-    GemfireHttpSession session =
-        (GemfireHttpSession) wrappedRequest.getSession(false);
-
-    // If there was a problem, we want to rethrow it if it is
-    // a known type, otherwise log it.
-    if (problem != null) {
-      if (problem instanceof ServletException) {
-        throw (ServletException) problem;
-      }
-      if (problem instanceof IOException) {
-        throw (IOException) problem;
-      }
-      sendProcessingError(problem, response);
-    }
-
-    /**
-     * Commit any updates. What actually happens at that point is
-     * dependent on the type of attributes defined for use by the sessions.
-     */
-    if (session != null) {
-      session.commit();
-    }
-  }
-
-  /**
-   * Return the filter configuration object for this filter.
-   */
-  public FilterConfig getFilterConfig() {
-    return (this.filterConfig);
-  }
-
-  /**
-   * Set the filter configuration object for this filter.
-   *
-   * @param filterConfig The filter configuration object
-   */
-  public void setFilterConfig(FilterConfig filterConfig) {
-    this.filterConfig = filterConfig;
-  }
-
-  /**
-   * Destroy method for this filter
-   */
-  @Override
-  public void destroy() {
-    if (manager != null) {
-      manager.stop();
-    }
-  }
-
-  /**
-   * This is where all the initialization happens.
-   *
-   * @param config
-   * @throws ServletException
-   */
-  @Override
-  public void init(final FilterConfig config) {
-    LOG.info("Starting Session Filter initialization");
-    this.filterConfig = config;
-
-    if (started.getAndDecrement() > 0) {
-      /**
-       * Allow override for testing purposes
-       */
-      String managerClassStr =
-          config.getInitParameter("session-manager-class");
-
-      // Otherwise default
-      if (managerClassStr == null) {
-        managerClassStr = GemfireSessionManager.class.getName();
-      }
-
-      try {
-        manager = (SessionManager) Class.forName(
-            managerClassStr).newInstance();
-        manager.start(config, this.getClass().getClassLoader());
-      } catch (Exception ex) {
-        LOG.error("Exception creating Session Manager", ex);
-      }
-
-      startingLatch.countDown();
-    } else {
-      try {
-        startingLatch.await();
-      } catch (InterruptedException iex) {
-      }
-
-      LOG.debug("SessionManager and listener initialization skipped - "
-          + "already done.");
-    }
-
-    LOG.info("Session Filter initialization complete");
-    LOG.debug("Filter class loader {}", this.getClass().getClassLoader());
-  }
-
-  /**
-   * Return a String representation of this object.
-   */
-  @Override
-  public String toString() {
-    if (filterConfig == null) {
-      return ("SessionCachingFilter()");
-    }
-    StringBuilder sb = new StringBuilder("SessionCachingFilter(");
-    sb.append(filterConfig);
-    sb.append(")");
-    return (sb.toString());
-
-  }
-
-
-  private void sendProcessingError(Throwable t, ServletResponse response) {
-    String stackTrace = getStackTrace(t);
-
-    if (stackTrace != null && !stackTrace.equals("")) {
-      try {
-        response.setContentType("text/html");
-        PrintStream ps = new PrintStream(response.getOutputStream());
-        PrintWriter pw = new PrintWriter(ps);
-        pw.print(
-            "<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N
-
-        // PENDING! Localize this for next official release
-        pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
-        pw.print(stackTrace);
-        pw.print("</pre></body>\n</html>"); //NOI18N
-        pw.close();
-        ps.close();
-        response.getOutputStream().close();
-      } catch (Exception ex) {
-      }
-    } else {
-      try {
-        PrintStream ps = new PrintStream(response.getOutputStream());
-        t.printStackTrace(ps);
-        ps.close();
-        response.getOutputStream().close();
-      } catch (Exception ex) {
-      }
-    }
-  }
-
-  public static String getStackTrace(Throwable t) {
-    String stackTrace = null;
-    try {
-      StringWriter sw = new StringWriter();
-      PrintWriter pw = new PrintWriter(sw);
-      t.printStackTrace(pw);
-      pw.close();
-      sw.close();
-      stackTrace = sw.getBuffer().toString();
-    } catch (Exception ex) {
-    }
-    return stackTrace;
-  }
-
-  /**
-   * Retrieve the SessionManager. This is only here so that tests can get access
-   * to the cache.
-   */
-  static SessionManager getSessionManager() {
-    return manager;
-  }
-
-  /**
-   * Return the GemFire session which wraps a native session
-   *
-   * @param nativeSession the native session for which the corresponding GemFire
-   *                      session should be returned.
-   * @return the GemFire session or null if no session maps to the native
-   * session
-   */
-  public static HttpSession getWrappingSession(HttpSession nativeSession) {
-        /*
-         * This is a special case where the GemFire session has been set as a
-         * ThreadLocal during session creation.
-         */
-    GemfireHttpSession gemfireSession = (GemfireHttpSession) ThreadLocalSession.get();
-    if (gemfireSession != null) {
-      gemfireSession.setNativeSession(nativeSession);
-      return gemfireSession;
-    }
-    return getSessionManager().getWrappingSession(nativeSession.getId());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionListener.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionListener.java b/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionListener.java
deleted file mode 100644
index 9726be0..0000000
--- a/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/filter/SessionListener.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*=========================================================================
- * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
- * This product is protected by U.S. and international copyright
- * and intellectual property laws. Pivotal products are covered by
- * one or more patents listed at http://www.pivotal.io/patents.
- *=========================================================================
- */
-package com.gemstone.gemfire.modules.session.filter;
-
-import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.http.HttpSessionEvent;
-import javax.servlet.http.HttpSessionListener;
-
-public class SessionListener implements HttpSessionListener {
-
-  private static final Logger LOG =
-      LoggerFactory.getLogger(SessionListener.class.getName());
-
-  public void sessionCreated(HttpSessionEvent httpSessionEvent) {
-  }
-
-  /**
-   * This will receive events from the container using the native sessions.
-   */
-  public void sessionDestroyed(HttpSessionEvent event) {
-    String nativeId = event.getSession().getId();
-    try {
-      String sessionId = SessionCachingFilter.getSessionManager().destroyNativeSession(
-          nativeId);
-      LOG.debug(
-          "Received sessionDestroyed event for native session {} (wrapped by {})",
-          nativeId, sessionId);
-    } catch (DistributedSystemDisconnectedException dex) {
-      LOG.debug("Cache disconnected - unable to destroy native session {0}",
-          nativeId);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/92ee6a79/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/installer/Installer.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/installer/Installer.java b/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/installer/Installer.java
index ee773d2..57bdde6 100644
--- a/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/installer/Installer.java
+++ b/modules/gemfire-modules-session-external/src/main/java/com/gemstone/gemfire/modules/session/installer/Installer.java
@@ -36,10 +36,10 @@ import java.io.OutputStream;
 public class Installer {
 
   private static final String GEMFIRE_FILTER_CLASS =
-      "com.gemstone.gemfire.modules.session.filter.SessionCachingFilter";
+      "com.gemstone.gemfire.modules.session.filter.internal.SessionCachingFilter";
 
   private static final String GEMFIRE_LISTENER_CLASS =
-      "com.gemstone.gemfire.modules.session.filter.SessionListener";
+      "com.gemstone.gemfire.modules.session.filter.internal.SessionListener";
 
   private ArgumentValues argValues;