geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dschnei...@apache.org
Subject [06/20] incubator-geode git commit: GEODE-14: Imported modules from geode-1.0.0-SNAPSHOT-2.src.tar
Date Mon, 06 Jul 2015 21:46:27 GMT
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/filter/util/ThreadLocalSession.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/filter/util/ThreadLocalSession.java b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/filter/util/ThreadLocalSession.java
new file mode 100644
index 0000000..3d04bbb
--- /dev/null
+++ b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/filter/util/ThreadLocalSession.java
@@ -0,0 +1,29 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.filter.util;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ */
+public class ThreadLocalSession {
+  private static ThreadLocal<HttpSession> threadLocal =
+      new ThreadLocal<HttpSession>();
+
+  public static HttpSession get() {
+    return threadLocal.get();
+  }
+
+  public static void set(HttpSession session) {
+    threadLocal.set(session);
+  }
+
+  public static void remove() {
+    threadLocal.remove();
+  }
+}

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

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

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

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

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/build.gradle
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/build.gradle b/modules/gemfire-modules-slf4j-weblogic/build.gradle
new file mode 100644
index 0000000..1d7fc24
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/build.gradle
@@ -0,0 +1,21 @@
+// In order to compile this module you need to reference your wlclient.jar
+// in gradle.properties.
+
+dependencies {
+  compile files(WEBLOGIC_LOGGING_JAR)
+}
+
+compileJava.onlyIf {
+  def buildit = project.hasProperty('WEBLOGIC_LOGGING_JAR') && WEBLOGIC_LOGGING_JAR != ""
+  if (! buildit) {
+    println('')
+    println('****************************************************************')
+    println('***   Warning: NOT building slf4j-weblogic binding!          ***')
+    println('***   See gemfire-modules-slf4j-weblogic/gradle.properties   ***')
+    println('****************************************************************')
+    println('')
+  }
+  return buildit
+}
+
+jar.onlyIf { compileJava.didWork }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/gradle.properties
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/gradle.properties b/modules/gemfire-modules-slf4j-weblogic/gradle.properties
new file mode 100644
index 0000000..4b76aa2
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/gradle.properties
@@ -0,0 +1,5 @@
+# Ensure that the Weblogic wlclient.jar is referenced here for this module to
+# build correctly.
+# This jar can typically be found as $MW_HOME/wlserver/server/lib/wlclient.jar
+
+WEBLOGIC_LOGGING_JAR =

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/pom.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/pom.xml b/modules/gemfire-modules-slf4j-weblogic/pom.xml
new file mode 100644
index 0000000..4a86a67
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <artifactId>gemfire-modules-parent</artifactId>
+    <groupId>com.gemstone</groupId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>com.gemstone</groupId>
+  <artifactId>gemfire-modules-slf4j-weblogic</artifactId>
+  <version>${gemfire.modules.version}</version>
+  <name>gemfire-modules-slf4j-weblogic</name>
+  <url>http://maven.apache.org</url>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.bea.core</groupId>
+      <artifactId>i18n</artifactId>
+      <version>1.7.0.0</version>
+      <scope>system</scope>
+      <systemPath>
+        ${basedir}/src/main/resources/lib/com.bea.core.i18n_1.7.0.0.jar
+      </systemPath>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.1</version>
+        <configuration>
+          <!--
+              Unfortunately a scope of 'system' causes the jar to be
+              included in our final artifact which is not desired.
+          -->
+          <excludes>
+            <exclude>**/com.bea.core.i18n*</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
new file mode 100644
index 0000000..5735908
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
@@ -0,0 +1,51 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package org.slf4j.impl;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.spi.LoggerFactoryBinder;
+
+/**
+ * The binding of LoggerFactory class with an actual instance of ILoggerFactory
+ * is performed using information returned by this class.
+ */
+public class StaticLoggerBinder implements LoggerFactoryBinder {
+
+  /**
+   * The unique instance of this class.
+   */
+  public static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
+  /**
+   * Declare the version of the SLF4J API this implementation is compiled
+   * against. The value of this field is usually modified with each release.
+   */
+  // to avoid constant folding by the compiler, this field must *not* be final
+  public static String REQUESTED_API_VERSION = "1.5.5";  // !final
+
+  private static final String loggerFactoryClassStr =
+      WeblogicLoggerAdapter.class.getName();
+  /**
+   * The ILoggerFactory instance returned by the getLoggerFactory method should
+   * always be the same object
+   */
+  private final ILoggerFactory loggerFactory;
+
+  private StaticLoggerBinder() {
+    loggerFactory = new WeblogicLoggerFactory();
+  }
+
+  @Override
+  public ILoggerFactory getLoggerFactory() {
+    return loggerFactory;
+  }
+
+  @Override
+  public String getLoggerFactoryClassStr() {
+    return loggerFactoryClassStr;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMDCBinder.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMDCBinder.java
new file mode 100644
index 0000000..3194040
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMDCBinder.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package org.slf4j.impl;
+
+import org.slf4j.helpers.BasicMDCAdapter;
+import org.slf4j.spi.MDCAdapter;
+
+/**
+ * This implementation is bound to BasicMDCAdapter.
+ */
+public class StaticMDCBinder {
+
+  /**
+   * The unique instance of this class.
+   */
+  public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
+
+  private StaticMDCBinder() {
+  }
+
+  public MDCAdapter getMDCA() {
+    return new BasicMDCAdapter();
+  }
+
+  public String getMDCAdapterClassStr() {
+    return BasicMDCAdapter.class.getName();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
new file mode 100644
index 0000000..7482dda
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
@@ -0,0 +1,37 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package org.slf4j.impl;
+
+import org.slf4j.IMarkerFactory;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.spi.MarkerFactoryBinder;
+
+/**
+ *
+ */
+public class StaticMarkerBinder implements MarkerFactoryBinder {
+
+  /**
+   * The unique instance of this class.
+   */
+  public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
+  final IMarkerFactory markerFactory = new BasicMarkerFactory();
+
+  private StaticMarkerBinder() {
+  }
+
+  @Override
+  public IMarkerFactory getMarkerFactory() {
+    return markerFactory;
+  }
+
+  @Override
+  public String getMarkerFactoryClassStr() {
+    return BasicMarkerFactory.class.getName();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerAdapter.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerAdapter.java b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerAdapter.java
new file mode 100644
index 0000000..9b86db6
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerAdapter.java
@@ -0,0 +1,324 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package org.slf4j.impl;
+
+import org.slf4j.helpers.FormattingTuple;
+import org.slf4j.helpers.MarkerIgnoringBase;
+import org.slf4j.helpers.MessageFormatter;
+import weblogic.logging.NonCatalogLogger;
+
+/**
+ * Very basic class which bridges SLF4J to Weblogic's NonCatalogLogger
+ */
+public class WeblogicLoggerAdapter extends MarkerIgnoringBase {
+
+  private static final long serialVersionUID = 2372632822791L;
+
+  static String SELF = WeblogicLoggerAdapter.class.getName();
+
+  static String SUPER = MarkerIgnoringBase.class.getName();
+
+  final NonCatalogLogger logger;
+
+  /**
+   * WeblogicLoggerAdapter constructor should have only package access so that
+   * only WeblogicLoggerAdapter be able to create one.
+   */
+  WeblogicLoggerAdapter(NonCatalogLogger logger) {
+    this.logger = logger;
+    this.name = logger.toString();
+  }
+
+  /**
+   * Is this logger instance enabled for the FINEST level?
+   *
+   * @return Always true
+   */
+  @Override
+  public boolean isTraceEnabled() {
+    return true;
+
+  }
+
+  /**
+   * Log a message object at level TRACE.
+   *
+   * @param msg - the message object to be logged
+   */
+  @Override
+  public void trace(String msg) {
+    logger.trace(msg);
+  }
+
+  /**
+   * Log a message at level TRACE according to the specified format and
+   * argument.
+   */
+  @Override
+  public void trace(String format, Object arg) {
+    FormattingTuple ft = MessageFormatter.format(format, arg);
+    logger.trace(ft.getMessage());
+  }
+
+  /**
+   * Log a message at level TRACE according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void trace(String format, Object arg1, Object arg2) {
+    FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
+    logger.trace(ft.getMessage());
+  }
+
+  /**
+   * Log a message at level TRACE according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void trace(String format, Object[] argArray) {
+    FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+    logger.trace(ft.getMessage());
+  }
+
+  /**
+   * Log an exception (throwable) at level FINEST with an accompanying message.
+   */
+  @Override
+  public void trace(String msg, Throwable t) {
+    logger.trace(msg, t);
+  }
+
+  /**
+   * Is this logger instance enabled for the DEBUG level?
+   *
+   * @return Always true
+   */
+  @Override
+  public boolean isDebugEnabled() {
+    return true;
+  }
+
+  /**
+   * Log a message object at level FINE.
+   *
+   * @param msg - the message object to be logged
+   */
+  @Override
+  public void debug(String msg) {
+    logger.debug(msg);
+  }
+
+  /**
+   * Log a message at level DEBUG according to the specified format and
+   * argument.
+   */
+  @Override
+  public void debug(String format, Object arg) {
+    FormattingTuple ft = MessageFormatter.format(format, arg);
+    logger.debug(ft.getMessage());
+  }
+
+  /**
+   * Log a message at level DEBUG according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void debug(String format, Object arg1, Object arg2) {
+    FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
+    logger.debug(ft.getMessage());
+  }
+
+  /**
+   * Log a message at level FINE according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void debug(String format, Object[] argArray) {
+    FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+    logger.debug(ft.getMessage());
+  }
+
+  /**
+   * Log an exception (throwable) at level FINE with an accompanying message.
+   */
+  @Override
+  public void debug(String msg, Throwable t) {
+    logger.debug(msg, t);
+  }
+
+  /**
+   * Is this logger instance enabled for the INFO level?
+   *
+   * @return Always true
+   */
+  @Override
+  public boolean isInfoEnabled() {
+    return true;
+  }
+
+  /**
+   * Log a message object at the INFO level.
+   */
+  @Override
+  public void info(String msg) {
+    logger.info(msg);
+  }
+
+  /**
+   * Log a message at level INFO according to the specified format and
+   * argument.
+   */
+  @Override
+  public void info(String format, Object arg) {
+    FormattingTuple ft = MessageFormatter.format(format, arg);
+    logger.info(ft.getMessage());
+  }
+
+  /**
+   * Log a message at the INFO level according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void info(String format, Object arg1, Object arg2) {
+    FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
+    logger.info(ft.getMessage());
+  }
+
+  /**
+   * Log a message at level INFO according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void info(String format, Object[] argArray) {
+    FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+    logger.info(ft.getMessage());
+  }
+
+  /**
+   * Log an exception (throwable) at the INFO level with an accompanying
+   * message.
+   */
+  @Override
+  public void info(String msg, Throwable t) {
+    logger.info(msg, t);
+  }
+
+  /**
+   * Is this logger instance enabled for the WARNING level?
+   *
+   * @return Always true
+   */
+  @Override
+  public boolean isWarnEnabled() {
+    return true;
+  }
+
+  /**
+   * Log a message object at the WARNING level.
+   */
+  @Override
+  public void warn(String msg) {
+    logger.warning(msg);
+  }
+
+  /**
+   * Log a message at the WARNING level according to the specified format and
+   * argument.
+   */
+  @Override
+  public void warn(String format, Object arg) {
+    FormattingTuple ft = MessageFormatter.format(format, arg);
+    logger.warning(ft.getMessage());
+  }
+
+  /**
+   * Log a message at the WARNING level according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void warn(String format, Object arg1, Object arg2) {
+    FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
+    logger.warning(ft.getMessage());
+  }
+
+  /**
+   * Log a message at level WARNING according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void warn(String format, Object[] argArray) {
+    FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+    logger.warning(ft.getMessage());
+  }
+
+  /**
+   * Log an exception (throwable) at the WARNING level with an accompanying
+   * message.
+   */
+  @Override
+  public void warn(String msg, Throwable t) {
+    logger.warning(msg, t);
+  }
+
+  /**
+   * Is this logger instance enabled for level SEVERE?
+   *
+   * @return Always true;
+   */
+  @Override
+  public boolean isErrorEnabled() {
+    return true;
+  }
+
+  /**
+   * Log a message object at the ERROR level.
+   */
+  @Override
+  public void error(String msg) {
+    logger.error(msg);
+  }
+
+  /**
+   * Log a message at the ERROR level according to the specified format and
+   * argument.
+   */
+  @Override
+  public void error(String format, Object arg) {
+    FormattingTuple ft = MessageFormatter.format(format, arg);
+    logger.error(ft.getMessage());
+  }
+
+  /**
+   * Log a message at the ERROR level according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void error(String format, Object arg1, Object arg2) {
+    FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
+    logger.error(ft.getMessage());
+  }
+
+  /**
+   * Log a message at level ERROR according to the specified format and
+   * arguments.
+   */
+  @Override
+  public void error(String format, Object[] argArray) {
+    FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+    logger.error(ft.getMessage());
+  }
+
+  /**
+   * Log an exception (throwable) at the ERROR level with an accompanying
+   * message.
+   */
+  @Override
+  public void error(String msg, Throwable t) {
+    logger.error(msg, t);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerFactory.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerFactory.java b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerFactory.java
new file mode 100644
index 0000000..1e6fb98
--- /dev/null
+++ b/modules/gemfire-modules-slf4j-weblogic/src/main/java/org/slf4j/impl/WeblogicLoggerFactory.java
@@ -0,0 +1,46 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package org.slf4j.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+import weblogic.logging.NonCatalogLogger;
+
+/**
+ * Implementation of slf4j's ILoggerFactory interface
+ */
+public class WeblogicLoggerFactory implements ILoggerFactory {
+
+  /**
+   * A map of loggers
+   */
+  private Map<String, Logger> loggers;
+
+  public WeblogicLoggerFactory() {
+    loggers = new HashMap<String, Logger>();
+  }
+
+  @Override
+  public Logger getLogger(String name) {
+    Logger ulogger = null;
+
+    synchronized (this) {
+      ulogger = (Logger) loggers.get(name);
+      if (ulogger == null) {
+        NonCatalogLogger logger = new NonCatalogLogger(name);
+        ulogger = new WeblogicLoggerAdapter(logger);
+        loggers.put(name, ulogger);
+      }
+    }
+
+    return ulogger;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/build.gradle
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/build.gradle b/modules/gemfire-modules-tomcat7/build.gradle
new file mode 100644
index 0000000..ac0202c
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/build.gradle
@@ -0,0 +1,10 @@
+test  {
+  include '**/AllTests.class'
+}
+
+dependencies {
+  compile 'org.apache.tomcat:tomcat-catalina:7.0.30'
+  compile 'org.apache.tomcat:tomcat-coyote:7.0.30'
+
+  compile project(':gemfire-modules')
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/pom.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/pom.xml b/modules/gemfire-modules-tomcat7/pom.xml
new file mode 100644
index 0000000..6722da2
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/pom.xml
@@ -0,0 +1,98 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>com.gemstone</groupId>
+  <artifactId>gemfire-modules-tomcat7</artifactId>
+  <version>${gemfire.modules.version}</version>
+  <packaging>jar</packaging>
+
+  <name>gemfire-modules-tomcat7</name>
+  <url>http://maven.apache.org</url>
+
+  <parent>
+    <groupId>com.gemstone</groupId>
+    <artifactId>gemfire-modules-parent</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.gemstone</groupId>
+      <artifactId>gemfire-modules</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-catalina</artifactId>
+      <version>7.0.30</version>
+    </dependency>
+    <dependency>
+      <groupId>com.gemstone.gemfire</groupId>
+      <artifactId>gemfire</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-coyote</artifactId>
+      <version>7.0.30</version>
+    </dependency>
+    <dependency>
+      <groupId>org.httpunit</groupId>
+      <artifactId>httpunit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>rhino</groupId>
+      <artifactId>js</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.7.2</version>
+        <configuration>
+          <includes>
+            <include>**/AllTests.java</include>
+            <!-- This is a suite -->
+          </includes>
+          <runOrder>alphabetical</runOrder>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>s3</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-deploy-plugin</artifactId>
+            <configuration>
+              <skip>false</skip>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/main/java/com/gemstone/gemfire/modules/session/catalina/Tomcat7DeltaSessionManager.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/main/java/com/gemstone/gemfire/modules/session/catalina/Tomcat7DeltaSessionManager.java b/modules/gemfire-modules-tomcat7/src/main/java/com/gemstone/gemfire/modules/session/catalina/Tomcat7DeltaSessionManager.java
new file mode 100644
index 0000000..0dab9e1
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/main/java/com/gemstone/gemfire/modules/session/catalina/Tomcat7DeltaSessionManager.java
@@ -0,0 +1,107 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.catalina;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleState;
+
+import java.io.IOException;
+
+public class Tomcat7DeltaSessionManager extends DeltaSessionManager {
+
+  /**
+   * Prepare for the beginning of active use of the public methods of this
+   * component.  This method should be called after <code>configure()</code>,
+   * and before any of the public methods of the component are utilized.
+   *
+   * @throws LifecycleException if this component detects a fatal error that
+   *                            prevents this component from being used
+   */
+  @Override
+  public void startInternal() throws LifecycleException {
+    super.startInternal();
+    if (getLogger().isDebugEnabled()) {
+      getLogger().debug(this + ": Starting");
+    }
+    if (this.started.get()) {
+      return;
+    }
+
+    this.lifecycle.fireLifecycleEvent(START_EVENT, null);
+
+    // Register our various valves
+    registerJvmRouteBinderValve();
+
+    if (isCommitValveEnabled()) {
+      registerCommitSessionValve();
+    }
+
+    // Initialize the appropriate session cache interface
+    initializeSessionCache();
+
+    try {
+      load();
+    } catch (ClassNotFoundException e) {
+      throw new LifecycleException("Exception starting manager", e);
+    } catch (IOException e) {
+      throw new LifecycleException("Exception starting manager", e);
+    }
+
+    // Create the timer and schedule tasks
+    scheduleTimerTasks();
+
+    this.started.set(true);
+    this.setState(LifecycleState.STARTING);
+  }
+
+  /**
+   * Gracefully terminate the active use of the public methods of this
+   * component.  This method should be the last one called on a given instance
+   * of this component.
+   *
+   * @throws LifecycleException if this component detects a fatal error that
+   *                            needs to be reported
+   */
+  @Override
+  public void stopInternal() throws LifecycleException {
+    super.stopInternal();
+    if (getLogger().isDebugEnabled()) {
+      getLogger().debug(this + ": Stopping");
+    }
+
+    try {
+      unload();
+    } catch (IOException e) {
+      getLogger().error("Unable to unload sessions", e);
+    }
+
+    this.started.set(false);
+    this.lifecycle.fireLifecycleEvent(STOP_EVENT, null);
+
+    // StandardManager expires all Sessions here.
+    // All Sessions are not known by this Manager.
+
+    super.destroyInternal();
+
+    // Clear any sessions to be touched
+    getSessionsToTouch().clear();
+
+    // Cancel the timer
+    cancelTimer();
+
+    // Unregister the JVM route valve
+    unregisterJvmRouteBinderValve();
+
+    if (isCommitValveEnabled()) {
+      unregisterCommitSessionValve();
+    }
+
+    this.setState(LifecycleState.STOPPING);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/AllTests.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/AllTests.java b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/AllTests.java
new file mode 100644
index 0000000..0230d2a
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/AllTests.java
@@ -0,0 +1,96 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSessionManager;
+import com.gemstone.gemfire.modules.session.catalina.PeerToPeerCacheLifecycleListener;
+import com.gemstone.gemfire.modules.session.catalina.Tomcat7DeltaSessionManager;
+
+import java.io.File;
+import javax.servlet.http.HttpSession;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.catalina.core.StandardWrapper;
+
+/**
+ *
+ */
+public class AllTests extends TestSuite {
+
+  static EmbeddedTomcat server;
+
+  static Region<String, HttpSession> region;
+
+  static StandardWrapper servlet;
+
+  static DeltaSessionManager sessionManager;
+
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+
+    suite.addTestSuite(TestSessions.class);
+// This requires manual startup of a second cache...
+//        suite.addTestSuite(DualCacheTest.class);
+
+    TestSetup wrapper = new TestSetup(suite) {
+
+      @Override
+      public void setUp() throws Exception {
+        setupClass();
+      }
+
+      @Override
+      public void tearDown() throws Exception {
+        teardownClass();
+      }
+    };
+
+    return wrapper;
+  }
+
+  public static void setupClass() throws Exception {
+    // Create a per-user scratch directory
+    File tmpDir = new File(System.getProperty("java.io.tmpdir"),
+        "gemfire_modules-" + System.getProperty("user.name"));
+    tmpDir.mkdirs();
+    tmpDir.deleteOnExit();
+
+    String gemfireLog = tmpDir.getPath() +
+        System.getProperty("file.separator") + "gemfire_modules.log";
+
+    server = new EmbeddedTomcat("/test", 7890, "JVM-1");
+
+    PeerToPeerCacheLifecycleListener p2pListener = new PeerToPeerCacheLifecycleListener();
+    p2pListener.setProperty("mcast-port", "19991");
+    p2pListener.setProperty("log-file", gemfireLog);
+    p2pListener.setProperty("writable-working-dir", tmpDir.getPath());
+    server.getEmbedded().addLifecycleListener(p2pListener);
+    sessionManager = new Tomcat7DeltaSessionManager();
+    server.getRootContext().setManager(sessionManager);
+
+    servlet = server.addServlet("/test/*", "default",
+        CommandServlet.class.getName());
+    server.startContainer();
+
+    /**
+     * Can only retrieve the region once the container has started up
+     * (and the cache has started too).
+     */
+    region = sessionManager.getSessionCache().getSessionRegion();
+    Thread.sleep(5000);
+
+  }
+
+  public static void teardownClass() throws Exception {
+    server.stopContainer();
+    Thread.sleep(2000);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Callback.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Callback.java b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Callback.java
new file mode 100644
index 0000000..923d2de
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Callback.java
@@ -0,0 +1,17 @@
+
+package com.gemstone.gemfire.modules.session;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Interface which, when implemented, can be put into a servlet context and
+ * executed by the servlet.
+ */
+public interface Callback {
+
+  public void call(HttpServletRequest request, HttpServletResponse response)
+      throws ServletException, IOException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/CommandServlet.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/CommandServlet.java b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/CommandServlet.java
new file mode 100644
index 0000000..4655a55
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/CommandServlet.java
@@ -0,0 +1,80 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+/**
+ *
+ */
+public class CommandServlet extends HttpServlet {
+
+  private ServletContext context;
+
+  /**
+   * The standard servlet method overridden.
+   *
+   * @param request
+   * @param response
+   * @throws IOException
+   */
+  @Override
+  protected void doGet(HttpServletRequest request,
+      HttpServletResponse response) throws IOException, ServletException {
+
+    QueryCommand cmd = QueryCommand.UNKNOWN;
+    String param = request.getParameter("param");
+    String value = request.getParameter("value");
+    PrintWriter out = response.getWriter();
+
+    String cmdStr = request.getParameter("cmd");
+    if (cmdStr != null) {
+      cmd = QueryCommand.valueOf(cmdStr);
+    }
+
+    HttpSession session = request.getSession();
+
+    switch (cmd) {
+      case SET:
+        session.setAttribute(param, value);
+        break;
+      case GET:
+        String val = (String) session.getAttribute(param);
+        if (val != null) {
+          out.write(val);
+        }
+        break;
+      case INVALIDATE:
+        session.invalidate();
+        break;
+      case CALLBACK:
+        Callback c = (Callback) context.getAttribute("callback");
+        c.call(request, response);
+        break;
+    }
+  }
+
+  /**
+   * Save a reference to the ServletContext for later use.
+   *
+   * @param config
+   */
+  @Override
+  public void init(ServletConfig config) {
+    this.context = config.getServletContext();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/DualCacheTest.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/DualCacheTest.java b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/DualCacheTest.java
new file mode 100644
index 0000000..9ab800d
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/DualCacheTest.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.gemstone.gemfire.modules.session;
+
+import junit.framework.TestCase;
+import com.meterware.httpunit.GetMethodWebRequest;
+import com.meterware.httpunit.WebConversation;
+import com.meterware.httpunit.WebRequest;
+import com.meterware.httpunit.WebResponse;
+
+import static junit.framework.Assert.*;
+
+/**
+ *
+ */
+public class DualCacheTest extends TestCase {
+
+  /**
+   * Check that our session persists. The values we pass in as query params are
+   * used to set attributes on the session.
+   */
+  public void testSessionFailover() throws Exception {
+    String key = "value_testSessionFailover";
+    String value = "Foo";
+
+    WebConversation wc = new WebConversation();
+    WebRequest req1 = new GetMethodWebRequest("http://localhost:7890/test");
+    req1.setParameter("cmd", QueryCommand.SET.name());
+    req1.setParameter("param", key);
+    req1.setParameter("value", value);
+    WebResponse response = wc.getResponse(req1);
+    String sessionId = response.getNewCookieValue("JSESSIONID");
+
+    assertNotNull("No apparent session cookie", sessionId);
+
+    WebRequest req2 = new GetMethodWebRequest("http://localhost:7891/test");
+    req2.setHeaderField("Cookie", "JSESSIONID=" + sessionId);
+    req2.setParameter("cmd", QueryCommand.GET.name());
+    req2.setParameter("param", key);
+    response = wc.getResponse(req2);
+    sessionId = response.getNewCookieValue("JSESSIONID");
+
+    assertEquals(value, response.getText());
+    assertTrue("The sessionId does not contain the correct JVM route value",
+        sessionId.contains("JVM-2"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/EmbeddedTomcat.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/EmbeddedTomcat.java b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/EmbeddedTomcat.java
new file mode 100644
index 0000000..2504774
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/EmbeddedTomcat.java
@@ -0,0 +1,178 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session;
+
+import com.gemstone.gemfire.modules.session.catalina.JvmRouteBinderValve;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import javax.servlet.ServletException;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Engine;
+import org.apache.catalina.Host;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.core.StandardEngine;
+import org.apache.catalina.core.StandardService;
+import org.apache.catalina.core.StandardWrapper;
+import org.apache.catalina.loader.WebappLoader;
+import org.apache.catalina.realm.MemoryRealm;
+import org.apache.catalina.startup.Embedded;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ *
+ */
+public class EmbeddedTomcat {
+
+  private String contextPath = null;
+  private Embedded container = null;
+  private Log logger = LogFactory.getLog(getClass());
+
+  /**
+   * The directory to create the Tomcat server configuration under.
+   */
+  private String catalinaHome = "tomcat";
+
+  /**
+   * The port to run the Tomcat server on.
+   */
+  private int port = 8089;
+
+  /**
+   * The classes directory for the web application being run.
+   */
+  private String classesDir = "target/classes";
+
+  private Context rootContext = null;
+
+  /**
+   * The web resources directory for the web application being run.
+   */
+  private String webappDir = "";
+
+  public EmbeddedTomcat(String contextPath, int port, String jvmRoute)
+      throws MalformedURLException {
+    this.contextPath = contextPath;
+    this.port = port;
+
+    // create server
+    container = new Embedded();
+    container.setCatalinaHome(catalinaHome);
+    // Not really necessasry, but let's still do it...
+    container.setRealm(new MemoryRealm());
+
+    // create webapp loader
+    WebappLoader loader = new WebappLoader(this.getClass().getClassLoader());
+    if (classesDir != null) {
+      loader.addRepository(new File(classesDir).toURI().toURL().toString());
+    }
+
+    rootContext = container.createContext("", webappDir);
+    rootContext.setLoader(loader);
+    rootContext.setReloadable(true);
+    // Otherwise we get NPE when instantiating servlets
+    rootContext.setIgnoreAnnotations(true);
+
+    // create host
+    Host localHost = container.createHost("127.0.0.1",
+        new File("target").getAbsolutePath());
+    localHost.addChild(rootContext);
+
+    localHost.setDeployOnStartup(true);
+
+    // create engine
+    Engine engine = container.createEngine();
+    engine.setName("localEngine");
+    engine.addChild(localHost);
+    engine.setDefaultHost(localHost.getName());
+    engine.setJvmRoute(jvmRoute);
+    engine.setService(new StandardService());
+    container.addEngine(engine);
+
+    // create http connector
+    Connector httpConnector = container.createConnector((InetAddress) null,
+        port, false);
+    container.addConnector(httpConnector);
+    container.setAwait(true);
+
+    // Create the JVMRoute valve for session failover
+    ValveBase valve = new JvmRouteBinderValve();
+    ((StandardEngine) engine).addValve(valve);
+  }
+
+  /**
+   * Starts the embedded Tomcat server.
+   */
+  public void startContainer() throws LifecycleException {
+    // start server
+    container.start();
+
+    // add shutdown hook to stop server
+    Runtime.getRuntime().addShutdownHook(new Thread() {
+      @Override
+      public void run() {
+        stopContainer();
+      }
+    });
+  }
+
+  /**
+   * Stops the embedded Tomcat server.
+   */
+  public void stopContainer() {
+    try {
+      if (container != null) {
+        container.stop();
+        logger.info("Stopped container");
+      }
+    } catch (LifecycleException exception) {
+      logger.warn("Cannot Stop Tomcat" + exception.getMessage());
+    }
+  }
+
+  public StandardWrapper addServlet(String path, String name,
+      String clazz) throws ServletException {
+    StandardWrapper servlet = (StandardWrapper) rootContext.createWrapper();
+    servlet.setName(name);
+    servlet.setServletClass(clazz);
+    servlet.setLoadOnStartup(1);
+
+    rootContext.addChild(servlet);
+    rootContext.addServletMapping(path, name);
+
+    servlet.setParent(rootContext);
+//        servlet.load();
+
+    return servlet;
+  }
+
+  public Embedded getEmbedded() {
+    return container;
+  }
+
+  public Context getRootContext() {
+    return rootContext;
+  }
+
+  public String getPath() {
+    return contextPath;
+  }
+
+  public void setPath(String path) {
+    this.contextPath = path;
+  }
+
+  public int getPort() {
+    return port;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/QueryCommand.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/QueryCommand.java b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/QueryCommand.java
new file mode 100644
index 0000000..63d9984
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/QueryCommand.java
@@ -0,0 +1,18 @@
+package com.gemstone.gemfire.modules.session;
+
+/**
+ * Basic commands to pass to our test servlet
+ */
+public enum QueryCommand {
+
+  SET,
+
+  GET,
+
+  INVALIDATE,
+
+  CALLBACK,
+
+  UNKNOWN;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/TestSessions.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/TestSessions.java b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/TestSessions.java
new file mode 100644
index 0000000..184c098
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/TestSessions.java
@@ -0,0 +1,349 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session;
+
+import junit.framework.TestCase;
+
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.meterware.httpunit.WebRequest;
+import com.meterware.httpunit.GetMethodWebRequest;
+import com.meterware.httpunit.WebConversation;
+import com.meterware.httpunit.WebResponse;
+
+import java.beans.PropertyChangeEvent;
+
+import static junit.framework.Assert.*;
+
+/**
+ *
+ */
+public class TestSessions extends TestCase {
+
+  /**
+   * Reset some data
+   */
+  public void setup() throws Exception {
+    AllTests.sessionManager.setMaxInactiveInterval(30);
+    AllTests.region.clear();
+  }
+
+  /**
+   * Check that the basics are working
+   */
+  public void testSanity() throws Exception {
+    WebConversation wc = new WebConversation();
+    WebResponse response = wc.getResponse("http://localhost:7890/test");
+
+    assertEquals("JSESSIONID", response.getNewCookieNames()[0]);
+  }
+
+  /**
+   * Test callback functionality. This is here really just as an example.
+   * Callbacks are useful to implement per test actions which can be defined
+   * within the actual test method instead of in a separate servlet class.
+   */
+  public void testCallback() throws Exception {
+    final String helloWorld = "Hello World";
+    Callback c = new Callback() {
+
+      @Override
+      public void call(HttpServletRequest request, HttpServletResponse response)
+          throws IOException {
+        PrintWriter out = response.getWriter();
+        out.write(helloWorld);
+      }
+    };
+    AllTests.servlet.getServletContext().setAttribute("callback", c);
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    req.setParameter("cmd", QueryCommand.CALLBACK.name());
+    req.setParameter("param", "callback");
+    WebResponse response = wc.getResponse(req);
+
+    assertEquals(helloWorld, response.getText());
+  }
+
+  /**
+   * Test that calling session.isNew() works for the initial as well as
+   * subsequent requests.
+   */
+  public void testIsNew() throws Exception {
+    Callback c = new Callback() {
+
+      @Override
+      public void call(HttpServletRequest request, HttpServletResponse response)
+          throws IOException {
+        HttpSession session = request.getSession();
+        response.getWriter().write(Boolean.toString(session.isNew()));
+      }
+    };
+    AllTests.servlet.getServletContext().setAttribute("callback", c);
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    req.setParameter("cmd", QueryCommand.CALLBACK.name());
+    req.setParameter("param", "callback");
+    WebResponse response = wc.getResponse(req);
+
+    assertEquals("true", response.getText());
+    response = wc.getResponse(req);
+
+    assertEquals("false", response.getText());
+  }
+
+  /**
+   * Check that our session persists. The values we pass in as query params are
+   * used to set attributes on the session.
+   */
+  public void testSessionPersists1() throws Exception {
+    String key = "value_testSessionPersists1";
+    String value = "Foo";
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+    req.setParameter("cmd", QueryCommand.SET.name());
+    req.setParameter("param", key);
+    req.setParameter("value", value);
+    WebResponse response = wc.getResponse(req);
+    String sessionId = response.getNewCookieValue("JSESSIONID");
+
+    assertNotNull("No apparent session cookie", sessionId);
+
+    // The request retains the cookie from the prior response...
+    req.setParameter("cmd", QueryCommand.GET.name());
+    req.setParameter("param", key);
+    req.removeParameter("value");
+    response = wc.getResponse(req);
+
+    assertEquals(value, response.getText());
+  }
+
+  /**
+   * Check that our session persists beyond the container restarting.
+   */
+//    public void testSessionPersists2() throws Exception {
+//        String key = "value_testSessionPersists2";
+//        String value = "Foo";
+//
+//        WebConversation wc = new WebConversation();
+//        WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+//        req.setParameter("cmd", QueryCommand.SET.name());
+//        req.setParameter("param", key);
+//        req.setParameter("value", value);
+//        WebResponse response = wc.getResponse(req);
+//        String sessionId = response.getNewCookieValue("JSESSIONID");
+//
+//        assertNotNull("No apparent session cookie", sessionId);
+//
+//        // Restart the container
+//        AllTests.teardownClass();
+//        AllTests.setupClass();
+//
+//        // The request retains the cookie from the prior response...
+//        req.setParameter("cmd", QueryCommand.GET.name());
+//        req.setParameter("param", key);
+//        req.removeParameter("value");
+//        response = wc.getResponse(req);
+//
+//        assertEquals(value, response.getText());
+//    }
+
+  /**
+   * Test that invalidating a session makes it's attributes inaccessible.
+   */
+  public void testInvalidate() throws Exception {
+    String key = "value_testInvalidate";
+    String value = "Foo";
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    // Set an attribute
+    req.setParameter("cmd", QueryCommand.SET.name());
+    req.setParameter("param", key);
+    req.setParameter("value", value);
+    WebResponse response = wc.getResponse(req);
+
+    // Invalidate the session
+    req.removeParameter("param");
+    req.removeParameter("value");
+    req.setParameter("cmd", QueryCommand.INVALIDATE.name());
+    wc.getResponse(req);
+
+    // The attribute should not be accessible now...
+    req.setParameter("cmd", QueryCommand.GET.name());
+    req.setParameter("param", key);
+    response = wc.getResponse(req);
+
+    assertEquals("", response.getText());
+  }
+
+  /**
+   * Test setting the session expiration
+   */
+  public void testSessionExpiration1() throws Exception {
+    // TestSessions only live for a second
+    AllTests.sessionManager.setMaxInactiveInterval(1);
+
+    String key = "value_testSessionExpiration1";
+    String value = "Foo";
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    // Set an attribute
+    req.setParameter("cmd", QueryCommand.SET.name());
+    req.setParameter("param", key);
+    req.setParameter("value", value);
+    WebResponse response = wc.getResponse(req);
+
+    // Sleep a while
+    Thread.sleep(2000);
+
+    // The attribute should not be accessible now...
+    req.setParameter("cmd", QueryCommand.GET.name());
+    req.setParameter("param", key);
+    response = wc.getResponse(req);
+
+    assertEquals("", response.getText());
+  }
+
+  /**
+   * Test setting the session expiration via a property change as would happen
+   * under normal deployment conditions.
+   */
+  public void testSessionExpiration2() throws Exception {
+    // TestSessions only live for a minute
+    AllTests.sessionManager.propertyChange(
+        new PropertyChangeEvent(AllTests.server.getRootContext(),
+            "sessionTimeout",
+            new Integer(30), new Integer(1)));
+
+    // Check that the value has been set to 60 seconds
+    assertEquals(60, AllTests.sessionManager.getMaxInactiveInterval());
+  }
+
+  /**
+   * Test that removing a session attribute also removes it from the region
+   */
+  public void testRemoveAttribute() throws Exception {
+    String key = "value_testRemoveAttribute";
+    String value = "Foo";
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    // Set an attribute
+    req.setParameter("cmd", QueryCommand.SET.name());
+    req.setParameter("param", key);
+    req.setParameter("value", value);
+    WebResponse response = wc.getResponse(req);
+    String sessionId = response.getNewCookieValue("JSESSIONID");
+
+    // Implicitly remove the attribute
+    req.removeParameter("value");
+    wc.getResponse(req);
+
+    // The attribute should not be accessible now...
+    req.setParameter("cmd", QueryCommand.GET.name());
+    req.setParameter("param", key);
+    response = wc.getResponse(req);
+
+    assertEquals("", response.getText());
+    assertNull(AllTests.region.get(sessionId).getAttribute(key));
+  }
+
+  /**
+   * Test that a session attribute gets set into the region too.
+   */
+  public void testBasicRegion() throws Exception {
+    String key = "value_testBasicRegion";
+    String value = "Foo";
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    // Set an attribute
+    req.setParameter("cmd", QueryCommand.SET.name());
+    req.setParameter("param", key);
+    req.setParameter("value", value);
+    WebResponse response = wc.getResponse(req);
+    String sessionId = response.getNewCookieValue("JSESSIONID");
+
+    assertEquals(value, AllTests.region.get(sessionId).getAttribute(key));
+  }
+
+  /**
+   * Test that a session attribute gets removed from the region when the session
+   * is invalidated.
+   */
+  public void testRegionInvalidate() throws Exception {
+    String key = "value_testRegionInvalidate";
+    String value = "Foo";
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    // Set an attribute
+    req.setParameter("cmd", QueryCommand.SET.name());
+    req.setParameter("param", key);
+    req.setParameter("value", value);
+    WebResponse response = wc.getResponse(req);
+    String sessionId = response.getNewCookieValue("JSESSIONID");
+
+    // Invalidate the session
+    req.removeParameter("param");
+    req.removeParameter("value");
+    req.setParameter("cmd", QueryCommand.INVALIDATE.name());
+    wc.getResponse(req);
+
+    assertNull("The region should not have an entry for this session",
+        AllTests.region.get(sessionId));
+  }
+
+  /**
+   * Test that multiple attribute updates, within the same request result in
+   * only the latest one being effective.
+   */
+  public void testMultipleAttributeUpdates() throws Exception {
+    final String key = "value_testMultipleAttributeUpdates";
+    Callback c = new Callback() {
+
+      @Override
+      public void call(HttpServletRequest request, HttpServletResponse response)
+          throws IOException {
+        HttpSession session = request.getSession();
+        for (int i = 0; i < 1000; i++) {
+          session.setAttribute(key, Integer.toString(i));
+        }
+      }
+    };
+    AllTests.servlet.getServletContext().setAttribute("callback", c);
+
+    WebConversation wc = new WebConversation();
+    WebRequest req = new GetMethodWebRequest("http://localhost:7890/test");
+
+    // Execute the callback
+    req.setParameter("cmd", QueryCommand.CALLBACK.name());
+    req.setParameter("param", "callback");
+    WebResponse response = wc.getResponse(req);
+
+    String sessionId = response.getNewCookieValue("JSESSIONID");
+
+    assertEquals("999", AllTests.region.get(sessionId).getAttribute(key));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-tomcat7/tomcat/conf/tomcat-users.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-tomcat7/tomcat/conf/tomcat-users.xml b/modules/gemfire-modules-tomcat7/tomcat/conf/tomcat-users.xml
new file mode 100644
index 0000000..6c9f217
--- /dev/null
+++ b/modules/gemfire-modules-tomcat7/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/4b56f5e4/modules/gemfire-modules/build.gradle
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/build.gradle b/modules/gemfire-modules/build.gradle
new file mode 100644
index 0000000..5dfc5c4
--- /dev/null
+++ b/modules/gemfire-modules/build.gradle
@@ -0,0 +1,11 @@
+
+test  {
+  include '**/TestSessions.class'
+  workingDir = "${projectDir}"
+}
+
+dependencies {
+  compile "org.apache.tomcat:catalina:${tomcat_version}"
+  compile "org.apache.tomcat:catalina-ha:${tomcat_version}"
+  testCompile "org.slf4j:slf4j-jdk14:${slf4j_version}"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules/pom.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/pom.xml b/modules/gemfire-modules/pom.xml
new file mode 100644
index 0000000..55c466e
--- /dev/null
+++ b/modules/gemfire-modules/pom.xml
@@ -0,0 +1,118 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>com.gemstone</groupId>
+  <artifactId>gemfire-modules</artifactId>
+  <version>${gemfire.modules.version}</version>
+  <packaging>jar</packaging>
+
+  <name>gemfire-modules</name>
+  <url>http://maven.apache.org</url>
+
+  <parent>
+    <groupId>com.gemstone</groupId>
+    <artifactId>gemfire-modules-parent</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.tomcat</groupId>
+    	<artifactId>catalina</artifactId>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.tomcat</groupId>
+    	<artifactId>catalina-ha</artifactId>
+        <version>${tomcat.version}</version>
+        <scope>provided</scope>
+    </dependency>
+    <dependency>
+    	<groupId>com.gemstone.gemfire</groupId>
+    	<artifactId>gemfire</artifactId>
+    </dependency>
+    <dependency>
+    	<groupId>org.slf4j</groupId>
+    	<artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>coyote</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.httpunit</groupId>
+      <artifactId>httpunit</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.7.2</version>
+        <configuration>
+          <includes>
+            <!-- This is a suite -->
+            <include>**/TestSessions.java</include>
+          </includes>
+          <runOrder>alphabetical</runOrder>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>com.google.code.maven-replacer-plugin</groupId>
+        <artifactId>replacer</artifactId>
+        <version>1.5.1</version>
+        <executions>
+          <execution>
+            <phase>compile</phase>
+            <goals>
+              <goal>replace</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <includes>
+            <include>target/**/modules-version.properties</include>
+          </includes>
+          <replacements>
+            <replacement>
+              <token>@VERSION@</token>
+              <value>${gemfire.modules.version}</value>
+            </replacement>
+          </replacements>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>s3</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-deploy-plugin</artifactId>
+            <configuration>
+              <skip>false</skip>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
new file mode 100644
index 0000000..e382174
--- /dev/null
+++ b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
@@ -0,0 +1,56 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+
+@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/4b56f5e4/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
new file mode 100644
index 0000000..7c37983
--- /dev/null
+++ b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
@@ -0,0 +1,10 @@
+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/4b56f5e4/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
new file mode 100644
index 0000000..ff597da
--- /dev/null
+++ b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
@@ -0,0 +1,84 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+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;
+
+@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/4b56f5e4/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
new file mode 100644
index 0000000..cf6160c
--- /dev/null
+++ b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
@@ -0,0 +1,80 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+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;
+
+@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/4b56f5e4/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
new file mode 100644
index 0000000..c784e66
--- /dev/null
+++ b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
@@ -0,0 +1,8 @@
+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/4b56f5e4/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
new file mode 100644
index 0000000..6c13919
--- /dev/null
+++ b/modules/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
@@ -0,0 +1,60 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import java.util.Properties;
+
+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.GatewayEventCallbackArgument;
+
+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 GatewayEventCallbackArgument) {
+      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) {}
+}
\ No newline at end of file


Mime
View raw message