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 2016/02/08 17:51:52 UTC

[04/32] incubator-geode git commit: GEODE-14: Integration of GemFire Session Replication and Hibernate modules

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java b/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java
new file mode 100644
index 0000000..f312545
--- /dev/null
+++ b/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session;
+
+import com.gemstone.gemfire.modules.session.catalina.Tomcat7DeltaSessionManager;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import org.junit.BeforeClass;
+import org.junit.experimental.categories.Category;
+
+/**
+ * @author Jens Deppe
+ */
+@Category(UnitTest.class)
+public class Tomcat7SessionsJUnitTest extends TestSessionsBase {
+
+  // Set up the session manager we need
+  @BeforeClass
+  public static void setupClass() throws Exception {
+    setupServer(new Tomcat7DeltaSessionManager());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml
new file mode 100644
index 0000000..6c9f217
--- /dev/null
+++ b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml
@@ -0,0 +1,3 @@
+<?xml version='1.0' encoding='utf-8'?>
+<tomcat-users>
+</tomcat-users>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/logs/.gitkeep
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/logs/.gitkeep b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/logs/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/temp/.gitkeep
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/temp/.gitkeep b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/temp/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/build.gradle b/extensions/gemfire-modules/build.gradle
new file mode 100644
index 0000000..1d45ab8
--- /dev/null
+++ b/extensions/gemfire-modules/build.gradle
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+test  {
+  doFirst {
+    copy {
+      from 'build/resources/test/tomcat'
+      into 'build/test/tomcat/'
+    }
+  }
+}
+
+jar {
+  baseName = 'gemfire-modules'
+}
+
+dependencies {
+  compile project(':gemfire-core')
+
+  compile 'org.apache.tomcat:catalina:' + project.'tomcat6.version'
+  compile 'org.apache.tomcat:catalina-ha:' + project.'tomcat6.version'
+  compile 'org.apache.tomcat:juli:' + project.'tomcat6.version'
+
+  testCompile 'org.httpunit:httpunit:' + project.'httpunit.version'
+  testRuntime 'org.apache.tomcat:coyote:' + project.'tomcat6.version'
+
+  provided project(path: ':gemfire-junit', configuration: 'testOutput')
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
new file mode 100644
index 0000000..13b2e77
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
@@ -0,0 +1,64 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+@SuppressWarnings("serial")
+public abstract class AbstractGatewayDeltaEvent implements GatewayDeltaEvent, DataSerializable {
+
+  protected String regionName;
+  protected String key;
+
+  public AbstractGatewayDeltaEvent() {
+  }
+
+  public AbstractGatewayDeltaEvent(String regionName, String key) {
+    this.regionName = regionName;
+    this.key = key;
+  }
+
+  public String getRegionName() {
+    return this.regionName;
+  }
+
+  public String getKey() {
+    return this.key;
+  }
+
+  @SuppressWarnings("unchecked")
+  public Region getRegion(Cache cache) {
+    return cache.getRegion(this.regionName);
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.regionName = DataSerializer.readString(in);
+    this.key = DataSerializer.readString(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeString(this.regionName, out);
+    DataSerializer.writeString(this.key, out);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
new file mode 100644
index 0000000..4acad05
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
@@ -0,0 +1,26 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.gatewaydelta;
+
+public interface GatewayDelta {
+
+  public static final String GATEWAY_DELTA_REGION_NAME = "__gatewayDelta";
+
+  public GatewayDeltaEvent getCurrentGatewayDeltaEvent();
+
+  public void setCurrentGatewayDeltaEvent(GatewayDeltaEvent currentGatewayDeltaEvent);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
new file mode 100644
index 0000000..3202591
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
@@ -0,0 +1,88 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.Instantiator;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.CachedDeserializableFactory;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+@SuppressWarnings("serial")
+public class GatewayDeltaCreateEvent extends AbstractGatewayDeltaEvent {
+
+  private byte[] gatewayDelta;
+
+  public GatewayDeltaCreateEvent() {
+  }
+
+  public GatewayDeltaCreateEvent(String regionName, String key, byte[] gatewayDelta) {
+    super(regionName, key);
+    this.gatewayDelta = gatewayDelta;
+  }
+
+  public byte[] getGatewayDelta() {
+    return this.gatewayDelta;
+  }
+
+  public void apply(Cache cache) {
+    Region<String, CachedDeserializable> region = getRegion(cache);
+    region.put(this.key, CachedDeserializableFactory.create(this.gatewayDelta), true);
+    if (cache.getLogger().fineEnabled()) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("Applied ").append(this);
+      cache.getLogger().fine(builder.toString());
+    }
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    this.gatewayDelta = DataSerializer.readByteArray(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    DataSerializer.writeByteArray(this.gatewayDelta, out);
+  }
+
+  public static void registerInstantiator(int id) {
+    Instantiator.register(new Instantiator(GatewayDeltaCreateEvent.class, id) {
+      public DataSerializable newInstance() {
+        return new GatewayDeltaCreateEvent();
+      }
+    });
+  }
+
+  public String toString() {
+    return new StringBuilder().append("GatewayDeltaCreateEvent[")
+        .append("regionName=")
+        .append(this.regionName)
+        .append("; key=")
+        .append(this.key)
+        .append("; gatewayDelta=")
+        .append(this.gatewayDelta)
+        .append("]")
+        .toString();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
new file mode 100644
index 0000000..18bfe8b
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
@@ -0,0 +1,82 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.Instantiator;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.EntryNotFoundException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSession;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+@SuppressWarnings("serial")
+public class GatewayDeltaDestroyEvent extends AbstractGatewayDeltaEvent {
+
+  public GatewayDeltaDestroyEvent() {
+  }
+
+  public GatewayDeltaDestroyEvent(String regionName, String key) {
+    super(regionName, key);
+  }
+
+  public void apply(Cache cache) {
+    Region<String, DeltaSession> region = getRegion(cache);
+    try {
+      region.destroy(this.key);
+      if (cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("Applied ").append(this);
+        cache.getLogger().fine(builder.toString());
+      }
+    } catch (EntryNotFoundException e) {
+      StringBuilder builder = new StringBuilder();
+      builder.append(this).append(": Session ").append(this.key).append(" was not found");
+      cache.getLogger().warning(builder.toString());
+    }
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+  }
+
+  public static void registerInstantiator(int id) {
+    Instantiator.register(new Instantiator(GatewayDeltaDestroyEvent.class, id) {
+      public DataSerializable newInstance() {
+        return new GatewayDeltaDestroyEvent();
+      }
+    });
+  }
+
+  public String toString() {
+    return new StringBuilder().append("GatewayDeltaDestroyEvent[")
+        .append("regionName=")
+        .append(this.regionName)
+        .append("; key=")
+        .append(this.key)
+        .append("]")
+        .toString();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
new file mode 100644
index 0000000..672a01f
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
@@ -0,0 +1,24 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.cache.Cache;
+
+public interface GatewayDeltaEvent {
+
+  public void apply(Cache cache);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
new file mode 100644
index 0000000..cf9aa1a
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
@@ -0,0 +1,67 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.EntryEvent;
+import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventCallbackArgument;
+
+import java.util.Properties;
+
+public class GatewayDeltaEventApplicationCacheListener extends CacheListenerAdapter<String, GatewayDeltaEvent> implements Declarable {
+
+  private final Cache cache;
+
+  public GatewayDeltaEventApplicationCacheListener() {
+    this.cache = CacheFactory.getAnyInstance();
+  }
+
+  public void afterCreate(EntryEvent<String, GatewayDeltaEvent> event) {
+    System.out.println("GatewayDeltaApplierCacheListener event: " + event);
+    EntryEventImpl eventImpl = (EntryEventImpl) event;
+    if (this.cache.getLogger().fineEnabled()) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("GatewayDeltaApplierCacheListener: Received event for ")
+          .append(event.getKey())
+          .append("->")
+          .append(event.getNewValue())
+          .append(".");
+      this.cache.getLogger().fine(builder.toString());
+    }
+
+    // If the event is from a remote site, apply it to the session
+    Object callbackArgument = eventImpl.getRawCallbackArgument();
+    System.out.println("GatewayDeltaApplierCacheListener callbackArgument: " + callbackArgument);
+    if (callbackArgument instanceof GatewaySenderEventCallbackArgument) {
+      GatewayDeltaEvent delta = event.getNewValue();
+      delta.apply(this.cache);
+      System.out.println("Applied " + delta);
+      if (this.cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("GatewayDeltaApplierCacheListener: Applied ").append(delta);
+        this.cache.getLogger().fine(builder.toString());
+      }
+    }
+  }
+
+  public void init(Properties p) {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java
new file mode 100644
index 0000000..ce44fcb
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java
@@ -0,0 +1,197 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.EntryEvent;
+import com.gemstone.gemfire.cache.InterestPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionFactory;
+import com.gemstone.gemfire.cache.Scope;
+import com.gemstone.gemfire.cache.SerializedCacheValue;
+import com.gemstone.gemfire.cache.SubscriptionAttributes;
+import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+
+import java.util.Properties;
+
+public class GatewayDeltaForwarderCacheListener extends CacheListenerAdapter<String, GatewayDelta> implements Declarable {
+
+  private final Cache cache;
+
+  private LocalRegion gatewayDeltaRegion;
+
+  public GatewayDeltaForwarderCacheListener() {
+    this(CacheFactory.getAnyInstance());
+  }
+
+  public GatewayDeltaForwarderCacheListener(Cache cache) {
+    this.cache = cache;
+  }
+
+  @SuppressWarnings("unchecked")
+  public void afterCreate(EntryEvent<String, GatewayDelta> event) {
+    // If the event is from the local site, create a 'create' event and send it to the
+    // gateway delta region
+    if (event.getCallbackArgument() == null) {
+      if (this.cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("GatewayDeltaForwarderCacheListener: Received create event for ")
+            .append(event.getKey())
+            .append("->")
+            .append(event.getNewValue())
+            .append(" that originated in the local site. Sending it to the remote site.");
+        this.cache.getLogger().fine(builder.toString());
+      }
+
+      // Distribute the create event to the gateway hub(s)
+      String regionName = event.getRegion().getFullPath();
+      String sessionId = event.getKey();
+      SerializedCacheValue scv = event.getSerializedNewValue();
+      if (scv == null) {
+        getGatewayDeltaRegion().put(sessionId,
+            new GatewayDeltaCreateEvent(regionName, sessionId, EntryEventImpl.serialize(event.getNewValue())));
+      } else {
+        System.out.println(
+            "GatewayDeltaForwarderCacheListener event.getSerializedNewValue().getSerializedValue(): " + event.getSerializedNewValue()
+                .getSerializedValue());
+        getGatewayDeltaRegion().put(sessionId,
+            new GatewayDeltaCreateEvent(regionName, sessionId, scv.getSerializedValue()));
+      }
+    } else {
+      if (this.cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("GatewayDeltaForwarderCacheListener: Received create event for ")
+            .append(event.getKey())
+            .append("->")
+            .append(event.getNewValue())
+            .append(" that originated in the remote site.");
+        this.cache.getLogger().fine(builder.toString());
+      }
+    }
+  }
+
+  public void afterUpdate(EntryEvent<String, GatewayDelta> event) {
+    //System.out.println("GatewayDeltaForwarderCacheListener.afterUpdate: " + event);
+    // If the event is from the local site, create an 'update' event and send it to the
+    // gateway delta region
+    if (event.getCallbackArgument() == null) {
+      if (this.cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("GatewayDeltaForwarderCacheListener: Received update event for ")
+            .append(event.getKey())
+            .append("->")
+            .append(event.getNewValue())
+            .append(" that originated in the local site. Sending it to the remote site.");
+        this.cache.getLogger().fine(builder.toString());
+      }
+
+      // Distribute the update event to the gateway hub(s)
+      GatewayDelta session = event.getNewValue();
+      getGatewayDeltaRegion().put(event.getKey(), session.getCurrentGatewayDeltaEvent());
+
+      // Reset the current delta
+      session.setCurrentGatewayDeltaEvent(null);
+    } else {
+      if (this.cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("GatewayDeltaForwarderCacheListener: Received update event for ")
+            .append(event.getKey())
+            .append("->")
+            .append(event.getNewValue())
+            .append(" that originated in the remote site.");
+        this.cache.getLogger().fine(builder.toString());
+      }
+    }
+  }
+
+  public void afterDestroy(EntryEvent<String, GatewayDelta> event) {
+    // If the event is from the local site, create a 'destroy' event and send it to the
+    // gateway delta region
+    if (event.getCallbackArgument() != null) {
+      if (this.cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("GatewayDeltaForwarderCacheListener: Received destroy event for ")
+            .append(event.getKey())
+            .append("->")
+            .append(event.getNewValue())
+            .append(" that originated in the local site. Sending it to the remote site.");
+        this.cache.getLogger().fine(builder.toString());
+      }
+
+      // Distribute the destroy event to the gateway hub(s)
+      String sessionId = event.getKey();
+      getGatewayDeltaRegion().put(sessionId, new GatewayDeltaDestroyEvent(event.getRegion().getFullPath(), sessionId));
+    } else {
+      if (this.cache.getLogger().fineEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("GatewayDeltaForwarderCacheListener: Received destroy event for session ")
+            .append(event.getKey())
+            .append(" that either expired or originated in the remote site.");
+        this.cache.getLogger().fine(builder.toString());
+      }
+    }
+  }
+
+  public void init(Properties p) {
+  }
+
+  private LocalRegion getGatewayDeltaRegion() {
+    if (this.gatewayDeltaRegion == null) {
+      this.gatewayDeltaRegion = createOrRetrieveGatewayDeltaRegion();
+    }
+    return this.gatewayDeltaRegion;
+  }
+
+  @SuppressWarnings("unchecked")
+  private LocalRegion createOrRetrieveGatewayDeltaRegion() {
+    Region region = this.cache.getRegion(GatewayDelta.GATEWAY_DELTA_REGION_NAME);
+    if (region == null) {
+      region = new RegionFactory().setScope(Scope.LOCAL)
+          .setDataPolicy(DataPolicy.EMPTY)
+          .setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL))
+// TODO: Disabled for WAN
+//        .setEnableGateway(true)
+          .addCacheListener(new GatewayDeltaEventApplicationCacheListener())
+          .create(GatewayDelta.GATEWAY_DELTA_REGION_NAME);
+    }
+    if (this.cache.getLogger().fineEnabled()) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("GatewayDeltaForwarderCacheListener: Created gateway delta region: ").append(region);
+      this.cache.getLogger().fine(builder.toString());
+    }
+    return (LocalRegion) region;
+  }
+
+  public boolean equals(Object obj) {
+    // This method is only implemented so that RegionCreator.validateRegion works properly.
+    // The CacheListener comparison fails because two of these instances are not equal.
+    if (this == obj) {
+      return true;
+    }
+
+    if (obj == null || !(obj instanceof GatewayDeltaForwarderCacheListener)) {
+      return false;
+    }
+
+    return true;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java
new file mode 100644
index 0000000..ea81309
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java
@@ -0,0 +1,398 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.bootstrap;
+
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.control.ResourceManager;
+import com.gemstone.gemfire.distributed.internal.AbstractDistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.modules.util.Banner;
+import com.gemstone.gemfire.modules.util.RegionHelper;
+import com.gemstone.gemfire.modules.util.ResourceManagerValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public abstract class AbstractCache {
+
+  protected GemFireCache cache;
+
+  private static final DateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+
+  protected static final String DEFAULT_LOG_FILE_NAME = RegionHelper.NAME + "." + FORMAT.format(new Date()) + ".log";
+
+  protected static final String DEFAULT_STATISTIC_ARCHIVE_FILE_NAME = RegionHelper.NAME + ".gfs";
+
+  protected static final float DEFAULT_EVICTION_HEAP_PERCENTAGE = LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE;
+
+  protected static final float DEFAULT_CRITICAL_HEAP_PERCENTAGE = ResourceManager.DEFAULT_CRITICAL_PERCENTAGE;
+
+  protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCache.class);
+
+  protected float evictionHeapPercentage = DEFAULT_EVICTION_HEAP_PERCENTAGE;
+
+  protected float criticalHeapPercentage = DEFAULT_CRITICAL_HEAP_PERCENTAGE;
+
+  protected boolean rebalance = false;
+
+  protected final Map<String, String> gemfireProperties;
+
+  private final AtomicBoolean started = new AtomicBoolean(false);
+
+  /**
+   * Instance reference which is set in static initialization blocks of any subclasses.
+   */
+  protected static AbstractCache instance = null;
+
+  public AbstractCache() {
+    this.gemfireProperties = new ConcurrentHashMap<String, String>();
+  }
+
+  public void lifecycleEvent(LifecycleTypeAdapter eventType) {
+    if (getLogger().isDebugEnabled()) {
+      getLogger().debug("Received " + eventType + " event");
+    }
+
+    if (eventType.equals(LifecycleTypeAdapter.START) && started.compareAndSet(false, true)) {
+      // Create or retrieve the cache
+      getLogger().info("Initializing " + Banner.getString());
+      createOrRetrieveCache();
+
+      // Initialize the resource manager
+      initializeResourceManager();
+    } else if (eventType.equals(LifecycleTypeAdapter.AFTER_START)) {
+      if (getRebalance()) {
+        rebalanceCache();
+      }
+    } else if (eventType.equals(LifecycleTypeAdapter.STOP)) {
+      // Close the cache
+//      closeCache();
+      // TODO: Do we need to reset the started flag here?
+    }
+  }
+
+  public boolean isStarted() {
+    return started.get();
+  }
+
+  public void close() {
+    getCache().close();
+    while (!getCache().isClosed()) {
+    }
+
+    started.set(false);
+  }
+
+  public GemFireCache getCache() {
+    return this.cache;
+  }
+
+  public String getLogFileName() {
+    String logFileName = getGemFireProperties().get(DistributionConfig.LOG_FILE_NAME);
+    if (logFileName == null) {
+      logFileName = DEFAULT_LOG_FILE_NAME;
+    }
+    return logFileName;
+  }
+
+  public String getStatisticArchiveFileName() {
+    String statisticsArchiveFileName = getGemFireProperties().get(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME);
+    if (statisticsArchiveFileName == null) {
+      statisticsArchiveFileName = DEFAULT_STATISTIC_ARCHIVE_FILE_NAME;
+    }
+    return statisticsArchiveFileName;
+  }
+
+  public String getCacheXmlFileName() {
+    String cacheXmlFileName = getGemFireProperties().get(DistributionConfig.CACHE_XML_FILE_NAME);
+    if (cacheXmlFileName == null) {
+      cacheXmlFileName = getDefaultCacheXmlFileName();
+    }
+    return cacheXmlFileName;
+  }
+
+  protected File getCacheXmlFile() {
+    String cacheXmlFileName = getCacheXmlFileName();
+    File cacheXmlFile = new File(cacheXmlFileName);
+    // If the cache xml file is not absolute, point it at the conf directory.
+    if (!cacheXmlFile.isAbsolute()) {
+      if (System.getProperty("catalina.base") != null) {
+        cacheXmlFile = new File(System.getProperty("catalina.base") + "/conf/", cacheXmlFileName);
+      }
+    }
+    return cacheXmlFile;
+  }
+
+  public float getEvictionHeapPercentage() {
+    return this.evictionHeapPercentage;
+  }
+
+  public void setEvictionHeapPercentage(String evictionHeapPercentage) {
+    this.evictionHeapPercentage = Float.valueOf(evictionHeapPercentage);
+  }
+
+  public float getCriticalHeapPercentage() {
+    return this.criticalHeapPercentage;
+  }
+
+  public void setCriticalHeapPercentage(String criticalHeapPercentage) {
+    this.criticalHeapPercentage = Float.valueOf(criticalHeapPercentage);
+  }
+
+  public void setRebalance(boolean rebalance) {
+    this.rebalance = rebalance;
+  }
+
+  public boolean getRebalance() {
+    return this.rebalance;
+  }
+
+  public Map<String, String> getGemFireProperties() {
+    return this.gemfireProperties;
+  }
+
+  public void setProperty(String name, String value) {
+    //TODO Look at fake attributes
+    if (name.equals("className")) {
+      return;
+    }
+
+    // Determine the validity of the input property
+    boolean validProperty = false;
+    for (String gemfireProperty : AbstractDistributionConfig._getAttNames()) {
+      if (name.equals(gemfireProperty)) {
+        validProperty = true;
+        break;
+      }
+    }
+
+    // If it is a valid GemFire property, add it to the the GemFire properties.
+    // Otherwise, log a warning.
+    if (validProperty) {
+      this.gemfireProperties.put(name, value);
+    } else {
+      getLogger().warn("The input property named " + name + " is not a valid GemFire property. It is being ignored.");
+    }
+  }
+
+  public Logger getLogger() {
+    return LOGGER;
+  }
+
+  protected Properties createDistributedSystemProperties() {
+    Properties properties = new Properties();
+
+    // Add any additional gemfire properties
+    for (Map.Entry<String, String> entry : this.gemfireProperties.entrySet()) {
+      properties.put(entry.getKey(), entry.getValue());
+    }
+
+    // Replace the cache xml file in the properties
+    File cacheXmlFile = getCacheXmlFile();
+    String absoluteCacheXmlFileName = cacheXmlFile.getAbsolutePath();
+    // If the file doesn't exist and the name is the default, set cache-xml-file
+    // to the GemFire default. This is for the case where only the jars have been
+    // installed and no default cache.xml exists in the conf directory.
+    if (getCacheXmlFileName().equals(getDefaultCacheXmlFileName()) && !cacheXmlFile.exists()) {
+      absoluteCacheXmlFileName = DistributionConfig.DEFAULT_CACHE_XML_FILE.getName();
+    }
+    properties.put(DistributionConfig.CACHE_XML_FILE_NAME, absoluteCacheXmlFileName);
+
+    // Replace the log file in the properties
+    properties.put(DistributionConfig.LOG_FILE_NAME, getLogFile().getAbsolutePath());
+
+    // Replace the statistics archive file in the properties
+    File statisticArchiveFile = getStatisticArchiveFile();
+    if (statisticArchiveFile == null) {
+      // Remove the statistics archive file name since statistic sampling is disabled
+      properties.remove(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME);
+      properties.remove(DistributionConfig.STATISTIC_SAMPLING_ENABLED_NAME);
+    } else {
+      properties.put(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME, statisticArchiveFile.getAbsolutePath());
+    }
+    getLogger().info("Creating distributed system from: " + properties);
+
+    return properties;
+  }
+
+  protected void closeCache() {
+    if (getLogger().isDebugEnabled()) {
+      getLogger().debug("Closing " + this.cache);
+    }
+    if (getCache() != null) {
+      getCache().close();
+    }
+    getLogger().info("Closed " + this.cache);
+  }
+
+  protected File getLogFile() {
+    String logFileName = getLogFileName();
+    File logFile = new File(logFileName);
+    // If the log file is not absolute, point it at the logs directory.
+    if (!logFile.isAbsolute()) {
+      if (System.getProperty("catalina.base") != null) {
+        logFile = new File(System.getProperty("catalina.base") + "/logs/", logFileName);
+      } else if (System.getProperty("weblogic.Name") != null) {
+        String weblogicName = System.getProperty("weblogic.Name");
+        String separator = System.getProperty("file.separator");
+        logFile = new File("servers" + separator + weblogicName + separator +
+            "logs" + separator + logFileName);
+      } else {
+        logFile = new File(System.getProperty("gemfire.logdir"), logFileName);
+      }
+    }
+    return logFile;
+  }
+
+  protected File getStatisticArchiveFile() {
+    File statisticsArchiveFile = null;
+    String statisticSamplingEnabled = getGemFireProperties().get(DistributionConfig.STATISTIC_SAMPLING_ENABLED_NAME);
+    if (statisticSamplingEnabled != null && statisticSamplingEnabled.equals("true")) {
+      String statisticsArchiveFileName = getStatisticArchiveFileName();
+      statisticsArchiveFile = new File(statisticsArchiveFileName);
+      // If the statistics archive file is not absolute, point it at the logs directory.
+      if (!statisticsArchiveFile.isAbsolute()) {
+        if (System.getProperty("catalina.base") != null) {
+          statisticsArchiveFile = new File(System.getProperty("catalina.base") + "/logs/", statisticsArchiveFileName);
+        } else if (System.getProperty("weblogic.Name") != null) {
+          String weblogicName = System.getProperty("weblogic.Name");
+          String separator = System.getProperty("file.separator");
+          statisticsArchiveFile = new File("servers" + separator + weblogicName + separator +
+              "logs" + separator + statisticsArchiveFileName);
+        } else {
+          statisticsArchiveFile = new File(System.getProperty("gemfire.statisticsdir"), statisticsArchiveFileName);
+        }
+      }
+    }
+    return statisticsArchiveFile;
+  }
+
+  protected void initializeResourceManager() {
+    // Get current eviction and critical heap percentages
+    ResourceManager rm = getCache().getResourceManager();
+    float currentEvictionHeapPercentage = rm.getEvictionHeapPercentage();
+    float currentCriticalHeapPercentage = rm.getCriticalHeapPercentage();
+
+    // Set new eviction and critical heap percentages if necessary
+    if (getEvictionHeapPercentage() != currentEvictionHeapPercentage || getCriticalHeapPercentage() != currentCriticalHeapPercentage) {
+      if (getLogger().isDebugEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("Previous eviction heap percentage=")
+            .append(currentEvictionHeapPercentage)
+            .append("; critical heap percentage=")
+            .append(currentCriticalHeapPercentage);
+        getLogger().debug(builder.toString());
+        builder.setLength(0);
+        builder.append("Requested eviction heap percentage=")
+            .append(getEvictionHeapPercentage())
+            .append("; critical heap percentage=")
+            .append(getCriticalHeapPercentage());
+        getLogger().debug(builder.toString());
+      }
+      if (currentCriticalHeapPercentage == 0.0f) {
+        // If the current critical heap percentage is 0 (disabled), set eviction
+        // heap percentage first, then set the critical heap percentage. At this
+        // point, the eviction heap percentage can be set to anything.
+        try {
+          rm.setEvictionHeapPercentage(getEvictionHeapPercentage());
+          rm.setCriticalHeapPercentage(getCriticalHeapPercentage());
+        } catch (IllegalArgumentException e) {
+          handleResourceManagerException(e, currentEvictionHeapPercentage, currentCriticalHeapPercentage);
+          rm.setEvictionHeapPercentage(currentEvictionHeapPercentage);
+          rm.setCriticalHeapPercentage(currentCriticalHeapPercentage);
+        }
+      } else if (getCriticalHeapPercentage() >= currentCriticalHeapPercentage) {
+        // If the requested critical heap percentage is >= the current critical
+        // heap percentage, then set the critical heap percentage first since it
+        // can safely be slid up. Then, set the eviction heap percentage.
+        try {
+          rm.setCriticalHeapPercentage(getCriticalHeapPercentage());
+          rm.setEvictionHeapPercentage(getEvictionHeapPercentage());
+        } catch (IllegalArgumentException e) {
+          handleResourceManagerException(e, currentEvictionHeapPercentage, currentCriticalHeapPercentage);
+          rm.setCriticalHeapPercentage(currentCriticalHeapPercentage);
+          rm.setEvictionHeapPercentage(currentEvictionHeapPercentage);
+        }
+      } else {
+        // If the requested critical heap percentage is < the current critical
+        // heap percentage, then set the eviction heap percentage first since it
+        // can safely be slid down. Then, set the critical heap percentage.
+        try {
+          rm.setEvictionHeapPercentage(getEvictionHeapPercentage());
+          rm.setCriticalHeapPercentage(getCriticalHeapPercentage());
+        } catch (IllegalArgumentException e) {
+          handleResourceManagerException(e, currentEvictionHeapPercentage, currentCriticalHeapPercentage);
+          rm.setEvictionHeapPercentage(currentEvictionHeapPercentage);
+          rm.setCriticalHeapPercentage(currentCriticalHeapPercentage);
+        }
+      }
+      if (getLogger().isDebugEnabled()) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("Actual eviction heap percentage=")
+            .append(rm.getEvictionHeapPercentage())
+            .append("; critical heap percentage=")
+            .append(rm.getCriticalHeapPercentage());
+        getLogger().debug(builder.toString());
+      }
+    }
+
+    // Validate java startup parameters (done after setting the eviction and
+    // critical heap percentages so that the CMSInitiatingOccupancyFraction can
+    // be compared against them.
+    ResourceManagerValidator.validateJavaStartupParameters(getCache());
+  }
+
+  private void handleResourceManagerException(IllegalArgumentException e, float currentEvictionHeapPercentage,
+      float currentCriticalHeapPercentage) {
+    StringBuilder builder = new StringBuilder();
+    builder.append("Caught exception attempting to set eviction heap percentage=")
+        .append(getEvictionHeapPercentage())
+        .append(" and critical heap percentage=")
+        .append(getCriticalHeapPercentage())
+        .append(". The percentages will be set back to their previous values (eviction heap percentage=")
+        .append(currentEvictionHeapPercentage)
+        .append(" and critical heap percentage=")
+        .append(currentCriticalHeapPercentage)
+        .append(").");
+    getLogger().warn(builder.toString(), e);
+  }
+
+  @Override
+  public String toString() {
+    return new StringBuilder().append(getClass().getSimpleName())
+        .append("[")
+        .append("cache=")
+        .append(this.cache)
+        .append("]")
+        .toString();
+  }
+
+  protected abstract void createOrRetrieveCache();
+
+  protected abstract void rebalanceCache();
+
+  protected abstract String getDefaultCacheXmlFileName();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java
new file mode 100644
index 0000000..f8cff16
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java
@@ -0,0 +1,74 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.bootstrap;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+
+/**
+ * This is a singleton class which maintains configuration properties as well as starting a Client-Server cache.
+ */
+public class ClientServerCache extends AbstractCache {
+
+  protected static final String DEFAULT_CACHE_XML_FILE_NAME = "cache-client.xml";
+
+  static {
+    instance = new ClientServerCache();
+  }
+
+  private ClientServerCache() {
+    // Singleton
+    super();
+  }
+
+  public static AbstractCache getInstance() {
+    return instance;
+  }
+
+  @Override
+  protected void createOrRetrieveCache() {
+    if (getLogger().isDebugEnabled()) {
+      getLogger().debug(this + ": Creating cache");
+    }
+    // Get the existing cache if any
+    try {
+      this.cache = ClientCacheFactory.getAnyInstance();
+    } catch (CacheClosedException e) {
+    }
+
+    // If no cache exists, create one
+    String message = null;
+    if (this.cache == null) {
+      // enable pool subscription so that default cache can be used by hibernate module
+      this.cache = new ClientCacheFactory(createDistributedSystemProperties()).create();
+      message = "Created ";
+    } else {
+      message = "Retrieved ";
+    }
+    getLogger().info(message + this.cache);
+  }
+
+  @Override
+  protected void rebalanceCache() {
+    getLogger().warn("The client cannot rebalance the server's cache.");
+  }
+
+  @Override
+  protected String getDefaultCacheXmlFileName() {
+    return DEFAULT_CACHE_XML_FILE_NAME;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java
new file mode 100644
index 0000000..2f0c9bb
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java
@@ -0,0 +1,59 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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.
+*/
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.gemstone.gemfire.modules.session.bootstrap;
+
+/**
+ * Adapter for the Catalina Lifecycle event types
+ */
+public enum LifecycleTypeAdapter {
+
+  CONFIGURE_START,
+
+  CONFIGURE_STOP,
+
+  AFTER_DESTROY,
+
+  AFTER_INIT,
+
+  AFTER_START,
+
+  AFTER_STOP,
+
+  BEFORE_DESTROY,
+
+  BEFORE_INIT,
+
+  BEFORE_START,
+
+  BEFORE_STOP,
+
+  DESTROY,
+
+  INIT,
+
+  PERIODIC,
+
+  START,
+
+  STOP;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java
new file mode 100644
index 0000000..b0b3b4a
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java
@@ -0,0 +1,85 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.bootstrap;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.control.RebalanceResults;
+import com.gemstone.gemfire.modules.util.RegionHelper;
+
+/**
+ * This is a singleton class which maintains configuration properties as well as starting a Peer-To-Peer cache.
+ */
+
+public class PeerToPeerCache extends AbstractCache {
+
+  protected static final String DEFAULT_CACHE_XML_FILE_NAME = "cache-peer.xml";
+
+  static {
+    instance = new PeerToPeerCache();
+  }
+
+  private PeerToPeerCache() {
+    // Singleton
+    super();
+  }
+
+  public static AbstractCache getInstance() {
+    return instance;
+  }
+
+  @Override
+  protected void createOrRetrieveCache() {
+    if (getLogger().isDebugEnabled()) {
+      getLogger().debug("Creating cache");
+    }
+    // Get the existing cache if any
+    try {
+      this.cache = CacheFactory.getAnyInstance();
+    } catch (CacheClosedException e) {
+    }
+
+    // If no cache exists, create one
+    String message = null;
+    if (this.cache == null) {
+      this.cache = new CacheFactory(createDistributedSystemProperties()).create();
+      message = "Created ";
+    } else {
+      message = "Retrieved ";
+    }
+    getLogger().info(message + this.cache);
+  }
+
+  @Override
+  protected void rebalanceCache() {
+    try {
+      getLogger().info("Rebalancing: " + this.cache);
+      RebalanceResults results = RegionHelper.rebalanceCache(this.cache);
+      if (getLogger().isDebugEnabled()) {
+        getLogger().debug("Done rebalancing: " + this.cache);
+        getLogger().debug(RegionHelper.getRebalanceResultsMessage(results));
+      }
+    } catch (Exception e) {
+      getLogger().warn("Rebalance failed because of the following exception:", e);
+    }
+  }
+
+  @Override
+  protected String getDefaultCacheXmlFileName() {
+    return DEFAULT_CACHE_XML_FILE_NAME;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java
new file mode 100644
index 0000000..1019ddc
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java
@@ -0,0 +1,68 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.catalina;
+
+
+import com.gemstone.gemfire.modules.session.bootstrap.AbstractCache;
+import com.gemstone.gemfire.modules.session.bootstrap.LifecycleTypeAdapter;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+
+
+public abstract class AbstractCacheLifecycleListener implements LifecycleListener {
+  protected AbstractCache cache;
+
+  @Override
+  public void lifecycleEvent(LifecycleEvent le) {
+    cache.lifecycleEvent(LifecycleTypeAdapter.valueOf(le.getType().toUpperCase()));
+  }
+
+  /**
+   * This is called by Tomcat to set properties on the Listener.
+   */
+  public void setProperty(String name, String value) {
+    cache.setProperty(name, value);
+  }
+
+  /*
+   * These getters and setters are also called by Tomcat and just passed on to
+   * the cache.
+   */
+  public float getEvictionHeapPercentage() {
+    return cache.getEvictionHeapPercentage();
+  }
+
+  public void setEvictionHeapPercentage(String evictionHeapPercentage) {
+    cache.setEvictionHeapPercentage(evictionHeapPercentage);
+  }
+
+  public float getCriticalHeapPercentage() {
+    return cache.getCriticalHeapPercentage();
+  }
+
+  public void setCriticalHeapPercentage(String criticalHeapPercentage) {
+    cache.setCriticalHeapPercentage(criticalHeapPercentage);
+  }
+
+  public void setRebalance(boolean rebalance) {
+    cache.setRebalance(rebalance);
+  }
+
+  public boolean getRebalance() {
+    return cache.getRebalance();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java
new file mode 100644
index 0000000..3019cae
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java
@@ -0,0 +1,113 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.catalina;
+
+import com.gemstone.gemfire.cache.EntryNotFoundException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.session.catalina.internal.DeltaSessionStatistics;
+import com.gemstone.gemfire.modules.util.RegionConfiguration;
+import com.gemstone.gemfire.modules.util.SessionCustomExpiry;
+import org.apache.catalina.Session;
+
+import javax.servlet.http.HttpSession;
+
+public abstract class AbstractSessionCache implements SessionCache {
+
+  protected SessionManager sessionManager;
+
+  /**
+   * The sessionRegion is the <code>Region</code> that actually stores and replicates the <code>Session</code>s.
+   */
+  protected Region<String, HttpSession> sessionRegion;
+
+  /**
+   * The operatingRegion is the <code>Region</code> used to do HTTP operations. if local cache is enabled, then this
+   * will be the local <code>Region</code>; otherwise, it will be the session <code>Region</code>.
+   */
+  protected Region<String, HttpSession> operatingRegion;
+
+  protected DeltaSessionStatistics statistics;
+
+  public AbstractSessionCache(SessionManager sessionManager) {
+    this.sessionManager = sessionManager;
+  }
+
+  @Override
+  public String getSessionRegionName() {
+    return getSessionRegion().getFullPath();
+  }
+
+  @Override
+  public String getOperatingRegionName() {
+    return getOperatingRegion().getFullPath();
+  }
+
+  @Override
+  public void putSession(Session session) {
+    getOperatingRegion().put(session.getId(), (HttpSession) session);
+  }
+
+  @Override
+  public HttpSession getSession(String sessionId) {
+    return getOperatingRegion().get(sessionId);
+  }
+
+  @Override
+  public void destroySession(String sessionId) {
+    try {
+      getOperatingRegion().destroy(sessionId);
+    } catch (EntryNotFoundException enex) {
+      // Ignored
+    }
+  }
+
+  @Override
+  public DeltaSessionStatistics getStatistics() {
+    return this.statistics;
+  }
+
+  protected SessionManager getSessionManager() {
+    return this.sessionManager;
+  }
+
+  public Region<String, HttpSession> getSessionRegion() {
+    return this.sessionRegion;
+  }
+
+  public Region<String, HttpSession> getOperatingRegion() {
+    return this.operatingRegion;
+  }
+
+  protected void createStatistics() {
+    this.statistics = new DeltaSessionStatistics(getCache().getDistributedSystem(),
+        getSessionManager().getStatisticsName());
+  }
+
+  protected RegionConfiguration createRegionConfiguration() {
+    RegionConfiguration configuration = new RegionConfiguration();
+    configuration.setRegionName(getSessionManager().getRegionName());
+    configuration.setRegionAttributesId(getSessionManager().getRegionAttributesId());
+    if (getSessionManager().getMaxInactiveInterval() != RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL) {
+      configuration.setMaxInactiveInterval(getSessionManager().getMaxInactiveInterval());
+      configuration.setCustomExpiry(new SessionCustomExpiry());
+    }
+    configuration.setEnableGatewayDeltaReplication(getSessionManager().getEnableGatewayDeltaReplication());
+    configuration.setEnableGatewayReplication(getSessionManager().getEnableGatewayReplication());
+    configuration.setEnableDebugListener(getSessionManager().getEnableDebugListener());
+    return configuration;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java
new file mode 100644
index 0000000..ba66fa2
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java
@@ -0,0 +1,26 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.catalina;
+
+import com.gemstone.gemfire.modules.session.bootstrap.ClientServerCache;
+
+public class ClientServerCacheLifecycleListener extends AbstractCacheLifecycleListener {
+
+  public ClientServerCacheLifecycleListener() {
+    cache = ClientServerCache.getInstance();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java
new file mode 100644
index 0000000..2de43b4
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java
@@ -0,0 +1,252 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.catalina;
+
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientRegionFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.modules.session.catalina.callback.SessionExpirationCacheListener;
+import com.gemstone.gemfire.modules.util.BootstrappingFunction;
+import com.gemstone.gemfire.modules.util.CreateRegionFunction;
+import com.gemstone.gemfire.modules.util.RegionConfiguration;
+import com.gemstone.gemfire.modules.util.RegionSizeFunction;
+import com.gemstone.gemfire.modules.util.RegionStatus;
+import com.gemstone.gemfire.modules.util.SessionCustomExpiry;
+import com.gemstone.gemfire.modules.util.TouchPartitionedRegionEntriesFunction;
+import com.gemstone.gemfire.modules.util.TouchReplicatedRegionEntriesFunction;
+
+import javax.servlet.http.HttpSession;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ClientServerSessionCache extends AbstractSessionCache {
+
+  private ClientCache cache;
+
+  protected static final String DEFAULT_REGION_ATTRIBUTES_ID = RegionShortcut.PARTITION_REDUNDANT.toString();
+
+  protected static final boolean DEFAULT_ENABLE_LOCAL_CACHE = true;
+
+  public ClientServerSessionCache(SessionManager sessionManager, ClientCache cache) {
+    super(sessionManager);
+    this.cache = cache;
+  }
+
+  @Override
+  public void initialize() {
+    // Bootstrap the servers
+    bootstrapServers();
+
+    // Create or retrieve the region
+    try {
+      createOrRetrieveRegion();
+    } catch (Exception ex) {
+      sessionManager.getLogger().fatal("Unable to create or retrieve region", ex);
+      throw new IllegalStateException(ex);
+    }
+
+    // Set the session region directly as the operating region since there is no difference
+    // between the local cache region and the session region.
+    this.operatingRegion = this.sessionRegion;
+
+    // Create or retrieve the statistics
+    createStatistics();
+  }
+
+  @Override
+  public String getDefaultRegionAttributesId() {
+    return DEFAULT_REGION_ATTRIBUTES_ID;
+  }
+
+  @Override
+  public boolean getDefaultEnableLocalCache() {
+    return DEFAULT_ENABLE_LOCAL_CACHE;
+  }
+
+  @Override
+  public void touchSessions(Set<String> sessionIds) {
+    // Get the region attributes id to determine the region type. This is
+    // problematic since the region attributes id doesn't really define the
+    // region type. Currently there is no way to know the type of region created
+    // on the server. Maybe the CreateRegionFunction should return it.
+    String regionAttributesID = getSessionManager().getRegionAttributesId().toLowerCase();
+
+    // Invoke the appropriate function depending on the type of region
+    if (regionAttributesID.startsWith("partition")) {
+      // Execute the partitioned touch function on the primary server(s)
+      Execution execution = FunctionService.onRegion(getSessionRegion()).withFilter(sessionIds);
+      try {
+        ResultCollector collector = execution.execute(TouchPartitionedRegionEntriesFunction.ID, true, false, true);
+        collector.getResult();
+      } catch (Exception e) {
+        // If an exception occurs in the function, log it.
+        getSessionManager().getLogger().warn("Caught unexpected exception:", e);
+      }
+    } else {
+      // Execute the member touch function on all the server(s)
+      Execution execution = FunctionService.onServers(getCache())
+          .withArgs(new Object[]{this.sessionRegion.getFullPath(), sessionIds});
+      try {
+        ResultCollector collector = execution.execute(TouchReplicatedRegionEntriesFunction.ID, true, false, false);
+        collector.getResult();
+      } catch (Exception e) {
+        // If an exception occurs in the function, log it.
+        getSessionManager().getLogger().warn("Caught unexpected exception:", e);
+      }
+    }
+  }
+
+  @Override
+  public boolean isPeerToPeer() {
+    return false;
+  }
+
+  @Override
+  public boolean isClientServer() {
+    return true;
+  }
+
+  @Override
+  public Set<String> keySet() {
+    return getSessionRegion().keySetOnServer();
+  }
+
+  @Override
+  public int size() {
+    // Add a single dummy key to force the function to go to one server
+    Set<String> filters = new HashSet<String>();
+    filters.add("test-key");
+
+    // Execute the function on the session region
+    Execution execution = FunctionService.onRegion(getSessionRegion()).withFilter(filters);
+    ResultCollector collector = execution.execute(RegionSizeFunction.ID, true, true, true);
+    List<Integer> result = (List<Integer>) collector.getResult();
+
+    // Return the first (and only) element
+    return result.get(0);
+  }
+
+  @Override
+  public boolean isBackingCacheAvailable() {
+    if (getSessionManager().isCommitValveFailfastEnabled()) {
+      PoolImpl pool = (PoolImpl) PoolManager.find(getOperatingRegionName());
+      return pool.isPrimaryUpdaterAlive();
+    }
+    return true;
+  }
+
+  public GemFireCache getCache() {
+    return this.cache;
+  }
+
+  private void bootstrapServers() {
+    Execution execution = FunctionService.onServers(this.cache);
+    ResultCollector collector = execution.execute(new BootstrappingFunction());
+    // Get the result. Nothing is being done with it.
+    try {
+      collector.getResult();
+    } catch (Exception e) {
+      // If an exception occurs in the function, log it.
+      getSessionManager().getLogger().warn("Caught unexpected exception:", e);
+    }
+  }
+
+  protected void createOrRetrieveRegion() {
+    // Retrieve the local session region
+    this.sessionRegion = this.cache.getRegion(getSessionManager().getRegionName());
+
+    // If necessary, create the regions on the server and client
+    if (this.sessionRegion == null) {
+      // Create the PR on the servers
+      createSessionRegionOnServers();
+
+      // Create the region on the client
+      this.sessionRegion = createLocalSessionRegion();
+      if (getSessionManager().getLogger().isDebugEnabled()) {
+        getSessionManager().getLogger().debug("Created session region: " + this.sessionRegion);
+      }
+    } else {
+      if (getSessionManager().getLogger().isDebugEnabled()) {
+        getSessionManager().getLogger().debug("Retrieved session region: " + this.sessionRegion);
+      }
+    }
+  }
+
+  private void createSessionRegionOnServers() {
+    // Create the RegionConfiguration
+    RegionConfiguration configuration = createRegionConfiguration();
+
+    // Send it to the server tier
+    Execution execution = FunctionService.onServer(this.cache).withArgs(configuration);
+    ResultCollector collector = execution.execute(CreateRegionFunction.ID);
+
+    // Verify the region was successfully created on the servers
+    List<RegionStatus> results = (List<RegionStatus>) collector.getResult();
+    for (RegionStatus status : results) {
+      if (status == RegionStatus.INVALID) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("An exception occurred on the server while attempting to create or validate region named ")
+            .append(getSessionManager().getRegionName())
+            .append(". See the server log for additional details.");
+        throw new IllegalStateException(builder.toString());
+      }
+    }
+  }
+
+  private Region<String, HttpSession> createLocalSessionRegion() {
+    ClientRegionFactory<String, HttpSession> factory = null;
+    if (getSessionManager().getEnableLocalCache()) {
+      // Create the region factory with caching and heap LRU enabled
+      factory = this.cache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU);
+
+      // Set the expiration time, action and listener if necessary
+      int maxInactiveInterval = getSessionManager().getMaxInactiveInterval();
+      if (maxInactiveInterval != RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL) {
+        factory.setStatisticsEnabled(true);
+        factory.setCustomEntryIdleTimeout(new SessionCustomExpiry());
+        factory.addCacheListener(new SessionExpirationCacheListener());
+      }
+    } else {
+      // Create the region factory without caching enabled
+      factory = this.cache.createClientRegionFactory(ClientRegionShortcut.PROXY);
+      factory.addCacheListener(new SessionExpirationCacheListener());
+    }
+
+    // Create the region
+    Region region = factory.create(getSessionManager().getRegionName());
+
+    /*
+     * If we're using an empty client region, we register interest so that
+     * expired sessions are destroyed correctly.
+     */
+    if (!getSessionManager().getEnableLocalCache()) {
+      region.registerInterest("ALL_KEYS", InterestResultPolicy.KEYS);
+    }
+
+    return region;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java
new file mode 100644
index 0000000..0ae17f2
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java
@@ -0,0 +1,68 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 com.gemstone.gemfire.modules.session.catalina;
+
+import org.apache.catalina.Manager;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+
+public class CommitSessionValve extends ValveBase {
+
+  private static final Log log = LogFactory.getLog(CommitSessionValve.class);
+
+  protected static final String info = "com.gemstone.gemfire.modules.session.catalina.CommitSessionValve/1.0";
+
+  public CommitSessionValve() {
+    log.info("Initialized");
+  }
+
+  @Override
+  public void invoke(Request request, Response response) throws IOException, ServletException {
+    // Get the Manager
+    Manager manager = request.getContext().getManager();
+    DeltaSessionFacade session = null;
+
+    // Invoke the next Valve
+    try {
+      getNext().invoke(request, response);
+    } finally {
+      // Commit and if the correct Manager was found
+      if (manager instanceof DeltaSessionManager) {
+        session = (DeltaSessionFacade) request.getSession(false);
+        if (session != null) {
+          if (session.isValid()) {
+            ((DeltaSessionManager) manager).removeTouchedSession(session.getId());
+            session.commit();
+            if (manager.getContainer().getLogger().isDebugEnabled()) {
+              manager.getContainer().getLogger().debug(session + ": Committed.");
+            }
+          } else {
+            if (manager.getContainer().getLogger().isDebugEnabled()) {
+              manager.getContainer().getLogger().debug(session + ": Not valid so not committing.");
+            }
+          }
+        }
+      }
+    }
+  }
+}