geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject [14/50] [abbrv] incubator-geode git commit: GEODE-14: Integration of GemFire Session Replication and Hibernate modules
Date Tue, 09 Feb 2016 01:30:07 GMT
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/callback/LocalSessionCacheWriter.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/callback/LocalSessionCacheWriter.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/callback/LocalSessionCacheWriter.java
new file mode 100644
index 0000000..0385ebf
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/callback/LocalSessionCacheWriter.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.
+*/
+package com.gemstone.gemfire.modules.session.catalina.callback;
+
+import com.gemstone.gemfire.cache.CacheWriterException;
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.EntryEvent;
+import com.gemstone.gemfire.cache.EntryNotFoundException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
+
+import javax.servlet.http.HttpSession;
+import java.util.Properties;
+
+public class LocalSessionCacheWriter extends CacheWriterAdapter<String, HttpSession> implements Declarable {
+
+  private final Region<String, HttpSession> backingRegion;
+
+  public LocalSessionCacheWriter(Region<String, HttpSession> backingRegion) {
+    this.backingRegion = backingRegion;
+  }
+
+  public void beforeCreate(EntryEvent<String, HttpSession> event) throws CacheWriterException {
+    this.backingRegion.put(event.getKey(), event.getNewValue(), event.getCallbackArgument());
+  }
+
+  public void beforeUpdate(EntryEvent<String, HttpSession> event) throws CacheWriterException {
+    this.backingRegion.put(event.getKey(), event.getNewValue(), event.getCallbackArgument());
+  }
+
+  public void beforeDestroy(EntryEvent<String, HttpSession> event) throws CacheWriterException {
+    try {
+      this.backingRegion.destroy(event.getKey(), event.getCallbackArgument());
+    } catch (EntryNotFoundException e) {
+      // I think it is safe to ignore this exception. The entry could have
+      // expired already in the backing region.
+    }
+  }
+
+  public void close() {
+  }
+
+  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/session/catalina/callback/SessionExpirationCacheListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/callback/SessionExpirationCacheListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/callback/SessionExpirationCacheListener.java
new file mode 100644
index 0000000..dff6d58
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/callback/SessionExpirationCacheListener.java
@@ -0,0 +1,77 @@
+/*
+* 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.callback;
+
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.EntryEvent;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSession;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSessionManager;
+import com.gemstone.gemfire.modules.util.ContextMapper;
+
+import javax.servlet.http.HttpSession;
+import java.util.Properties;
+
+public class SessionExpirationCacheListener extends CacheListenerAdapter<String, HttpSession> implements Declarable {
+
+  public void afterDestroy(EntryEvent<String, HttpSession> event) {
+    // A Session expired. If it was destroyed by GemFire expiration, process it.
+    // If it was destroyed via Session.invalidate, ignore it since it has
+    // already been processed.
+    DeltaSession session = null;
+    if (event.getOperation() == Operation.EXPIRE_DESTROY) {
+      session = (DeltaSession) event.getOldValue();
+    } else {
+      /*
+       * This comes into play when we're dealing with an empty client proxy. We
+       * need the actual destroyed object to come back from the server so that
+       * any associated listeners can fire correctly. Having the destroyed
+       * object come back as the callback arg depends on setting the property
+       * gemfire.EXPIRE_SENDS_ENTRY_AS_CALLBACK.
+       */
+      Object callback = event.getCallbackArgument();
+      if (callback != null && callback instanceof DeltaSession) {
+        session = (DeltaSession) callback;
+        DeltaSessionManager m = ContextMapper.getContext(session.getContextName());
+        if (m != null) {
+          session.setOwner(m);
+        }
+      }
+    }
+    if (session != null) {
+      session.processExpired();
+    }
+  }
+
+  public void init(Properties p) {
+  }
+
+  public boolean equals(Object obj) {
+    // This method is only implemented so that RegionAttributesCreation.sameAs
+    // works properly.
+    if (this == obj) {
+      return true;
+    }
+
+    if (obj == null || !(obj instanceof SessionExpirationCacheListener)) {
+      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/catalina/internal/DeltaSessionAttributeEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionAttributeEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionAttributeEvent.java
new file mode 100644
index 0000000..90b6f28
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionAttributeEvent.java
@@ -0,0 +1,25 @@
+/*
+* 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.internal;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSession;
+
+public interface DeltaSessionAttributeEvent extends DataSerializable {
+
+  public void apply(DeltaSession session);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionAttributeEventBatch.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionAttributeEventBatch.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionAttributeEventBatch.java
new file mode 100644
index 0000000..47df071
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionAttributeEventBatch.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.session.catalina.internal;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.gatewaydelta.AbstractGatewayDeltaEvent;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSession;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@SuppressWarnings("serial")
+public class DeltaSessionAttributeEventBatch extends AbstractGatewayDeltaEvent {
+
+  private List<DeltaSessionAttributeEvent> eventQueue;
+
+  public DeltaSessionAttributeEventBatch() {
+  }
+
+  public DeltaSessionAttributeEventBatch(String regionName, String sessionId,
+      List<DeltaSessionAttributeEvent> eventQueue) {
+    super(regionName, sessionId);
+    this.eventQueue = eventQueue;
+  }
+
+  public List<DeltaSessionAttributeEvent> getEventQueue() {
+    return this.eventQueue;
+  }
+
+  public void apply(Cache cache) {
+    Region<String, DeltaSession> region = getRegion(cache);
+    DeltaSession session = region.get(this.key);
+    if (session == null) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("Session ").append(this.key).append(" was not found while attempting to apply ").append(this);
+      cache.getLogger().warning(builder.toString());
+    } else {
+      session.applyAttributeEvents(region, this.eventQueue);
+      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.eventQueue = DataSerializer.readArrayList(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    DataSerializer.writeArrayList((ArrayList) this.eventQueue, out);
+  }
+
+  public String toString() {
+    return new StringBuilder().append("DeltaSessionAttributeEventBatch[")
+        .append("regionName=")
+        .append(this.regionName)
+        .append("; sessionId=")
+        .append(this.key)
+        .append("; numberOfEvents=")
+        .append(this.eventQueue.size())
+        .append("]")
+        .toString();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionDestroyAttributeEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionDestroyAttributeEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionDestroyAttributeEvent.java
new file mode 100644
index 0000000..989474f
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionDestroyAttributeEvent.java
@@ -0,0 +1,73 @@
+/*
+* 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.internal;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.Instantiator;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSession;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+
+@SuppressWarnings("serial")
+public class DeltaSessionDestroyAttributeEvent implements DeltaSessionAttributeEvent {
+
+  private String attributeName;
+
+  public DeltaSessionDestroyAttributeEvent() {
+  }
+
+  public DeltaSessionDestroyAttributeEvent(String attributeName) {
+    this.attributeName = attributeName;
+  }
+
+  public String getAttributeName() {
+    return this.attributeName;
+  }
+
+  public void apply(DeltaSession session) {
+    session.localDestroyAttribute(this.attributeName);
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.attributeName = DataSerializer.readString(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeString(this.attributeName, out);
+  }
+
+  public static void registerInstantiator(int id) {
+    Instantiator.register(new Instantiator(DeltaSessionDestroyAttributeEvent.class, id) {
+      public DataSerializable newInstance() {
+        return new DeltaSessionDestroyAttributeEvent();
+      }
+    });
+  }
+
+  public String toString() {
+    return new StringBuilder().append("DeltaSessionDestroyAttributeEvent[")
+        .append("attributeName=")
+        .append(this.attributeName)
+        .append("]")
+        .toString();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionStatistics.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionStatistics.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionStatistics.java
new file mode 100644
index 0000000..2d59103
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionStatistics.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.session.catalina.internal;
+
+import com.gemstone.gemfire.StatisticDescriptor;
+import com.gemstone.gemfire.Statistics;
+import com.gemstone.gemfire.StatisticsFactory;
+import com.gemstone.gemfire.StatisticsType;
+import com.gemstone.gemfire.StatisticsTypeFactory;
+import com.gemstone.gemfire.internal.StatisticsTypeFactoryImpl;
+
+public class DeltaSessionStatistics {
+
+  public static final String typeName = "SessionStatistics";
+
+  private static final StatisticsType type;
+
+  private static final String SESSIONS_CREATED = "sessionsCreated";
+  private static final String SESSIONS_INVALIDATED = "sessionsInvalidated";
+  private static final String SESSIONS_EXPIRED = "sessionsExpired";
+
+  private static final int sessionsCreatedId;
+  private static final int sessionsInvalidatedId;
+  private static final int sessionsExpiredId;
+
+  static {
+    // Initialize type
+    StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();
+    type = f.createType(typeName, typeName,
+        new StatisticDescriptor[]{f.createIntCounter(SESSIONS_CREATED, "The number of sessions created",
+            "operations"), f.createIntCounter(SESSIONS_INVALIDATED,
+            "The number of sessions invalidated by invoking invalidate", "operations"), f.createIntCounter(
+            SESSIONS_EXPIRED, "The number of sessions invalidated by timeout", "operations"),});
+
+    // Initialize id fields
+    sessionsCreatedId = type.nameToId(SESSIONS_CREATED);
+    sessionsInvalidatedId = type.nameToId(SESSIONS_INVALIDATED);
+    sessionsExpiredId = type.nameToId(SESSIONS_EXPIRED);
+  }
+
+  private final Statistics stats;
+
+  public DeltaSessionStatistics(StatisticsFactory factory, String applicationName) {
+    this.stats = factory.createAtomicStatistics(type, typeName + "_" + applicationName);
+  }
+
+  public void close() {
+    this.stats.close();
+  }
+
+  public int getSessionsCreated() {
+    return this.stats.getInt(sessionsCreatedId);
+  }
+
+  public void incSessionsCreated() {
+    this.stats.incInt(sessionsCreatedId, 1);
+  }
+
+  public int getSessionsInvalidated() {
+    return this.stats.getInt(sessionsInvalidatedId);
+  }
+
+  public void incSessionsInvalidated() {
+    this.stats.incInt(sessionsInvalidatedId, 1);
+  }
+
+  public int getSessionsExpired() {
+    return this.stats.getInt(sessionsExpiredId);
+  }
+
+  public void incSessionsExpired() {
+    this.stats.incInt(sessionsExpiredId, 1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionUpdateAttributeEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionUpdateAttributeEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionUpdateAttributeEvent.java
new file mode 100644
index 0000000..6678e55
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/internal/DeltaSessionUpdateAttributeEvent.java
@@ -0,0 +1,83 @@
+/*
+* 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.internal;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.Instantiator;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSession;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+@SuppressWarnings("serial")
+public class DeltaSessionUpdateAttributeEvent implements DeltaSessionAttributeEvent {
+
+  private String attributeName;
+
+  private Object attributeValue;
+
+  public DeltaSessionUpdateAttributeEvent() {
+  }
+
+  public DeltaSessionUpdateAttributeEvent(String attributeName, Object attributeValue) {
+    this.attributeName = attributeName;
+    this.attributeValue = attributeValue;
+  }
+
+  public String getAttributeName() {
+    return this.attributeName;
+  }
+
+  public Object getAttributeValue() {
+    return this.attributeValue;
+  }
+
+  public void apply(DeltaSession session) {
+    session.localUpdateAttribute(this.attributeName, this.attributeValue);
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.attributeName = DataSerializer.readString(in);
+    this.attributeValue = DataSerializer.readObject(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeString(this.attributeName, out);
+    DataSerializer.writeObject(this.attributeValue, out);
+  }
+
+  public static void registerInstantiator(int id) {
+    Instantiator.register(new Instantiator(DeltaSessionUpdateAttributeEvent.class, id) {
+      public DataSerializable newInstance() {
+        return new DeltaSessionUpdateAttributeEvent();
+      }
+    });
+  }
+
+  public String toString() {
+    return new StringBuilder().append("DeltaSessionUpdateAttributeEvent[")
+        .append("attributeName=")
+        .append(this.attributeName)
+        .append("; attributeValue=")
+        .append(this.attributeValue)
+        .append("]")
+        .toString();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/Banner.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/Banner.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/Banner.java
new file mode 100644
index 0000000..dbe8e05
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/Banner.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.
+*/
+package com.gemstone.gemfire.modules.util;
+
+import com.gemstone.gemfire.internal.GemFireVersion;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Properties;
+
+public class Banner {
+
+  private static String VERSION = "unknown";
+
+  private static Properties props = new Properties();
+
+  static {
+    InputStream is = Banner.class.getResourceAsStream("/modules-version.properties");
+    try {
+      props.load(is);
+      VERSION = props.getProperty("version");
+    } catch (IOException e) {
+    }
+  }
+
+  public static String getString() {
+    StringWriter sw = new StringWriter();
+    PrintWriter pw = new PrintWriter(sw);
+    print(pw);
+    pw.close();
+    return sw.toString();
+  }
+
+  private static void print(PrintWriter pw) {
+    pw.println("GemFire Modules");
+    pw.print("Modules version: ");
+    pw.println(VERSION);
+    GemFireVersion.print(pw);
+  }
+
+  private Banner() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/BootstrappingFunction.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/BootstrappingFunction.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/BootstrappingFunction.java
new file mode 100644
index 0000000..827c6f7
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/BootstrappingFunction.java
@@ -0,0 +1,188 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.MembershipListener;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+
+import java.util.List;
+import java.util.Set;
+
+public class BootstrappingFunction implements Function, MembershipListener {
+
+  private static final long serialVersionUID = 1856043174458190605L;
+
+  public static final String ID = "bootstrapping-function";
+
+  private static final int TIME_TO_WAIT_FOR_CACHE = Integer.getInteger("gemfiremodules.timeToWaitForCache", 30000);
+
+  @Override
+  public void execute(FunctionContext context) {
+    // Verify that the cache exists before continuing.
+    // When this function is executed by a remote membership listener, it is
+    // being invoked before the cache is started.
+    Cache cache = verifyCacheExists();
+
+    // Register as membership listener
+    registerAsMembershipListener(cache);
+
+    // Register functions
+    registerFunctions();
+
+    // Return status
+    context.getResultSender().lastResult(Boolean.TRUE);
+  }
+
+  private Cache verifyCacheExists() {
+    int timeToWait = 0;
+    Cache cache = null;
+    while (timeToWait < TIME_TO_WAIT_FOR_CACHE) {
+      try {
+        cache = CacheFactory.getAnyInstance();
+        break;
+      } catch (Exception ignore) {
+        //keep trying and hope for the best
+      }
+      try {
+        Thread.sleep(250);
+      } catch (InterruptedException ie) {
+        Thread.currentThread().interrupt();
+        break;
+      }
+      timeToWait += 250;
+    }
+
+    if (cache == null) {
+      cache = new CacheFactory().create();
+    }
+
+    return cache;
+  }
+
+  private void registerAsMembershipListener(Cache cache) {
+    DM dm = ((InternalDistributedSystem) cache.getDistributedSystem()).getDistributionManager();
+    dm.addMembershipListener(this);
+  }
+
+  private void registerFunctions() {
+    // Synchronize so that these functions aren't registered twice. The
+    // constructor for the CreateRegionFunction creates a meta region.
+    synchronized (ID) {
+      // Register the create region function if it is not already registered
+      if (!FunctionService.isRegistered(CreateRegionFunction.ID)) {
+        FunctionService.registerFunction(new CreateRegionFunction());
+      }
+
+      // Register the touch partitioned region entries function if it is not already registered
+      if (!FunctionService.isRegistered(TouchPartitionedRegionEntriesFunction.ID)) {
+        FunctionService.registerFunction(new TouchPartitionedRegionEntriesFunction());
+      }
+
+      // Register the touch replicated region entries function if it is not already registered
+      if (!FunctionService.isRegistered(TouchReplicatedRegionEntriesFunction.ID)) {
+        FunctionService.registerFunction(new TouchReplicatedRegionEntriesFunction());
+      }
+
+      // Register the region size function if it is not already registered
+      if (!FunctionService.isRegistered(RegionSizeFunction.ID)) {
+        FunctionService.registerFunction(new RegionSizeFunction());
+      }
+    }
+  }
+
+  private void bootstrapMember(InternalDistributedMember member) {
+    // Create and execute the function
+    Cache cache = CacheFactory.getAnyInstance();
+    Execution execution = FunctionService.onMember(cache.getDistributedSystem(), member);
+    ResultCollector collector = execution.execute(this);
+
+    // Get the result. Nothing is being done with it.
+    try {
+      collector.getResult();
+    } catch (Exception e) {
+      // If an exception occurs in the function, log it.
+      cache.getLogger().warning("Caught unexpected exception:", e);
+    }
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public boolean isHA() {
+    return false;
+  }
+
+  @Override
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+  public int hashCode() {
+    // This method is only implemented so that multiple instances of this class
+    // don't get added as membership listeners.
+    return ID.hashCode();
+  }
+
+  public boolean equals(Object obj) {
+    // This method is only implemented so that multiple instances of this class
+    // don't get added as membership listeners.
+    if (this == obj) {
+      return true;
+    }
+
+    if (obj == null || !(obj instanceof BootstrappingFunction)) {
+      return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public void memberDeparted(InternalDistributedMember id, boolean crashed) {
+  }
+
+  @Override
+  public void memberJoined(InternalDistributedMember id) {
+    bootstrapMember(id);
+  }
+
+  @Override
+  public void memberSuspect(InternalDistributedMember id, InternalDistributedMember whoSuspected, String reason) {
+  }
+
+  @Override
+  public void quorumLost(Set<InternalDistributedMember> internalDistributedMembers,
+      List<InternalDistributedMember> internalDistributedMembers2) {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ClassLoaderObjectInputStream.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ClassLoaderObjectInputStream.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ClassLoaderObjectInputStream.java
new file mode 100644
index 0000000..8cd600e
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ClassLoaderObjectInputStream.java
@@ -0,0 +1,40 @@
+/*
+* 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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+
+/**
+ * This class is used when session attributes need to be reconstructed with a new classloader.
+ */
+public class ClassLoaderObjectInputStream extends ObjectInputStream {
+
+  private final ClassLoader loader;
+
+  public ClassLoaderObjectInputStream(InputStream in, ClassLoader loader) throws IOException {
+    super(in);
+    this.loader = loader;
+  }
+
+  @Override
+  public Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {
+    return Class.forName(desc.getName(), false, loader);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ContextMapper.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ContextMapper.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ContextMapper.java
new file mode 100644
index 0000000..3b7b2de
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ContextMapper.java
@@ -0,0 +1,53 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.modules.session.catalina.DeltaSessionManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This basic singleton class maps context paths to manager instances.
+ * <p>
+ * This class exists for a particular corner case described here. Consider a client-server environment with empty client
+ * regions *and* the need to fire HttpSessionListener destroy events. When a session expires, in this scenario, the
+ * Gemfire destroy events originate on the server and, with some Gemfire hackery, the destroyed object ends up as the
+ * event's callback argument. At the point that the CacheListener then gets the event, the re-constituted session object
+ * has no manager associated and so we need to re-attach a manager to it so that events can be fired correctly.
+ */
+
+public class ContextMapper {
+
+  private static Map<String, DeltaSessionManager> managers = new HashMap<String, DeltaSessionManager>();
+
+  private ContextMapper() {
+    // This is a singleton
+  }
+
+  public static void addContext(String path, DeltaSessionManager manager) {
+    managers.put(path, manager);
+  }
+
+  public static DeltaSessionManager getContext(String path) {
+    return managers.get(path);
+  }
+
+  public static DeltaSessionManager removeContext(String path) {
+    return managers.remove(path);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/CreateRegionFunction.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/CreateRegionFunction.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/CreateRegionFunction.java
new file mode 100644
index 0000000..564ccb7
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/CreateRegionFunction.java
@@ -0,0 +1,245 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionFactory;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.distributed.DistributedLockService;
+import com.gemstone.gemfire.distributed.internal.locks.DistributedMemberLock;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Properties;
+
+public class CreateRegionFunction implements Function, Declarable {
+
+  private static final long serialVersionUID = -9210226844302128969L;
+
+  private final Cache cache;
+
+  private final Region<String, RegionConfiguration> regionConfigurationsRegion;
+
+  public static final String ID = "create-region-function";
+
+  private static final boolean DUMP_SESSION_CACHE_XML = Boolean.getBoolean("gemfiremodules.dumpSessionCacheXml");
+
+  private static final String REGION_CONFIGURATION_METADATA_REGION = "__regionConfigurationMetadata";
+
+  public CreateRegionFunction() {
+    this(CacheFactory.getAnyInstance());
+  }
+
+  public CreateRegionFunction(Cache cache) {
+    this.cache = cache;
+    this.regionConfigurationsRegion = createRegionConfigurationMetadataRegion();
+  }
+
+  public CreateRegionFunction(ClientCache cache) {
+    this.cache = null;
+    this.regionConfigurationsRegion = null;
+  }
+
+  public void execute(FunctionContext context) {
+    RegionConfiguration configuration = (RegionConfiguration) context.getArguments();
+    if (this.cache.getLogger().fineEnabled()) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("Function ").append(ID).append(" received request: ").append(configuration);
+      this.cache.getLogger().fine(builder.toString());
+    }
+
+    // Create or retrieve region
+    RegionStatus status = createOrRetrieveRegion(configuration);
+
+    // Dump XML
+    if (DUMP_SESSION_CACHE_XML) {
+      writeCacheXml();
+    }
+    // Return status
+    context.getResultSender().lastResult(status);
+  }
+
+  private RegionStatus createOrRetrieveRegion(RegionConfiguration configuration) {
+    RegionStatus status = null;
+    String regionName = configuration.getRegionName();
+    if (this.cache.getLogger().fineEnabled()) {
+      this.cache.getLogger().fine("Function " + ID + " retrieving region named: " + regionName);
+    }
+    Region region = this.cache.getRegion(regionName);
+    if (region == null) {
+      status = createRegion(configuration);
+    } else {
+      status = RegionStatus.VALID;
+      try {
+        RegionHelper.validateRegion(this.cache, configuration, region);
+      } catch (Exception e) {
+        if (!e.getMessage()
+            .equals(LocalizedStrings.RegionAttributesCreation_CACHELISTENERS_ARE_NOT_THE_SAME.toLocalizedString())) {
+          this.cache.getLogger().warning(e);
+        }
+        status = RegionStatus.INVALID;
+      }
+    }
+    return status;
+  }
+
+  public String getId() {
+    return ID;
+  }
+
+  public boolean optimizeForWrite() {
+    return false;
+  }
+
+  public boolean isHA() {
+    return true;
+  }
+
+  public boolean hasResult() {
+    return true;
+  }
+
+  public void init(Properties properties) {
+  }
+
+  private RegionStatus createRegion(RegionConfiguration configuration) {
+    // Get a distributed lock
+    DistributedMemberLock dml = getDistributedLock();
+    if (this.cache.getLogger().fineEnabled()) {
+      this.cache.getLogger().fine(this + ": Attempting to lock " + dml);
+    }
+    long start = 0, end = 0;
+    RegionStatus status = null;
+    try {
+      if (this.cache.getLogger().fineEnabled()) {
+        start = System.currentTimeMillis();
+      }
+      // Obtain a lock on the distributed lock
+      dml.lockInterruptibly();
+      if (this.cache.getLogger().fineEnabled()) {
+        end = System.currentTimeMillis();
+        this.cache.getLogger().fine(this + ": Obtained lock on " + dml + " in " + (end - start) + " ms");
+      }
+
+      // Attempt to get the region again after the lock has been obtained
+      String regionName = configuration.getRegionName();
+      Region region = this.cache.getRegion(regionName);
+
+      // If it exists now, validate it.
+      // Else put an entry into the sessionRegionConfigurationsRegion
+      // while holding the lock. This will create the region in all VMs.
+      if (region == null) {
+        this.regionConfigurationsRegion.put(regionName, configuration);
+
+        // Retrieve the region after creating it
+        region = this.cache.getRegion(regionName);
+        // If the region is null now, it wasn't created for some reason
+        // (e.g. the region attributes id were invalid)
+        if (region == null) {
+          status = RegionStatus.INVALID;
+        } else {
+          // Create the PR buckets if necessary)
+          if (region instanceof PartitionedRegion) {
+            PartitionedRegion pr = (PartitionedRegion) region;
+            createBuckets(pr);
+          }
+          status = RegionStatus.VALID;
+        }
+      } else {
+        status = RegionStatus.VALID;
+        try {
+          RegionHelper.validateRegion(this.cache, configuration, region);
+        } catch (Exception e) {
+          if (!e.getMessage()
+              .equals(LocalizedStrings.RegionAttributesCreation_CACHELISTENERS_ARE_NOT_THE_SAME.toLocalizedString())) {
+            this.cache.getLogger().warning(e);
+          }
+          status = RegionStatus.INVALID;
+        }
+      }
+    } catch (Exception e) {
+      StringBuilder builder = new StringBuilder();
+      builder.append(this)
+          .append(": Caught Exception attempting to create region named ")
+          .append(configuration.getRegionName())
+          .append(":");
+      this.cache.getLogger().warning(builder.toString(), e);
+      status = RegionStatus.INVALID;
+    } finally {
+      // Unlock the distributed lock
+      try {
+        dml.unlock();
+      } catch (Exception e) {
+      }
+    }
+    return status;
+  }
+
+  private void createBuckets(PartitionedRegion region) {
+    PartitionRegionHelper.assignBucketsToPartitions(region);
+  }
+
+  private Region<String, RegionConfiguration> createRegionConfigurationMetadataRegion() {
+    // a sessionFactory in hibernate could have been re-started
+    // so, it is possible that this region exists already
+    Region<String, RegionConfiguration> r = this.cache.getRegion(REGION_CONFIGURATION_METADATA_REGION);
+    if (r != null) {
+      return r;
+    }
+    RegionFactory<String, RegionConfiguration> factory = this.cache.createRegionFactory(RegionShortcut.REPLICATE);
+    factory.addCacheListener(new RegionConfigurationCacheListener());
+    return factory.create(REGION_CONFIGURATION_METADATA_REGION);
+  }
+
+  private void writeCacheXml() {
+    File file = new File("cache-" + System.currentTimeMillis() + ".xml");
+    try {
+      PrintWriter pw = new PrintWriter(new FileWriter(file), true);
+      CacheXmlGenerator.generate(this.cache, pw);
+      pw.close();
+    } catch (IOException e) {
+    }
+  }
+
+  private DistributedMemberLock getDistributedLock() {
+    String dlsName = this.regionConfigurationsRegion.getName();
+    DistributedLockService lockService = initializeDistributedLockService(dlsName);
+    String lockToken = dlsName + "_token";
+    return new DistributedMemberLock(lockService, lockToken);
+  }
+
+  private DistributedLockService initializeDistributedLockService(String dlsName) {
+    DistributedLockService lockService = DistributedLockService.getServiceNamed(dlsName);
+    if (lockService == null) {
+      lockService = DistributedLockService.create(dlsName, this.cache.getDistributedSystem());
+    }
+    return lockService;
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/DebugCacheListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/DebugCacheListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/DebugCacheListener.java
new file mode 100644
index 0000000..baca5b8
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/DebugCacheListener.java
@@ -0,0 +1,72 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.EntryEvent;
+import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+
+import java.util.Properties;
+
+@SuppressWarnings("unchecked")
+public class DebugCacheListener extends CacheListenerAdapter implements Declarable {
+
+  public void afterCreate(EntryEvent event) {
+    log(event);
+  }
+
+  public void afterUpdate(EntryEvent event) {
+    log(event);
+  }
+
+  public void afterInvalidate(EntryEvent event) {
+    log(event);
+  }
+
+  public void afterDestroy(EntryEvent event) {
+    log(event);
+  }
+
+  private void log(EntryEvent event) {
+    StringBuilder builder = new StringBuilder();
+    builder.append("DebugCacheListener: Received ")
+        .append(event.getOperation())
+        .append(" for key=")
+        .append(event.getKey());
+    if (event.getNewValue() != null) {
+      builder.append("; value=").append(event.getNewValue());
+    }
+    event.getRegion().getCache().getLogger().info(builder.toString());
+  }
+
+  public void init(Properties p) {
+  }
+
+  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 DebugCacheListener)) {
+      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/util/ModuleStatistics.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ModuleStatistics.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ModuleStatistics.java
new file mode 100644
index 0000000..dff5b95
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/ModuleStatistics.java
@@ -0,0 +1,91 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.StatisticDescriptor;
+import com.gemstone.gemfire.Statistics;
+import com.gemstone.gemfire.StatisticsFactory;
+import com.gemstone.gemfire.StatisticsType;
+import com.gemstone.gemfire.StatisticsTypeFactory;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.internal.StatisticsTypeFactoryImpl;
+
+/**
+ * Statistics for modules.
+ *
+ * @author sbawaska
+ */
+public class ModuleStatistics {
+
+  private static final StatisticsType type;
+
+  private static final int cacheHitsId;
+
+  private static final int cacheMissesId;
+
+  private static final int hibernateEntityDestroyJobsScheduledId;
+
+  static {
+    StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();
+    type = f.createType("pluginStats", "statistics for hibernate plugin and hibernate L2 cache",
+        new StatisticDescriptor[]{f.createLongCounter("cacheHits", "number of times an entity was found in L2 cache",
+            "count"), f.createLongCounter("cacheMisses", "number of times an entity was NOT found in l2 cache",
+            "count"), f.createLongCounter("hibernateEntityDestroyJobsScheduled",
+            "number of entities scheduled for destroy because of version conflict with a remote member", "jobs")});
+
+    cacheHitsId = type.nameToId("cacheHits");
+    cacheMissesId = type.nameToId("cacheMisses");
+    hibernateEntityDestroyJobsScheduledId = type.nameToId("hibernateEntityDestroyJobsScheduled");
+  }
+
+  private final Statistics stats;
+
+  private static ModuleStatistics instance;
+
+  private ModuleStatistics(StatisticsFactory factory) {
+    this.stats = factory.createAtomicStatistics(type, "PluginStatistics");
+  }
+
+  public static ModuleStatistics getInstance(DistributedSystem system) {
+    synchronized (ModuleStatistics.class) {
+      if (instance == null) {
+        instance = new ModuleStatistics(system);
+      }
+    }
+    return instance;
+  }
+
+  public void incCacheHit() {
+    stats.incLong(cacheHitsId, 1);
+  }
+
+  public long getCacheHits() {
+    return stats.getLong(cacheHitsId);
+  }
+
+  public void incCacheMiss() {
+    stats.incLong(cacheMissesId, 1);
+  }
+
+  public long getCacheMiss() {
+    return stats.getLong(cacheMissesId);
+  }
+
+  public void incHibernateDestroyJobsScheduled() {
+    stats.incLong(hibernateEntityDestroyJobsScheduledId, 1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfiguration.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfiguration.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfiguration.java
new file mode 100644
index 0000000..5b025bc
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfiguration.java
@@ -0,0 +1,308 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.Instantiator;
+import com.gemstone.gemfire.cache.CacheWriter;
+import com.gemstone.gemfire.cache.CustomExpiry;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Class <code>RegionConfiguration</code> encapsulates the configuration attributes for a <code>Region</code> to be
+ * created on the server.
+ *
+ * @author Barry Oglesby
+ * @since 6.5
+ */
+@SuppressWarnings({"serial", "unchecked"})
+public class RegionConfiguration implements DataSerializable {
+
+  /**
+   * The name of the <code>Region</code> to be created
+   */
+  private String regionName;
+
+  /**
+   * The id of the <code>RegionAttributes</code> to be used
+   */
+  private String regionAttributesId;
+
+  /**
+   * The default max inactive interval. The default value is -1.
+   */
+  public static final int DEFAULT_MAX_INACTIVE_INTERVAL = -1;
+
+  /**
+   * The maximum time interval in seconds before entries are expired
+   */
+  private int maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL;
+
+  /**
+   * The <code>CustomExpiry</code> to be used
+   */
+  private CustomExpiry customExpiry;
+
+  /**
+   * Whether delta replication across a <code>Gateway</code> is enabled.
+   */
+  private boolean enableGatewayDeltaReplication = false;
+
+  /**
+   * Whether replication across a <code>Gateway</code> is enabled.
+   */
+  private boolean enableGatewayReplication = false;
+
+  /**
+   * Whether to add a <code>DebugCacheListener</code> to the <code>Region</code>.
+   */
+  private boolean enableDebugListener = false;
+
+  /**
+   * Whether to add a cache listener for session expiration events
+   */
+  private boolean enableSessionExpirationCacheListener = false;
+
+  /**
+   * name for the CacheWriter to be associated with this region. This cache writer must have a zero arg constructor and
+   * must be present on the classpath on the server.
+   */
+  private String cacheWriterName;
+
+  /**
+   * Default constructor used by the <code>DataSerialiable</code> interface
+   */
+  public RegionConfiguration() {
+  }
+
+  /**
+   * Sets the name of the <code>Region</code> to be created
+   *
+   * @param regionName The name of the <code>Region</code> to be created
+   */
+  public void setRegionName(String regionName) {
+    this.regionName = regionName;
+  }
+
+  /**
+   * Returns the name of the <code>Region</code> to be created
+   *
+   * @return the name of the <code>Region</code> to be created
+   */
+  public String getRegionName() {
+    return this.regionName;
+  }
+
+  /**
+   * Sets the id of the <code>RegionAttributes</code> to be used
+   *
+   * @param regionAttributesId The id of the <code>RegionAttributes</code> to be used
+   */
+  public void setRegionAttributesId(String regionAttributesId) {
+    this.regionAttributesId = regionAttributesId;
+  }
+
+  /**
+   * Returns the id of the <code>RegionAttributes</code> to be used
+   *
+   * @return the id of the <code>RegionAttributes</code> to be used
+   */
+  public String getRegionAttributesId() {
+    return this.regionAttributesId;
+  }
+
+  /**
+   * Sets the maximum time interval in seconds before entries are expired
+   *
+   * @param maxInactiveInterval The maximum time interval in seconds before entries are expired
+   */
+  public void setMaxInactiveInterval(int maxInactiveInterval) {
+    this.maxInactiveInterval = maxInactiveInterval;
+  }
+
+  /**
+   * Returns the maximum time interval in seconds entries are expired
+   *
+   * @return the maximum time interval in seconds before entries are expired
+   */
+  public int getMaxInactiveInterval() {
+    return this.maxInactiveInterval;
+  }
+
+  /**
+   * Sets the <code>CustomExpiry</code> to be used
+   *
+   * @param customExpiry The <code>CustomExpiry</code> to be used
+   */
+  public void setCustomExpiry(CustomExpiry customExpiry) {
+    this.customExpiry = customExpiry;
+  }
+
+  /**
+   * Returns the <code>CustomExpiry</code> to be used
+   *
+   * @return the <code>CustomExpiry</code> to be used
+   */
+  public CustomExpiry getCustomExpiry() {
+    return this.customExpiry;
+  }
+
+  /**
+   * Enables/disables delta replication across a <code>Gateway</code>.
+   *
+   * @param enableGatewayDeltaReplication true to enable, false to disable gateway delta replication.
+   */
+  public void setEnableGatewayDeltaReplication(boolean enableGatewayDeltaReplication) {
+    this.enableGatewayDeltaReplication = enableGatewayDeltaReplication;
+  }
+
+  /**
+   * Returns whether delta replication across a <code>Gateway</code> is enabled.
+   *
+   * @return whether delta replication across a <code>Gateway</code> is enabled
+   */
+  public boolean getEnableGatewayDeltaReplication() {
+    return this.enableGatewayDeltaReplication;
+  }
+
+  /**
+   * Enables/disables replication across a <code>Gateway</code>.
+   *
+   * @param enableGatewayReplication true to enable, false to disable gateway replication.
+   */
+  public void setEnableGatewayReplication(boolean enableGatewayReplication) {
+    this.enableGatewayReplication = enableGatewayReplication;
+  }
+
+  /**
+   * Returns whether replication across a <code>Gateway</code> is enabled.
+   *
+   * @return whether replication across a <code>Gateway</code> is enabled
+   */
+  public boolean getEnableGatewayReplication() {
+    return this.enableGatewayReplication;
+  }
+
+  /**
+   * Enables/disables a debug <code>CacheListener</code>.
+   *
+   * @param enableDebugListener true to enable, false to disable debug <code>CacheListener</code>.
+   */
+  public void setEnableDebugListener(boolean enableDebugListener) {
+    this.enableDebugListener = enableDebugListener;
+  }
+
+  /**
+   * Returns whether a debug <code>CacheListener</code> is enabled.
+   *
+   * @return whether a debug <code>CacheListener</code> is enabled
+   */
+  public boolean getEnableDebugListener() {
+    return this.enableDebugListener;
+  }
+
+  public void setSessionExpirationCacheListener(boolean enableSessionExpirationCacheListener) {
+    this.enableSessionExpirationCacheListener = enableSessionExpirationCacheListener;
+  }
+
+  public boolean getSessionExpirationCacheListener() {
+    return this.enableSessionExpirationCacheListener;
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeString(this.regionName, out);
+    DataSerializer.writeString(this.regionAttributesId, out);
+    DataSerializer.writePrimitiveInt(this.maxInactiveInterval, out);
+    DataSerializer.writeObject(this.customExpiry, out);
+    DataSerializer.writeBoolean(this.enableGatewayDeltaReplication, out);
+    DataSerializer.writeBoolean(this.enableGatewayReplication, out);
+    DataSerializer.writeBoolean(this.enableDebugListener, out);
+    DataSerializer.writeString(this.cacheWriterName, out);
+    DataSerializer.writeBoolean(this.enableSessionExpirationCacheListener, out);
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.regionName = DataSerializer.readString(in);
+    this.regionAttributesId = DataSerializer.readString(in);
+    this.maxInactiveInterval = DataSerializer.readPrimitiveInt(in);
+    this.customExpiry = DataSerializer.readObject(in);
+    this.enableGatewayDeltaReplication = DataSerializer.readBoolean(in);
+    this.enableGatewayReplication = DataSerializer.readBoolean(in);
+    this.enableDebugListener = DataSerializer.readBoolean(in);
+    this.cacheWriterName = DataSerializer.readString(in);
+
+    // This allows for backwards compatibility with 2.1 clients
+    if (((InputStream) in).available() > 0) {
+      this.enableSessionExpirationCacheListener = DataSerializer.readBoolean(in);
+    } else {
+      this.enableSessionExpirationCacheListener = false;
+    }
+  }
+
+  /**
+   * Registers an <code>Instantiator</code> for the <code>SessionConfiguration</code> class
+   */
+  public static void registerInstantiator(int id) {
+    Instantiator.register(new Instantiator(RegionConfiguration.class, id) {
+      public DataSerializable newInstance() {
+        return new RegionConfiguration();
+      }
+    });
+  }
+
+  public String toString() {
+    return new StringBuilder().append("RegionConfiguration[")
+        .append("regionName=")
+        .append(this.regionName)
+        .append("; regionAttributesId=")
+        .append(this.regionAttributesId)
+        .append("; maxInactiveInterval=")
+        .append(this.maxInactiveInterval)
+        .append("; enableGatewayDeltaReplication=")
+        .append(this.enableGatewayDeltaReplication)
+        .append("; enableGatewayReplication=")
+        .append(this.enableGatewayReplication)
+        .append("; enableDebugListener=")
+        .append(this.enableDebugListener)
+        .append("; enableSessionExpirationCacheListener=")
+        .append(this.enableSessionExpirationCacheListener)
+        .append("; cacheWriter=")
+        .append(this.cacheWriterName)
+        .append("]")
+        .toString();
+  }
+
+  /**
+   * set the fully qualified name of the {@link CacheWriter} to be created on the server. The cacheWriter must have a
+   * zero arg constructor, and must be present on the classpath on the server.
+   *
+   * @param cacheWriterName fully qualified class name of the cacheWriter
+   */
+  public void setCacheWriterName(String cacheWriterName) {
+    this.cacheWriterName = cacheWriterName;
+  }
+
+  public String getCacheWriterName() {
+    return cacheWriterName;
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfigurationCacheListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfigurationCacheListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfigurationCacheListener.java
new file mode 100644
index 0000000..c25082b
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionConfigurationCacheListener.java
@@ -0,0 +1,114 @@
+/*
+* 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.util;
+
+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.Region;
+import com.gemstone.gemfire.cache.RegionEvent;
+import com.gemstone.gemfire.cache.RegionExistsException;
+import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+
+import java.util.Properties;
+
+public class RegionConfigurationCacheListener extends CacheListenerAdapter<String, RegionConfiguration> implements Declarable {
+
+  private Cache cache;
+
+  public RegionConfigurationCacheListener() {
+    this.cache = CacheFactory.getAnyInstance();
+  }
+
+  public void afterCreate(EntryEvent<String, RegionConfiguration> event) {
+    RegionConfiguration configuration = event.getNewValue();
+    if (this.cache.getLogger().fineEnabled()) {
+      this.cache.getLogger().fine("RegionConfigurationCacheListener received afterCreate for region " + event.getKey());
+    }
+    // Create region
+    // this is a replicate region, and many VMs can be doing create region
+    // simultaneously, so ignore the RegionExistsException
+    try {
+      Region region = RegionHelper.createRegion(this.cache, configuration);
+      if (this.cache.getLogger().fineEnabled()) {
+        this.cache.getLogger().fine("RegionConfigurationCacheListener created region: " + region);
+      }
+    } catch (RegionExistsException exists) {
+      // ignore
+      this.cache.getLogger().fine("Region with configuration " + configuration + " existed");
+    }
+  }
+
+  @Override
+  public void afterUpdate(EntryEvent<String, RegionConfiguration> event) {
+    // a region could have been destroyed and then
+    // re-created, we want to create region again
+    // on remote nodes
+    afterCreate(event);
+  }
+
+  public void afterRegionCreate(RegionEvent<String, RegionConfiguration> event) {
+    StringBuilder builder1 = null, builder2 = null;
+    Region<String, RegionConfiguration> region = event.getRegion();
+    if (this.cache.getLogger().fineEnabled()) {
+      builder1 = new StringBuilder();
+      int regionSize = region.size();
+      if (regionSize > 0) {
+        builder1.append("RegionConfigurationCacheListener region ")
+            .append(region.getName())
+            .append(" has been initialized with the following ")
+            .append(regionSize)
+            .append(" region configurations:\n");
+        builder2 = new StringBuilder();
+        builder2.append("RegionConfigurationCacheListener created the following ")
+            .append(regionSize)
+            .append(" regions:\n");
+      } else {
+        builder1.append("RegionConfigurationCacheListener region ")
+            .append(region.getName())
+            .append(" has been initialized with no region configurations");
+      }
+    }
+    for (RegionConfiguration configuration : region.values()) {
+      if (this.cache.getLogger().fineEnabled()) {
+        builder1.append("\t").append(configuration);
+      }
+      try {
+        Region createRegion = RegionHelper.createRegion(this.cache, configuration);
+        if (this.cache.getLogger().fineEnabled()) {
+          builder2.append("\t").append(createRegion);
+        }
+      } catch (RegionExistsException exists) {
+        // could have been concurrently created by another function
+        if (this.cache.getLogger().fineEnabled()) {
+          builder2.append("\t").append(" region existed");
+        }
+      }
+
+    }
+    if (this.cache.getLogger().fineEnabled()) {
+      this.cache.getLogger().fine(builder1.toString());
+      if (builder2 != null) {
+        this.cache.getLogger().fine(builder2.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/util/RegionHelper.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionHelper.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionHelper.java
new file mode 100644
index 0000000..78e4423
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionHelper.java
@@ -0,0 +1,241 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.cache.AttributesFactory;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheWriter;
+import com.gemstone.gemfire.cache.ExpirationAction;
+import com.gemstone.gemfire.cache.ExpirationAttributes;
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.cache.control.RebalanceFactory;
+import com.gemstone.gemfire.cache.control.RebalanceOperation;
+import com.gemstone.gemfire.cache.control.RebalanceResults;
+import com.gemstone.gemfire.cache.control.ResourceManager;
+import com.gemstone.gemfire.cache.partition.PartitionMemberInfo;
+import com.gemstone.gemfire.cache.partition.PartitionRebalanceInfo;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
+import com.gemstone.gemfire.internal.cache.xmlcache.RegionAttributesCreation;
+import com.gemstone.gemfire.modules.gatewaydelta.GatewayDeltaForwarderCacheListener;
+import com.gemstone.gemfire.modules.session.catalina.callback.SessionExpirationCacheListener;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CancellationException;
+
+@SuppressWarnings({"deprecation", "unchecked"})
+public class RegionHelper {
+
+  public static final String NAME = "gemfire_modules";
+
+  public static Region createRegion(Cache cache, RegionConfiguration configuration) {
+    // Use the createRegion method so that the RegionAttributes creation can be reused by validate.
+    RegionAttributes requestedRegionAttributes = getRegionAttributes(cache, configuration);
+    Region region = cache.createRegion(configuration.getRegionName(), requestedRegionAttributes);
+
+    // Log the cache xml if debugging is enabled. I'd like to be able to just
+    // log the region, but that API is not available.
+    if (configuration.getEnableDebugListener()) {
+      cache.getLogger().info("Created new session region: " + region);
+      cache.getLogger().info(generateCacheXml(cache));
+    }
+    return region;
+  }
+
+  public static void validateRegion(Cache cache, RegionConfiguration configuration, Region region) {
+    // Get the attributes of the existing region
+    RegionAttributes existingAttributes = region.getAttributes();
+
+    // Create region attributes creation on existing region attributes.
+    // The RAC is created to execute the sameAs method.
+    RegionAttributesCreation existingRACreation = new RegionAttributesCreation(existingAttributes, false);
+
+    // Create requested region attributes
+    RegionAttributes requestedRegionAttributes = getRegionAttributes(cache, configuration);
+
+    // Compare the two region attributes. This method either returns true or throws a RuntimeException.
+    existingRACreation.sameAs(requestedRegionAttributes);
+  }
+
+  public static RebalanceResults rebalanceRegion(Region region) throws CancellationException, InterruptedException {
+    String regionName = region.getName(); // FilterByName only looks at name and not full path
+    if (!PartitionRegionHelper.isPartitionedRegion(region)) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("Region ")
+          .append(regionName)
+          .append(" is not partitioned. Instead, it is ")
+          .append(region.getAttributes().getDataPolicy())
+          .append(". It can't be rebalanced.");
+      throw new IllegalArgumentException(builder.toString());
+    }
+
+    // Rebalance the region
+    ResourceManager resourceManager = region.getCache().getResourceManager();
+    RebalanceFactory rebalanceFactory = resourceManager.createRebalanceFactory();
+    Set<String> regionsToRebalance = new HashSet<String>();
+    regionsToRebalance.add(regionName);
+    rebalanceFactory.includeRegions(regionsToRebalance);
+    RebalanceOperation rebalanceOperation = rebalanceFactory.start();
+
+    // Return the results
+    return rebalanceOperation.getResults();
+  }
+
+  public static RebalanceResults rebalanceCache(GemFireCache cache) throws CancellationException, InterruptedException {
+    ResourceManager resourceManager = cache.getResourceManager();
+    RebalanceFactory rebalanceFactory = resourceManager.createRebalanceFactory();
+    RebalanceOperation rebalanceOperation = rebalanceFactory.start();
+    return rebalanceOperation.getResults();
+  }
+
+  public static String generateCacheXml(Cache cache) {
+    try {
+      StringWriter sw = new StringWriter();
+      PrintWriter pw = new PrintWriter(sw, true);
+      CacheXmlGenerator.generate(cache, pw);
+      pw.close();
+      return sw.toString();
+    } catch (Exception ex) {
+      return "";
+    }
+  }
+
+  private static RegionAttributes getRegionAttributes(Cache cache, RegionConfiguration configuration) {
+    // Create the requested attributes
+    RegionAttributes baseRequestedAttributes = cache.getRegionAttributes(configuration.getRegionAttributesId());
+    if (baseRequestedAttributes == null) {
+      throw new IllegalArgumentException(
+          "No region attributes named " + configuration.getRegionAttributesId() + " are defined.");
+    }
+    AttributesFactory requestedFactory = new AttributesFactory(baseRequestedAttributes);
+
+    // Set the expiration time and action if necessary
+    int maxInactiveInterval = configuration.getMaxInactiveInterval();
+    if (maxInactiveInterval != RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL) {
+      requestedFactory.setStatisticsEnabled(true);
+      if (configuration.getCustomExpiry() == null) {
+        requestedFactory.setEntryIdleTimeout(new ExpirationAttributes(maxInactiveInterval, ExpirationAction.DESTROY));
+      } else {
+        requestedFactory.setCustomEntryIdleTimeout(configuration.getCustomExpiry());
+      }
+    }
+
+    // Add the gateway delta region cache listener if necessary
+    if (configuration.getEnableGatewayDeltaReplication()) {
+      // Add the listener that forwards created/destroyed deltas to the gateway
+      requestedFactory.addCacheListener(new GatewayDeltaForwarderCacheListener(cache));
+    }
+
+    // Enable gateway replication if necessary
+    // TODO: Disabled for WAN
+//    requestedFactory.setEnableGateway(configuration.getEnableGatewayReplication());
+
+    // Add the debug cache listener if necessary
+    if (configuration.getEnableDebugListener()) {
+      requestedFactory.addCacheListener(new DebugCacheListener());
+    }
+
+    if (configuration.getSessionExpirationCacheListener()) {
+      requestedFactory.addCacheListener(new SessionExpirationCacheListener());
+    }
+
+    // Add the cacheWriter if necessary
+    if (configuration.getCacheWriterName() != null) {
+      try {
+        CacheWriter writer = (CacheWriter) Class.forName(configuration.getCacheWriterName()).newInstance();
+        requestedFactory.setCacheWriter(writer);
+      } catch (InstantiationException e) {
+        throw new RuntimeException("Could not set a cacheWriter for the region", e);
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException("Could not set a cacheWriter for the region", e);
+      } catch (ClassNotFoundException e) {
+        throw new RuntimeException("Could not set a cacheWriter for the region", e);
+      }
+    }
+    return requestedFactory.create();
+  }
+
+  private RegionHelper() {
+  }
+
+  public static String getRebalanceResultsMessage(RebalanceResults results) {
+    StringBuilder builder = new StringBuilder();
+    for (PartitionRebalanceInfo rebalanceInfo : results.getPartitionRebalanceDetails()) {
+      // Log the overall results
+      fillInRebalanceResultsSummary(builder, rebalanceInfo);
+
+      // Log the 'Before' results
+      fillInRebalanceResultsMemberDetails(builder, rebalanceInfo.getPartitionMemberDetailsBefore(), "Before");
+
+      // Log the 'After' results
+      fillInRebalanceResultsMemberDetails(builder, rebalanceInfo.getPartitionMemberDetailsAfter(), "After");
+    }
+    return builder.toString();
+  }
+
+  private static void fillInRebalanceResultsSummary(StringBuilder builder, PartitionRebalanceInfo rebalanceInfo) {
+    builder.append("\nRebalanced region ")
+        .append(rebalanceInfo.getRegionPath())
+        .append(" in ")
+        .append(rebalanceInfo.getTime())
+        .append(" ms")
+
+        .append("\nCreated ")
+        .append(rebalanceInfo.getBucketCreatesCompleted())
+        .append(" buckets containing ")
+        .append(rebalanceInfo.getBucketCreateBytes())
+        .append(" bytes in ")
+        .append(rebalanceInfo.getBucketCreateTime())
+        .append(" ms")
+
+        .append("\nTransferred ")
+        .append(rebalanceInfo.getBucketTransfersCompleted())
+        .append(" buckets containing ")
+        .append(rebalanceInfo.getBucketTransferBytes())
+        .append(" bytes in ")
+        .append(rebalanceInfo.getBucketTransferTime())
+        .append(" ms")
+
+        .append("\nTransferred ")
+        .append(rebalanceInfo.getPrimaryTransfersCompleted())
+        .append(" primary buckets in ")
+        .append(rebalanceInfo.getPrimaryTransferTime())
+        .append(" ms");
+  }
+
+  private static void fillInRebalanceResultsMemberDetails(StringBuilder builder, Set<PartitionMemberInfo> memberInfoSet,
+      String when) {
+    builder.append("\nMember Info ").append(when).append(" Rebalance:\n");
+    for (PartitionMemberInfo info : memberInfoSet) {
+      builder.append("\tdistributedMember=")
+          .append(info.getDistributedMember())
+          .append(", configuredMaxMemory=")
+          .append(info.getConfiguredMaxMemory())
+          .append(", size=")
+          .append(info.getSize())
+          .append(", bucketCount=")
+          .append(info.getBucketCount())
+          .append(", primaryCount=")
+          .append(info.getPrimaryCount());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionSizeFunction.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionSizeFunction.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionSizeFunction.java
new file mode 100644
index 0000000..13791a3
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionSizeFunction.java
@@ -0,0 +1,56 @@
+/*
+* 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.util;
+
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
+
+import java.util.Properties;
+
+public class RegionSizeFunction implements Function, Declarable {
+
+  private static final long serialVersionUID = -2791590491585777990L;
+
+  public static final String ID = "region-size-function";
+
+  public void execute(FunctionContext context) {
+    RegionFunctionContext rfc = (RegionFunctionContext) context;
+    context.getResultSender().lastResult(rfc.getDataSet().size());
+  }
+
+  public String getId() {
+    return ID;
+  }
+
+  public boolean hasResult() {
+    return true;
+  }
+
+  public boolean optimizeForWrite() {
+    return true;
+  }
+
+  public boolean isHA() {
+    return true;
+  }
+
+  @Override
+  public void init(Properties arg0) {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionStatus.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionStatus.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionStatus.java
new file mode 100644
index 0000000..fec1fc1
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/util/RegionStatus.java
@@ -0,0 +1,21 @@
+/*
+ * 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.util;
+
+public enum RegionStatus {
+  VALID, INVALID
+}


Mime
View raw message