You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2016/02/08 17:51:52 UTC
[04/32] incubator-geode git commit: GEODE-14: Integration of GemFire
Session Replication and Hibernate modules
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java b/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java
new file mode 100644
index 0000000..f312545
--- /dev/null
+++ b/extensions/gemfire-modules-tomcat7/src/test/java/com/gemstone/gemfire/modules/session/Tomcat7SessionsJUnitTest.java
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session;
+
+import com.gemstone.gemfire.modules.session.catalina.Tomcat7DeltaSessionManager;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import org.junit.BeforeClass;
+import org.junit.experimental.categories.Category;
+
+/**
+ * @author Jens Deppe
+ */
+@Category(UnitTest.class)
+public class Tomcat7SessionsJUnitTest extends TestSessionsBase {
+
+ // Set up the session manager we need
+ @BeforeClass
+ public static void setupClass() throws Exception {
+ setupServer(new Tomcat7DeltaSessionManager());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml
new file mode 100644
index 0000000..6c9f217
--- /dev/null
+++ b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/conf/tomcat-users.xml
@@ -0,0 +1,3 @@
+<?xml version='1.0' encoding='utf-8'?>
+<tomcat-users>
+</tomcat-users>
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/logs/.gitkeep
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/logs/.gitkeep b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/logs/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/temp/.gitkeep
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/temp/.gitkeep b/extensions/gemfire-modules-tomcat7/src/test/resources/tomcat/temp/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/build.gradle b/extensions/gemfire-modules/build.gradle
new file mode 100644
index 0000000..1d45ab8
--- /dev/null
+++ b/extensions/gemfire-modules/build.gradle
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+test {
+ doFirst {
+ copy {
+ from 'build/resources/test/tomcat'
+ into 'build/test/tomcat/'
+ }
+ }
+}
+
+jar {
+ baseName = 'gemfire-modules'
+}
+
+dependencies {
+ compile project(':gemfire-core')
+
+ compile 'org.apache.tomcat:catalina:' + project.'tomcat6.version'
+ compile 'org.apache.tomcat:catalina-ha:' + project.'tomcat6.version'
+ compile 'org.apache.tomcat:juli:' + project.'tomcat6.version'
+
+ testCompile 'org.httpunit:httpunit:' + project.'httpunit.version'
+ testRuntime 'org.apache.tomcat:coyote:' + project.'tomcat6.version'
+
+ provided project(path: ':gemfire-junit', configuration: 'testOutput')
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
new file mode 100644
index 0000000..13b2e77
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/AbstractGatewayDeltaEvent.java
@@ -0,0 +1,64 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+@SuppressWarnings("serial")
+public abstract class AbstractGatewayDeltaEvent implements GatewayDeltaEvent, DataSerializable {
+
+ protected String regionName;
+ protected String key;
+
+ public AbstractGatewayDeltaEvent() {
+ }
+
+ public AbstractGatewayDeltaEvent(String regionName, String key) {
+ this.regionName = regionName;
+ this.key = key;
+ }
+
+ public String getRegionName() {
+ return this.regionName;
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Region getRegion(Cache cache) {
+ return cache.getRegion(this.regionName);
+ }
+
+ public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+ this.regionName = DataSerializer.readString(in);
+ this.key = DataSerializer.readString(in);
+ }
+
+ public void toData(DataOutput out) throws IOException {
+ DataSerializer.writeString(this.regionName, out);
+ DataSerializer.writeString(this.key, out);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
new file mode 100644
index 0000000..4acad05
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDelta.java
@@ -0,0 +1,26 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+public interface GatewayDelta {
+
+ public static final String GATEWAY_DELTA_REGION_NAME = "__gatewayDelta";
+
+ public GatewayDeltaEvent getCurrentGatewayDeltaEvent();
+
+ public void setCurrentGatewayDeltaEvent(GatewayDeltaEvent currentGatewayDeltaEvent);
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
new file mode 100644
index 0000000..3202591
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaCreateEvent.java
@@ -0,0 +1,88 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.Instantiator;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.CachedDeserializableFactory;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+@SuppressWarnings("serial")
+public class GatewayDeltaCreateEvent extends AbstractGatewayDeltaEvent {
+
+ private byte[] gatewayDelta;
+
+ public GatewayDeltaCreateEvent() {
+ }
+
+ public GatewayDeltaCreateEvent(String regionName, String key, byte[] gatewayDelta) {
+ super(regionName, key);
+ this.gatewayDelta = gatewayDelta;
+ }
+
+ public byte[] getGatewayDelta() {
+ return this.gatewayDelta;
+ }
+
+ public void apply(Cache cache) {
+ Region<String, CachedDeserializable> region = getRegion(cache);
+ region.put(this.key, CachedDeserializableFactory.create(this.gatewayDelta), true);
+ if (cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Applied ").append(this);
+ cache.getLogger().fine(builder.toString());
+ }
+ }
+
+ public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+ super.fromData(in);
+ this.gatewayDelta = DataSerializer.readByteArray(in);
+ }
+
+ public void toData(DataOutput out) throws IOException {
+ super.toData(out);
+ DataSerializer.writeByteArray(this.gatewayDelta, out);
+ }
+
+ public static void registerInstantiator(int id) {
+ Instantiator.register(new Instantiator(GatewayDeltaCreateEvent.class, id) {
+ public DataSerializable newInstance() {
+ return new GatewayDeltaCreateEvent();
+ }
+ });
+ }
+
+ public String toString() {
+ return new StringBuilder().append("GatewayDeltaCreateEvent[")
+ .append("regionName=")
+ .append(this.regionName)
+ .append("; key=")
+ .append(this.key)
+ .append("; gatewayDelta=")
+ .append(this.gatewayDelta)
+ .append("]")
+ .toString();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
new file mode 100644
index 0000000..18bfe8b
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaDestroyEvent.java
@@ -0,0 +1,82 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.Instantiator;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.EntryNotFoundException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.session.catalina.DeltaSession;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+@SuppressWarnings("serial")
+public class GatewayDeltaDestroyEvent extends AbstractGatewayDeltaEvent {
+
+ public GatewayDeltaDestroyEvent() {
+ }
+
+ public GatewayDeltaDestroyEvent(String regionName, String key) {
+ super(regionName, key);
+ }
+
+ public void apply(Cache cache) {
+ Region<String, DeltaSession> region = getRegion(cache);
+ try {
+ region.destroy(this.key);
+ if (cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Applied ").append(this);
+ cache.getLogger().fine(builder.toString());
+ }
+ } catch (EntryNotFoundException e) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(this).append(": Session ").append(this.key).append(" was not found");
+ cache.getLogger().warning(builder.toString());
+ }
+ }
+
+ public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+ super.fromData(in);
+ }
+
+ public void toData(DataOutput out) throws IOException {
+ super.toData(out);
+ }
+
+ public static void registerInstantiator(int id) {
+ Instantiator.register(new Instantiator(GatewayDeltaDestroyEvent.class, id) {
+ public DataSerializable newInstance() {
+ return new GatewayDeltaDestroyEvent();
+ }
+ });
+ }
+
+ public String toString() {
+ return new StringBuilder().append("GatewayDeltaDestroyEvent[")
+ .append("regionName=")
+ .append(this.regionName)
+ .append("; key=")
+ .append(this.key)
+ .append("]")
+ .toString();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
new file mode 100644
index 0000000..672a01f
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEvent.java
@@ -0,0 +1,24 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.cache.Cache;
+
+public interface GatewayDeltaEvent {
+
+ public void apply(Cache cache);
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
new file mode 100644
index 0000000..cf9aa1a
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaEventApplicationCacheListener.java
@@ -0,0 +1,67 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.EntryEvent;
+import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventCallbackArgument;
+
+import java.util.Properties;
+
+public class GatewayDeltaEventApplicationCacheListener extends CacheListenerAdapter<String, GatewayDeltaEvent> implements Declarable {
+
+ private final Cache cache;
+
+ public GatewayDeltaEventApplicationCacheListener() {
+ this.cache = CacheFactory.getAnyInstance();
+ }
+
+ public void afterCreate(EntryEvent<String, GatewayDeltaEvent> event) {
+ System.out.println("GatewayDeltaApplierCacheListener event: " + event);
+ EntryEventImpl eventImpl = (EntryEventImpl) event;
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaApplierCacheListener: Received event for ")
+ .append(event.getKey())
+ .append("->")
+ .append(event.getNewValue())
+ .append(".");
+ this.cache.getLogger().fine(builder.toString());
+ }
+
+ // If the event is from a remote site, apply it to the session
+ Object callbackArgument = eventImpl.getRawCallbackArgument();
+ System.out.println("GatewayDeltaApplierCacheListener callbackArgument: " + callbackArgument);
+ if (callbackArgument instanceof GatewaySenderEventCallbackArgument) {
+ GatewayDeltaEvent delta = event.getNewValue();
+ delta.apply(this.cache);
+ System.out.println("Applied " + delta);
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaApplierCacheListener: Applied ").append(delta);
+ this.cache.getLogger().fine(builder.toString());
+ }
+ }
+ }
+
+ public void init(Properties p) {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java
new file mode 100644
index 0000000..ce44fcb
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/gatewaydelta/GatewayDeltaForwarderCacheListener.java
@@ -0,0 +1,197 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.gatewaydelta;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.Declarable;
+import com.gemstone.gemfire.cache.EntryEvent;
+import com.gemstone.gemfire.cache.InterestPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionFactory;
+import com.gemstone.gemfire.cache.Scope;
+import com.gemstone.gemfire.cache.SerializedCacheValue;
+import com.gemstone.gemfire.cache.SubscriptionAttributes;
+import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+
+import java.util.Properties;
+
+public class GatewayDeltaForwarderCacheListener extends CacheListenerAdapter<String, GatewayDelta> implements Declarable {
+
+ private final Cache cache;
+
+ private LocalRegion gatewayDeltaRegion;
+
+ public GatewayDeltaForwarderCacheListener() {
+ this(CacheFactory.getAnyInstance());
+ }
+
+ public GatewayDeltaForwarderCacheListener(Cache cache) {
+ this.cache = cache;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void afterCreate(EntryEvent<String, GatewayDelta> event) {
+ // If the event is from the local site, create a 'create' event and send it to the
+ // gateway delta region
+ if (event.getCallbackArgument() == null) {
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaForwarderCacheListener: Received create event for ")
+ .append(event.getKey())
+ .append("->")
+ .append(event.getNewValue())
+ .append(" that originated in the local site. Sending it to the remote site.");
+ this.cache.getLogger().fine(builder.toString());
+ }
+
+ // Distribute the create event to the gateway hub(s)
+ String regionName = event.getRegion().getFullPath();
+ String sessionId = event.getKey();
+ SerializedCacheValue scv = event.getSerializedNewValue();
+ if (scv == null) {
+ getGatewayDeltaRegion().put(sessionId,
+ new GatewayDeltaCreateEvent(regionName, sessionId, EntryEventImpl.serialize(event.getNewValue())));
+ } else {
+ System.out.println(
+ "GatewayDeltaForwarderCacheListener event.getSerializedNewValue().getSerializedValue(): " + event.getSerializedNewValue()
+ .getSerializedValue());
+ getGatewayDeltaRegion().put(sessionId,
+ new GatewayDeltaCreateEvent(regionName, sessionId, scv.getSerializedValue()));
+ }
+ } else {
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaForwarderCacheListener: Received create event for ")
+ .append(event.getKey())
+ .append("->")
+ .append(event.getNewValue())
+ .append(" that originated in the remote site.");
+ this.cache.getLogger().fine(builder.toString());
+ }
+ }
+ }
+
+ public void afterUpdate(EntryEvent<String, GatewayDelta> event) {
+ //System.out.println("GatewayDeltaForwarderCacheListener.afterUpdate: " + event);
+ // If the event is from the local site, create an 'update' event and send it to the
+ // gateway delta region
+ if (event.getCallbackArgument() == null) {
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaForwarderCacheListener: Received update event for ")
+ .append(event.getKey())
+ .append("->")
+ .append(event.getNewValue())
+ .append(" that originated in the local site. Sending it to the remote site.");
+ this.cache.getLogger().fine(builder.toString());
+ }
+
+ // Distribute the update event to the gateway hub(s)
+ GatewayDelta session = event.getNewValue();
+ getGatewayDeltaRegion().put(event.getKey(), session.getCurrentGatewayDeltaEvent());
+
+ // Reset the current delta
+ session.setCurrentGatewayDeltaEvent(null);
+ } else {
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaForwarderCacheListener: Received update event for ")
+ .append(event.getKey())
+ .append("->")
+ .append(event.getNewValue())
+ .append(" that originated in the remote site.");
+ this.cache.getLogger().fine(builder.toString());
+ }
+ }
+ }
+
+ public void afterDestroy(EntryEvent<String, GatewayDelta> event) {
+ // If the event is from the local site, create a 'destroy' event and send it to the
+ // gateway delta region
+ if (event.getCallbackArgument() != null) {
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaForwarderCacheListener: Received destroy event for ")
+ .append(event.getKey())
+ .append("->")
+ .append(event.getNewValue())
+ .append(" that originated in the local site. Sending it to the remote site.");
+ this.cache.getLogger().fine(builder.toString());
+ }
+
+ // Distribute the destroy event to the gateway hub(s)
+ String sessionId = event.getKey();
+ getGatewayDeltaRegion().put(sessionId, new GatewayDeltaDestroyEvent(event.getRegion().getFullPath(), sessionId));
+ } else {
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaForwarderCacheListener: Received destroy event for session ")
+ .append(event.getKey())
+ .append(" that either expired or originated in the remote site.");
+ this.cache.getLogger().fine(builder.toString());
+ }
+ }
+ }
+
+ public void init(Properties p) {
+ }
+
+ private LocalRegion getGatewayDeltaRegion() {
+ if (this.gatewayDeltaRegion == null) {
+ this.gatewayDeltaRegion = createOrRetrieveGatewayDeltaRegion();
+ }
+ return this.gatewayDeltaRegion;
+ }
+
+ @SuppressWarnings("unchecked")
+ private LocalRegion createOrRetrieveGatewayDeltaRegion() {
+ Region region = this.cache.getRegion(GatewayDelta.GATEWAY_DELTA_REGION_NAME);
+ if (region == null) {
+ region = new RegionFactory().setScope(Scope.LOCAL)
+ .setDataPolicy(DataPolicy.EMPTY)
+ .setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL))
+// TODO: Disabled for WAN
+// .setEnableGateway(true)
+ .addCacheListener(new GatewayDeltaEventApplicationCacheListener())
+ .create(GatewayDelta.GATEWAY_DELTA_REGION_NAME);
+ }
+ if (this.cache.getLogger().fineEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GatewayDeltaForwarderCacheListener: Created gateway delta region: ").append(region);
+ this.cache.getLogger().fine(builder.toString());
+ }
+ return (LocalRegion) region;
+ }
+
+ public boolean equals(Object obj) {
+ // This method is only implemented so that RegionCreator.validateRegion works properly.
+ // The CacheListener comparison fails because two of these instances are not equal.
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || !(obj instanceof GatewayDeltaForwarderCacheListener)) {
+ return false;
+ }
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java
new file mode 100644
index 0000000..ea81309
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/AbstractCache.java
@@ -0,0 +1,398 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.bootstrap;
+
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.control.ResourceManager;
+import com.gemstone.gemfire.distributed.internal.AbstractDistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.modules.util.Banner;
+import com.gemstone.gemfire.modules.util.RegionHelper;
+import com.gemstone.gemfire.modules.util.ResourceManagerValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public abstract class AbstractCache {
+
+ protected GemFireCache cache;
+
+ private static final DateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+
+ protected static final String DEFAULT_LOG_FILE_NAME = RegionHelper.NAME + "." + FORMAT.format(new Date()) + ".log";
+
+ protected static final String DEFAULT_STATISTIC_ARCHIVE_FILE_NAME = RegionHelper.NAME + ".gfs";
+
+ protected static final float DEFAULT_EVICTION_HEAP_PERCENTAGE = LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE;
+
+ protected static final float DEFAULT_CRITICAL_HEAP_PERCENTAGE = ResourceManager.DEFAULT_CRITICAL_PERCENTAGE;
+
+ protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCache.class);
+
+ protected float evictionHeapPercentage = DEFAULT_EVICTION_HEAP_PERCENTAGE;
+
+ protected float criticalHeapPercentage = DEFAULT_CRITICAL_HEAP_PERCENTAGE;
+
+ protected boolean rebalance = false;
+
+ protected final Map<String, String> gemfireProperties;
+
+ private final AtomicBoolean started = new AtomicBoolean(false);
+
+ /**
+ * Instance reference which is set in static initialization blocks of any subclasses.
+ */
+ protected static AbstractCache instance = null;
+
+ public AbstractCache() {
+ this.gemfireProperties = new ConcurrentHashMap<String, String>();
+ }
+
+ public void lifecycleEvent(LifecycleTypeAdapter eventType) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Received " + eventType + " event");
+ }
+
+ if (eventType.equals(LifecycleTypeAdapter.START) && started.compareAndSet(false, true)) {
+ // Create or retrieve the cache
+ getLogger().info("Initializing " + Banner.getString());
+ createOrRetrieveCache();
+
+ // Initialize the resource manager
+ initializeResourceManager();
+ } else if (eventType.equals(LifecycleTypeAdapter.AFTER_START)) {
+ if (getRebalance()) {
+ rebalanceCache();
+ }
+ } else if (eventType.equals(LifecycleTypeAdapter.STOP)) {
+ // Close the cache
+// closeCache();
+ // TODO: Do we need to reset the started flag here?
+ }
+ }
+
+ public boolean isStarted() {
+ return started.get();
+ }
+
+ public void close() {
+ getCache().close();
+ while (!getCache().isClosed()) {
+ }
+
+ started.set(false);
+ }
+
+ public GemFireCache getCache() {
+ return this.cache;
+ }
+
+ public String getLogFileName() {
+ String logFileName = getGemFireProperties().get(DistributionConfig.LOG_FILE_NAME);
+ if (logFileName == null) {
+ logFileName = DEFAULT_LOG_FILE_NAME;
+ }
+ return logFileName;
+ }
+
+ public String getStatisticArchiveFileName() {
+ String statisticsArchiveFileName = getGemFireProperties().get(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME);
+ if (statisticsArchiveFileName == null) {
+ statisticsArchiveFileName = DEFAULT_STATISTIC_ARCHIVE_FILE_NAME;
+ }
+ return statisticsArchiveFileName;
+ }
+
+ public String getCacheXmlFileName() {
+ String cacheXmlFileName = getGemFireProperties().get(DistributionConfig.CACHE_XML_FILE_NAME);
+ if (cacheXmlFileName == null) {
+ cacheXmlFileName = getDefaultCacheXmlFileName();
+ }
+ return cacheXmlFileName;
+ }
+
+ protected File getCacheXmlFile() {
+ String cacheXmlFileName = getCacheXmlFileName();
+ File cacheXmlFile = new File(cacheXmlFileName);
+ // If the cache xml file is not absolute, point it at the conf directory.
+ if (!cacheXmlFile.isAbsolute()) {
+ if (System.getProperty("catalina.base") != null) {
+ cacheXmlFile = new File(System.getProperty("catalina.base") + "/conf/", cacheXmlFileName);
+ }
+ }
+ return cacheXmlFile;
+ }
+
+ public float getEvictionHeapPercentage() {
+ return this.evictionHeapPercentage;
+ }
+
+ public void setEvictionHeapPercentage(String evictionHeapPercentage) {
+ this.evictionHeapPercentage = Float.valueOf(evictionHeapPercentage);
+ }
+
+ public float getCriticalHeapPercentage() {
+ return this.criticalHeapPercentage;
+ }
+
+ public void setCriticalHeapPercentage(String criticalHeapPercentage) {
+ this.criticalHeapPercentage = Float.valueOf(criticalHeapPercentage);
+ }
+
+ public void setRebalance(boolean rebalance) {
+ this.rebalance = rebalance;
+ }
+
+ public boolean getRebalance() {
+ return this.rebalance;
+ }
+
+ public Map<String, String> getGemFireProperties() {
+ return this.gemfireProperties;
+ }
+
+ public void setProperty(String name, String value) {
+ //TODO Look at fake attributes
+ if (name.equals("className")) {
+ return;
+ }
+
+ // Determine the validity of the input property
+ boolean validProperty = false;
+ for (String gemfireProperty : AbstractDistributionConfig._getAttNames()) {
+ if (name.equals(gemfireProperty)) {
+ validProperty = true;
+ break;
+ }
+ }
+
+ // If it is a valid GemFire property, add it to the the GemFire properties.
+ // Otherwise, log a warning.
+ if (validProperty) {
+ this.gemfireProperties.put(name, value);
+ } else {
+ getLogger().warn("The input property named " + name + " is not a valid GemFire property. It is being ignored.");
+ }
+ }
+
+ public Logger getLogger() {
+ return LOGGER;
+ }
+
+ protected Properties createDistributedSystemProperties() {
+ Properties properties = new Properties();
+
+ // Add any additional gemfire properties
+ for (Map.Entry<String, String> entry : this.gemfireProperties.entrySet()) {
+ properties.put(entry.getKey(), entry.getValue());
+ }
+
+ // Replace the cache xml file in the properties
+ File cacheXmlFile = getCacheXmlFile();
+ String absoluteCacheXmlFileName = cacheXmlFile.getAbsolutePath();
+ // If the file doesn't exist and the name is the default, set cache-xml-file
+ // to the GemFire default. This is for the case where only the jars have been
+ // installed and no default cache.xml exists in the conf directory.
+ if (getCacheXmlFileName().equals(getDefaultCacheXmlFileName()) && !cacheXmlFile.exists()) {
+ absoluteCacheXmlFileName = DistributionConfig.DEFAULT_CACHE_XML_FILE.getName();
+ }
+ properties.put(DistributionConfig.CACHE_XML_FILE_NAME, absoluteCacheXmlFileName);
+
+ // Replace the log file in the properties
+ properties.put(DistributionConfig.LOG_FILE_NAME, getLogFile().getAbsolutePath());
+
+ // Replace the statistics archive file in the properties
+ File statisticArchiveFile = getStatisticArchiveFile();
+ if (statisticArchiveFile == null) {
+ // Remove the statistics archive file name since statistic sampling is disabled
+ properties.remove(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME);
+ properties.remove(DistributionConfig.STATISTIC_SAMPLING_ENABLED_NAME);
+ } else {
+ properties.put(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME, statisticArchiveFile.getAbsolutePath());
+ }
+ getLogger().info("Creating distributed system from: " + properties);
+
+ return properties;
+ }
+
+ protected void closeCache() {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Closing " + this.cache);
+ }
+ if (getCache() != null) {
+ getCache().close();
+ }
+ getLogger().info("Closed " + this.cache);
+ }
+
+ protected File getLogFile() {
+ String logFileName = getLogFileName();
+ File logFile = new File(logFileName);
+ // If the log file is not absolute, point it at the logs directory.
+ if (!logFile.isAbsolute()) {
+ if (System.getProperty("catalina.base") != null) {
+ logFile = new File(System.getProperty("catalina.base") + "/logs/", logFileName);
+ } else if (System.getProperty("weblogic.Name") != null) {
+ String weblogicName = System.getProperty("weblogic.Name");
+ String separator = System.getProperty("file.separator");
+ logFile = new File("servers" + separator + weblogicName + separator +
+ "logs" + separator + logFileName);
+ } else {
+ logFile = new File(System.getProperty("gemfire.logdir"), logFileName);
+ }
+ }
+ return logFile;
+ }
+
+ protected File getStatisticArchiveFile() {
+ File statisticsArchiveFile = null;
+ String statisticSamplingEnabled = getGemFireProperties().get(DistributionConfig.STATISTIC_SAMPLING_ENABLED_NAME);
+ if (statisticSamplingEnabled != null && statisticSamplingEnabled.equals("true")) {
+ String statisticsArchiveFileName = getStatisticArchiveFileName();
+ statisticsArchiveFile = new File(statisticsArchiveFileName);
+ // If the statistics archive file is not absolute, point it at the logs directory.
+ if (!statisticsArchiveFile.isAbsolute()) {
+ if (System.getProperty("catalina.base") != null) {
+ statisticsArchiveFile = new File(System.getProperty("catalina.base") + "/logs/", statisticsArchiveFileName);
+ } else if (System.getProperty("weblogic.Name") != null) {
+ String weblogicName = System.getProperty("weblogic.Name");
+ String separator = System.getProperty("file.separator");
+ statisticsArchiveFile = new File("servers" + separator + weblogicName + separator +
+ "logs" + separator + statisticsArchiveFileName);
+ } else {
+ statisticsArchiveFile = new File(System.getProperty("gemfire.statisticsdir"), statisticsArchiveFileName);
+ }
+ }
+ }
+ return statisticsArchiveFile;
+ }
+
+ protected void initializeResourceManager() {
+ // Get current eviction and critical heap percentages
+ ResourceManager rm = getCache().getResourceManager();
+ float currentEvictionHeapPercentage = rm.getEvictionHeapPercentage();
+ float currentCriticalHeapPercentage = rm.getCriticalHeapPercentage();
+
+ // Set new eviction and critical heap percentages if necessary
+ if (getEvictionHeapPercentage() != currentEvictionHeapPercentage || getCriticalHeapPercentage() != currentCriticalHeapPercentage) {
+ if (getLogger().isDebugEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Previous eviction heap percentage=")
+ .append(currentEvictionHeapPercentage)
+ .append("; critical heap percentage=")
+ .append(currentCriticalHeapPercentage);
+ getLogger().debug(builder.toString());
+ builder.setLength(0);
+ builder.append("Requested eviction heap percentage=")
+ .append(getEvictionHeapPercentage())
+ .append("; critical heap percentage=")
+ .append(getCriticalHeapPercentage());
+ getLogger().debug(builder.toString());
+ }
+ if (currentCriticalHeapPercentage == 0.0f) {
+ // If the current critical heap percentage is 0 (disabled), set eviction
+ // heap percentage first, then set the critical heap percentage. At this
+ // point, the eviction heap percentage can be set to anything.
+ try {
+ rm.setEvictionHeapPercentage(getEvictionHeapPercentage());
+ rm.setCriticalHeapPercentage(getCriticalHeapPercentage());
+ } catch (IllegalArgumentException e) {
+ handleResourceManagerException(e, currentEvictionHeapPercentage, currentCriticalHeapPercentage);
+ rm.setEvictionHeapPercentage(currentEvictionHeapPercentage);
+ rm.setCriticalHeapPercentage(currentCriticalHeapPercentage);
+ }
+ } else if (getCriticalHeapPercentage() >= currentCriticalHeapPercentage) {
+ // If the requested critical heap percentage is >= the current critical
+ // heap percentage, then set the critical heap percentage first since it
+ // can safely be slid up. Then, set the eviction heap percentage.
+ try {
+ rm.setCriticalHeapPercentage(getCriticalHeapPercentage());
+ rm.setEvictionHeapPercentage(getEvictionHeapPercentage());
+ } catch (IllegalArgumentException e) {
+ handleResourceManagerException(e, currentEvictionHeapPercentage, currentCriticalHeapPercentage);
+ rm.setCriticalHeapPercentage(currentCriticalHeapPercentage);
+ rm.setEvictionHeapPercentage(currentEvictionHeapPercentage);
+ }
+ } else {
+ // If the requested critical heap percentage is < the current critical
+ // heap percentage, then set the eviction heap percentage first since it
+ // can safely be slid down. Then, set the critical heap percentage.
+ try {
+ rm.setEvictionHeapPercentage(getEvictionHeapPercentage());
+ rm.setCriticalHeapPercentage(getCriticalHeapPercentage());
+ } catch (IllegalArgumentException e) {
+ handleResourceManagerException(e, currentEvictionHeapPercentage, currentCriticalHeapPercentage);
+ rm.setEvictionHeapPercentage(currentEvictionHeapPercentage);
+ rm.setCriticalHeapPercentage(currentCriticalHeapPercentage);
+ }
+ }
+ if (getLogger().isDebugEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Actual eviction heap percentage=")
+ .append(rm.getEvictionHeapPercentage())
+ .append("; critical heap percentage=")
+ .append(rm.getCriticalHeapPercentage());
+ getLogger().debug(builder.toString());
+ }
+ }
+
+ // Validate java startup parameters (done after setting the eviction and
+ // critical heap percentages so that the CMSInitiatingOccupancyFraction can
+ // be compared against them.
+ ResourceManagerValidator.validateJavaStartupParameters(getCache());
+ }
+
+ private void handleResourceManagerException(IllegalArgumentException e, float currentEvictionHeapPercentage,
+ float currentCriticalHeapPercentage) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Caught exception attempting to set eviction heap percentage=")
+ .append(getEvictionHeapPercentage())
+ .append(" and critical heap percentage=")
+ .append(getCriticalHeapPercentage())
+ .append(". The percentages will be set back to their previous values (eviction heap percentage=")
+ .append(currentEvictionHeapPercentage)
+ .append(" and critical heap percentage=")
+ .append(currentCriticalHeapPercentage)
+ .append(").");
+ getLogger().warn(builder.toString(), e);
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder().append(getClass().getSimpleName())
+ .append("[")
+ .append("cache=")
+ .append(this.cache)
+ .append("]")
+ .toString();
+ }
+
+ protected abstract void createOrRetrieveCache();
+
+ protected abstract void rebalanceCache();
+
+ protected abstract String getDefaultCacheXmlFileName();
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java
new file mode 100644
index 0000000..f8cff16
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/ClientServerCache.java
@@ -0,0 +1,74 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.bootstrap;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+
+/**
+ * This is a singleton class which maintains configuration properties as well as starting a Client-Server cache.
+ */
+public class ClientServerCache extends AbstractCache {
+
+ protected static final String DEFAULT_CACHE_XML_FILE_NAME = "cache-client.xml";
+
+ static {
+ instance = new ClientServerCache();
+ }
+
+ private ClientServerCache() {
+ // Singleton
+ super();
+ }
+
+ public static AbstractCache getInstance() {
+ return instance;
+ }
+
+ @Override
+ protected void createOrRetrieveCache() {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug(this + ": Creating cache");
+ }
+ // Get the existing cache if any
+ try {
+ this.cache = ClientCacheFactory.getAnyInstance();
+ } catch (CacheClosedException e) {
+ }
+
+ // If no cache exists, create one
+ String message = null;
+ if (this.cache == null) {
+ // enable pool subscription so that default cache can be used by hibernate module
+ this.cache = new ClientCacheFactory(createDistributedSystemProperties()).create();
+ message = "Created ";
+ } else {
+ message = "Retrieved ";
+ }
+ getLogger().info(message + this.cache);
+ }
+
+ @Override
+ protected void rebalanceCache() {
+ getLogger().warn("The client cannot rebalance the server's cache.");
+ }
+
+ @Override
+ protected String getDefaultCacheXmlFileName() {
+ return DEFAULT_CACHE_XML_FILE_NAME;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java
new file mode 100644
index 0000000..2f0c9bb
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/LifecycleTypeAdapter.java
@@ -0,0 +1,59 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.gemstone.gemfire.modules.session.bootstrap;
+
+/**
+ * Adapter for the Catalina Lifecycle event types
+ */
+public enum LifecycleTypeAdapter {
+
+ CONFIGURE_START,
+
+ CONFIGURE_STOP,
+
+ AFTER_DESTROY,
+
+ AFTER_INIT,
+
+ AFTER_START,
+
+ AFTER_STOP,
+
+ BEFORE_DESTROY,
+
+ BEFORE_INIT,
+
+ BEFORE_START,
+
+ BEFORE_STOP,
+
+ DESTROY,
+
+ INIT,
+
+ PERIODIC,
+
+ START,
+
+ STOP;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java
new file mode 100644
index 0000000..b0b3b4a
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/bootstrap/PeerToPeerCache.java
@@ -0,0 +1,85 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.bootstrap;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.control.RebalanceResults;
+import com.gemstone.gemfire.modules.util.RegionHelper;
+
+/**
+ * This is a singleton class which maintains configuration properties as well as starting a Peer-To-Peer cache.
+ */
+
+public class PeerToPeerCache extends AbstractCache {
+
+ protected static final String DEFAULT_CACHE_XML_FILE_NAME = "cache-peer.xml";
+
+ static {
+ instance = new PeerToPeerCache();
+ }
+
+ private PeerToPeerCache() {
+ // Singleton
+ super();
+ }
+
+ public static AbstractCache getInstance() {
+ return instance;
+ }
+
+ @Override
+ protected void createOrRetrieveCache() {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Creating cache");
+ }
+ // Get the existing cache if any
+ try {
+ this.cache = CacheFactory.getAnyInstance();
+ } catch (CacheClosedException e) {
+ }
+
+ // If no cache exists, create one
+ String message = null;
+ if (this.cache == null) {
+ this.cache = new CacheFactory(createDistributedSystemProperties()).create();
+ message = "Created ";
+ } else {
+ message = "Retrieved ";
+ }
+ getLogger().info(message + this.cache);
+ }
+
+ @Override
+ protected void rebalanceCache() {
+ try {
+ getLogger().info("Rebalancing: " + this.cache);
+ RebalanceResults results = RegionHelper.rebalanceCache(this.cache);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Done rebalancing: " + this.cache);
+ getLogger().debug(RegionHelper.getRebalanceResultsMessage(results));
+ }
+ } catch (Exception e) {
+ getLogger().warn("Rebalance failed because of the following exception:", e);
+ }
+ }
+
+ @Override
+ protected String getDefaultCacheXmlFileName() {
+ return DEFAULT_CACHE_XML_FILE_NAME;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java
new file mode 100644
index 0000000..1019ddc
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractCacheLifecycleListener.java
@@ -0,0 +1,68 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.catalina;
+
+
+import com.gemstone.gemfire.modules.session.bootstrap.AbstractCache;
+import com.gemstone.gemfire.modules.session.bootstrap.LifecycleTypeAdapter;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+
+
+public abstract class AbstractCacheLifecycleListener implements LifecycleListener {
+ protected AbstractCache cache;
+
+ @Override
+ public void lifecycleEvent(LifecycleEvent le) {
+ cache.lifecycleEvent(LifecycleTypeAdapter.valueOf(le.getType().toUpperCase()));
+ }
+
+ /**
+ * This is called by Tomcat to set properties on the Listener.
+ */
+ public void setProperty(String name, String value) {
+ cache.setProperty(name, value);
+ }
+
+ /*
+ * These getters and setters are also called by Tomcat and just passed on to
+ * the cache.
+ */
+ public float getEvictionHeapPercentage() {
+ return cache.getEvictionHeapPercentage();
+ }
+
+ public void setEvictionHeapPercentage(String evictionHeapPercentage) {
+ cache.setEvictionHeapPercentage(evictionHeapPercentage);
+ }
+
+ public float getCriticalHeapPercentage() {
+ return cache.getCriticalHeapPercentage();
+ }
+
+ public void setCriticalHeapPercentage(String criticalHeapPercentage) {
+ cache.setCriticalHeapPercentage(criticalHeapPercentage);
+ }
+
+ public void setRebalance(boolean rebalance) {
+ cache.setRebalance(rebalance);
+ }
+
+ public boolean getRebalance() {
+ return cache.getRebalance();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java
new file mode 100644
index 0000000..3019cae
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/AbstractSessionCache.java
@@ -0,0 +1,113 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.catalina;
+
+import com.gemstone.gemfire.cache.EntryNotFoundException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.session.catalina.internal.DeltaSessionStatistics;
+import com.gemstone.gemfire.modules.util.RegionConfiguration;
+import com.gemstone.gemfire.modules.util.SessionCustomExpiry;
+import org.apache.catalina.Session;
+
+import javax.servlet.http.HttpSession;
+
+public abstract class AbstractSessionCache implements SessionCache {
+
+ protected SessionManager sessionManager;
+
+ /**
+ * The sessionRegion is the <code>Region</code> that actually stores and replicates the <code>Session</code>s.
+ */
+ protected Region<String, HttpSession> sessionRegion;
+
+ /**
+ * The operatingRegion is the <code>Region</code> used to do HTTP operations. if local cache is enabled, then this
+ * will be the local <code>Region</code>; otherwise, it will be the session <code>Region</code>.
+ */
+ protected Region<String, HttpSession> operatingRegion;
+
+ protected DeltaSessionStatistics statistics;
+
+ public AbstractSessionCache(SessionManager sessionManager) {
+ this.sessionManager = sessionManager;
+ }
+
+ @Override
+ public String getSessionRegionName() {
+ return getSessionRegion().getFullPath();
+ }
+
+ @Override
+ public String getOperatingRegionName() {
+ return getOperatingRegion().getFullPath();
+ }
+
+ @Override
+ public void putSession(Session session) {
+ getOperatingRegion().put(session.getId(), (HttpSession) session);
+ }
+
+ @Override
+ public HttpSession getSession(String sessionId) {
+ return getOperatingRegion().get(sessionId);
+ }
+
+ @Override
+ public void destroySession(String sessionId) {
+ try {
+ getOperatingRegion().destroy(sessionId);
+ } catch (EntryNotFoundException enex) {
+ // Ignored
+ }
+ }
+
+ @Override
+ public DeltaSessionStatistics getStatistics() {
+ return this.statistics;
+ }
+
+ protected SessionManager getSessionManager() {
+ return this.sessionManager;
+ }
+
+ public Region<String, HttpSession> getSessionRegion() {
+ return this.sessionRegion;
+ }
+
+ public Region<String, HttpSession> getOperatingRegion() {
+ return this.operatingRegion;
+ }
+
+ protected void createStatistics() {
+ this.statistics = new DeltaSessionStatistics(getCache().getDistributedSystem(),
+ getSessionManager().getStatisticsName());
+ }
+
+ protected RegionConfiguration createRegionConfiguration() {
+ RegionConfiguration configuration = new RegionConfiguration();
+ configuration.setRegionName(getSessionManager().getRegionName());
+ configuration.setRegionAttributesId(getSessionManager().getRegionAttributesId());
+ if (getSessionManager().getMaxInactiveInterval() != RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL) {
+ configuration.setMaxInactiveInterval(getSessionManager().getMaxInactiveInterval());
+ configuration.setCustomExpiry(new SessionCustomExpiry());
+ }
+ configuration.setEnableGatewayDeltaReplication(getSessionManager().getEnableGatewayDeltaReplication());
+ configuration.setEnableGatewayReplication(getSessionManager().getEnableGatewayReplication());
+ configuration.setEnableDebugListener(getSessionManager().getEnableDebugListener());
+ return configuration;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java
new file mode 100644
index 0000000..ba66fa2
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerCacheLifecycleListener.java
@@ -0,0 +1,26 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.catalina;
+
+import com.gemstone.gemfire.modules.session.bootstrap.ClientServerCache;
+
+public class ClientServerCacheLifecycleListener extends AbstractCacheLifecycleListener {
+
+ public ClientServerCacheLifecycleListener() {
+ cache = ClientServerCache.getInstance();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java
new file mode 100644
index 0000000..2de43b4
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/ClientServerSessionCache.java
@@ -0,0 +1,252 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.catalina;
+
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientRegionFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.modules.session.catalina.callback.SessionExpirationCacheListener;
+import com.gemstone.gemfire.modules.util.BootstrappingFunction;
+import com.gemstone.gemfire.modules.util.CreateRegionFunction;
+import com.gemstone.gemfire.modules.util.RegionConfiguration;
+import com.gemstone.gemfire.modules.util.RegionSizeFunction;
+import com.gemstone.gemfire.modules.util.RegionStatus;
+import com.gemstone.gemfire.modules.util.SessionCustomExpiry;
+import com.gemstone.gemfire.modules.util.TouchPartitionedRegionEntriesFunction;
+import com.gemstone.gemfire.modules.util.TouchReplicatedRegionEntriesFunction;
+
+import javax.servlet.http.HttpSession;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ClientServerSessionCache extends AbstractSessionCache {
+
+ private ClientCache cache;
+
+ protected static final String DEFAULT_REGION_ATTRIBUTES_ID = RegionShortcut.PARTITION_REDUNDANT.toString();
+
+ protected static final boolean DEFAULT_ENABLE_LOCAL_CACHE = true;
+
+ public ClientServerSessionCache(SessionManager sessionManager, ClientCache cache) {
+ super(sessionManager);
+ this.cache = cache;
+ }
+
+ @Override
+ public void initialize() {
+ // Bootstrap the servers
+ bootstrapServers();
+
+ // Create or retrieve the region
+ try {
+ createOrRetrieveRegion();
+ } catch (Exception ex) {
+ sessionManager.getLogger().fatal("Unable to create or retrieve region", ex);
+ throw new IllegalStateException(ex);
+ }
+
+ // Set the session region directly as the operating region since there is no difference
+ // between the local cache region and the session region.
+ this.operatingRegion = this.sessionRegion;
+
+ // Create or retrieve the statistics
+ createStatistics();
+ }
+
+ @Override
+ public String getDefaultRegionAttributesId() {
+ return DEFAULT_REGION_ATTRIBUTES_ID;
+ }
+
+ @Override
+ public boolean getDefaultEnableLocalCache() {
+ return DEFAULT_ENABLE_LOCAL_CACHE;
+ }
+
+ @Override
+ public void touchSessions(Set<String> sessionIds) {
+ // Get the region attributes id to determine the region type. This is
+ // problematic since the region attributes id doesn't really define the
+ // region type. Currently there is no way to know the type of region created
+ // on the server. Maybe the CreateRegionFunction should return it.
+ String regionAttributesID = getSessionManager().getRegionAttributesId().toLowerCase();
+
+ // Invoke the appropriate function depending on the type of region
+ if (regionAttributesID.startsWith("partition")) {
+ // Execute the partitioned touch function on the primary server(s)
+ Execution execution = FunctionService.onRegion(getSessionRegion()).withFilter(sessionIds);
+ try {
+ ResultCollector collector = execution.execute(TouchPartitionedRegionEntriesFunction.ID, true, false, true);
+ collector.getResult();
+ } catch (Exception e) {
+ // If an exception occurs in the function, log it.
+ getSessionManager().getLogger().warn("Caught unexpected exception:", e);
+ }
+ } else {
+ // Execute the member touch function on all the server(s)
+ Execution execution = FunctionService.onServers(getCache())
+ .withArgs(new Object[]{this.sessionRegion.getFullPath(), sessionIds});
+ try {
+ ResultCollector collector = execution.execute(TouchReplicatedRegionEntriesFunction.ID, true, false, false);
+ collector.getResult();
+ } catch (Exception e) {
+ // If an exception occurs in the function, log it.
+ getSessionManager().getLogger().warn("Caught unexpected exception:", e);
+ }
+ }
+ }
+
+ @Override
+ public boolean isPeerToPeer() {
+ return false;
+ }
+
+ @Override
+ public boolean isClientServer() {
+ return true;
+ }
+
+ @Override
+ public Set<String> keySet() {
+ return getSessionRegion().keySetOnServer();
+ }
+
+ @Override
+ public int size() {
+ // Add a single dummy key to force the function to go to one server
+ Set<String> filters = new HashSet<String>();
+ filters.add("test-key");
+
+ // Execute the function on the session region
+ Execution execution = FunctionService.onRegion(getSessionRegion()).withFilter(filters);
+ ResultCollector collector = execution.execute(RegionSizeFunction.ID, true, true, true);
+ List<Integer> result = (List<Integer>) collector.getResult();
+
+ // Return the first (and only) element
+ return result.get(0);
+ }
+
+ @Override
+ public boolean isBackingCacheAvailable() {
+ if (getSessionManager().isCommitValveFailfastEnabled()) {
+ PoolImpl pool = (PoolImpl) PoolManager.find(getOperatingRegionName());
+ return pool.isPrimaryUpdaterAlive();
+ }
+ return true;
+ }
+
+ public GemFireCache getCache() {
+ return this.cache;
+ }
+
+ private void bootstrapServers() {
+ Execution execution = FunctionService.onServers(this.cache);
+ ResultCollector collector = execution.execute(new BootstrappingFunction());
+ // Get the result. Nothing is being done with it.
+ try {
+ collector.getResult();
+ } catch (Exception e) {
+ // If an exception occurs in the function, log it.
+ getSessionManager().getLogger().warn("Caught unexpected exception:", e);
+ }
+ }
+
+ protected void createOrRetrieveRegion() {
+ // Retrieve the local session region
+ this.sessionRegion = this.cache.getRegion(getSessionManager().getRegionName());
+
+ // If necessary, create the regions on the server and client
+ if (this.sessionRegion == null) {
+ // Create the PR on the servers
+ createSessionRegionOnServers();
+
+ // Create the region on the client
+ this.sessionRegion = createLocalSessionRegion();
+ if (getSessionManager().getLogger().isDebugEnabled()) {
+ getSessionManager().getLogger().debug("Created session region: " + this.sessionRegion);
+ }
+ } else {
+ if (getSessionManager().getLogger().isDebugEnabled()) {
+ getSessionManager().getLogger().debug("Retrieved session region: " + this.sessionRegion);
+ }
+ }
+ }
+
+ private void createSessionRegionOnServers() {
+ // Create the RegionConfiguration
+ RegionConfiguration configuration = createRegionConfiguration();
+
+ // Send it to the server tier
+ Execution execution = FunctionService.onServer(this.cache).withArgs(configuration);
+ ResultCollector collector = execution.execute(CreateRegionFunction.ID);
+
+ // Verify the region was successfully created on the servers
+ List<RegionStatus> results = (List<RegionStatus>) collector.getResult();
+ for (RegionStatus status : results) {
+ if (status == RegionStatus.INVALID) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("An exception occurred on the server while attempting to create or validate region named ")
+ .append(getSessionManager().getRegionName())
+ .append(". See the server log for additional details.");
+ throw new IllegalStateException(builder.toString());
+ }
+ }
+ }
+
+ private Region<String, HttpSession> createLocalSessionRegion() {
+ ClientRegionFactory<String, HttpSession> factory = null;
+ if (getSessionManager().getEnableLocalCache()) {
+ // Create the region factory with caching and heap LRU enabled
+ factory = this.cache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU);
+
+ // Set the expiration time, action and listener if necessary
+ int maxInactiveInterval = getSessionManager().getMaxInactiveInterval();
+ if (maxInactiveInterval != RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL) {
+ factory.setStatisticsEnabled(true);
+ factory.setCustomEntryIdleTimeout(new SessionCustomExpiry());
+ factory.addCacheListener(new SessionExpirationCacheListener());
+ }
+ } else {
+ // Create the region factory without caching enabled
+ factory = this.cache.createClientRegionFactory(ClientRegionShortcut.PROXY);
+ factory.addCacheListener(new SessionExpirationCacheListener());
+ }
+
+ // Create the region
+ Region region = factory.create(getSessionManager().getRegionName());
+
+ /*
+ * If we're using an empty client region, we register interest so that
+ * expired sessions are destroyed correctly.
+ */
+ if (!getSessionManager().getEnableLocalCache()) {
+ region.registerInterest("ALL_KEYS", InterestResultPolicy.KEYS);
+ }
+
+ return region;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/48552465/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java
----------------------------------------------------------------------
diff --git a/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java
new file mode 100644
index 0000000..0ae17f2
--- /dev/null
+++ b/extensions/gemfire-modules/src/main/java/com/gemstone/gemfire/modules/session/catalina/CommitSessionValve.java
@@ -0,0 +1,68 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.gemstone.gemfire.modules.session.catalina;
+
+import org.apache.catalina.Manager;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+
+public class CommitSessionValve extends ValveBase {
+
+ private static final Log log = LogFactory.getLog(CommitSessionValve.class);
+
+ protected static final String info = "com.gemstone.gemfire.modules.session.catalina.CommitSessionValve/1.0";
+
+ public CommitSessionValve() {
+ log.info("Initialized");
+ }
+
+ @Override
+ public void invoke(Request request, Response response) throws IOException, ServletException {
+ // Get the Manager
+ Manager manager = request.getContext().getManager();
+ DeltaSessionFacade session = null;
+
+ // Invoke the next Valve
+ try {
+ getNext().invoke(request, response);
+ } finally {
+ // Commit and if the correct Manager was found
+ if (manager instanceof DeltaSessionManager) {
+ session = (DeltaSessionFacade) request.getSession(false);
+ if (session != null) {
+ if (session.isValid()) {
+ ((DeltaSessionManager) manager).removeTouchedSession(session.getId());
+ session.commit();
+ if (manager.getContainer().getLogger().isDebugEnabled()) {
+ manager.getContainer().getLogger().debug(session + ": Committed.");
+ }
+ } else {
+ if (manager.getContainer().getLogger().isDebugEnabled()) {
+ manager.getContainer().getLogger().debug(session + ": Not valid so not committing.");
+ }
+ }
+ }
+ }
+ }
+ }
+}