From 7822c0ac3ad57019ffd9220945c7314145b1deee Mon Sep 17 00:00:00 2001 From: "masaki.yamakawa" Date: Fri, 22 Apr 2022 22:09:45 +0900 Subject: [PATCH] GEODE-10256: HttpSessionListener is not working --- extensions/geode-modules/build.gradle | 4 +- .../modules/util/SessionCustomExpiry.java | 33 ++++- .../modules/util/SessionCustomExpiryTest.java | 137 ++++++++++++++++++ 3 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 extensions/geode-modules/src/test/java/org/apache/geode/modules/util/SessionCustomExpiryTest.java diff --git a/extensions/geode-modules/build.gradle b/extensions/geode-modules/build.gradle index 806dceddc9f0..ec15d4ea0bfb 100644 --- a/extensions/geode-modules/build.gradle +++ b/extensions/geode-modules/build.gradle @@ -45,7 +45,9 @@ dependencies { testImplementation('org.assertj:assertj-core') testImplementation('org.mockito:mockito-core') testImplementation('org.apache.tomcat:catalina-ha:' + DependencyConstraints.get('tomcat6.version')) - + testImplementation(project(':geode-junit')) { + exclude module: 'geode-core' + } // integrationTest integrationTestImplementation(project(':extensions:geode-modules-test')) diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/SessionCustomExpiry.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/SessionCustomExpiry.java index 5cc35071ce90..c348f6d427bb 100644 --- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/SessionCustomExpiry.java +++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/SessionCustomExpiry.java @@ -18,11 +18,14 @@ import javax.servlet.http.HttpSession; +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.CustomExpiry; import org.apache.geode.cache.Declarable; import org.apache.geode.cache.ExpirationAction; import org.apache.geode.cache.ExpirationAttributes; import org.apache.geode.cache.Region; +import org.apache.geode.util.internal.GeodeGlossary; @SuppressWarnings("serial") public class SessionCustomExpiry @@ -33,12 +36,16 @@ public class SessionCustomExpiry private static final ExpirationAttributes EXPIRE_NOW = new ExpirationAttributes(1, ExpirationAction.DESTROY); + private static int SESSION_EXPIRY_DELAY = Integer + .parseInt(System.getProperty(GeodeGlossary.GEMFIRE_PREFIX + "SessionExpiry.Delay", "0")); + + private static Boolean isServer = null; + @Override public ExpirationAttributes getExpiry(Region.Entry entry) { HttpSession session = entry.getValue(); if (session != null) { - return new ExpirationAttributes(entry.getValue().getMaxInactiveInterval(), - ExpirationAction.DESTROY); + return new ExpirationAttributes(getExpirationTime(entry), ExpirationAction.DESTROY); } else { return EXPIRE_NOW; } @@ -64,6 +71,26 @@ public int hashCode() { @Override public String toString() { - return getClass().toString(); + return this.getClass().toString(); + } + + private int getExpirationTime(Region.Entry entry) { + int expirationTime = entry.getValue().getMaxInactiveInterval(); + if (isServer() && expirationTime > 0) { + expirationTime = expirationTime + SESSION_EXPIRY_DELAY; + } + return expirationTime; + } + + // The following helper method is to allow for proper mocking in unit tests + Cache getCache() { + return CacheFactory.getAnyInstance(); + } + + private boolean isServer() { + if (isServer == null) { + isServer = getCache().isServer(); + } + return isServer; } } diff --git a/extensions/geode-modules/src/test/java/org/apache/geode/modules/util/SessionCustomExpiryTest.java b/extensions/geode-modules/src/test/java/org/apache/geode/modules/util/SessionCustomExpiryTest.java new file mode 100644 index 000000000000..a2a609249e0c --- /dev/null +++ b/extensions/geode-modules/src/test/java/org/apache/geode/modules/util/SessionCustomExpiryTest.java @@ -0,0 +1,137 @@ +/* + * 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 org.apache.geode.modules.util; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Field; + +import javax.servlet.http.HttpSession; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; + +import org.apache.geode.cache.ExpirationAction; +import org.apache.geode.cache.ExpirationAttributes; +import org.apache.geode.cache.Region; +import org.apache.geode.internal.cache.InternalCache; +import org.apache.geode.modules.session.catalina.DeltaSession; +import org.apache.geode.util.internal.GeodeGlossary; + +public class SessionCustomExpiryTest { + + @Rule + public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); + + private InternalCache cache = mock(InternalCache.class); + private SessionCustomExpiry expiry; + private int expiryDelay = 3; + + @Before + public void setUp() throws Exception { + System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "SessionExpiry.Delay", + String.valueOf(expiryDelay)); + + Field isServerField = SessionCustomExpiry.class.getDeclaredField("isServer"); + isServerField.setAccessible(true); + isServerField.set(null, null); + + expiry = spy(SessionCustomExpiry.class); + doReturn(cache).when(expiry).getCache(); + } + + @Test + public void testGetExpiryOnServerWhenSetMaxInactiveInterval() { + final Region.Entry entry = mock(Region.Entry.class); + final DeltaSession session = mock(DeltaSession.class); + final int maxInactiveInterval = 2000; + + when(cache.isServer()).thenReturn(true); + when(entry.getValue()).thenReturn(session); + when(session.getMaxInactiveInterval()).thenReturn(maxInactiveInterval); + + ExpirationAttributes expirationAttrs = expiry.getExpiry(entry); + + assertThat(expirationAttrs).isEqualTo( + new ExpirationAttributes(maxInactiveInterval + expiryDelay, ExpirationAction.DESTROY)); + } + + @Test + public void testGetExpiryOnServerWhenSetMaxInactiveIntervalZero() { + final Region.Entry entry = mock(Region.Entry.class); + final DeltaSession session = mock(DeltaSession.class); + final int maxInactiveInterval = 0; + + when(cache.isServer()).thenReturn(true); + when(entry.getValue()).thenReturn(session); + when(session.getMaxInactiveInterval()).thenReturn(maxInactiveInterval); + + ExpirationAttributes expirationAttrs = expiry.getExpiry(entry); + + assertThat(expirationAttrs) + .isEqualTo(new ExpirationAttributes(maxInactiveInterval, ExpirationAction.DESTROY)); + } + + @Test + public void testGetExpiryOnClientWhenSetMaxInactiveInterval() { + final Region.Entry entry = mock(Region.Entry.class); + final DeltaSession session = mock(DeltaSession.class); + final int maxInactiveInterval = 3000; + + when(cache.isServer()).thenReturn(false); + when(entry.getValue()).thenReturn(session); + when(session.getMaxInactiveInterval()).thenReturn(maxInactiveInterval); + + ExpirationAttributes expirationAttrs = expiry.getExpiry(entry); + + assertThat(expirationAttrs) + .isEqualTo(new ExpirationAttributes(maxInactiveInterval, ExpirationAction.DESTROY)); + } + + @Test + public void testGetExpiryOnClientWhenSetMaxInactiveIntervalZero() { + final Region.Entry entry = mock(Region.Entry.class); + final DeltaSession session = mock(DeltaSession.class); + final int maxInactiveInterval = 0; + + when(cache.isServer()).thenReturn(false); + when(entry.getValue()).thenReturn(session); + when(session.getMaxInactiveInterval()).thenReturn(maxInactiveInterval); + + ExpirationAttributes expirationAttrs = expiry.getExpiry(entry); + + assertThat(expirationAttrs) + .isEqualTo(new ExpirationAttributes(maxInactiveInterval, ExpirationAction.DESTROY)); + } + + @Test + public void testGetExpiryWhenSessionIsNull() { + final Region.Entry entry = mock(Region.Entry.class); + + when(cache.isServer()).thenReturn(true); + when(entry.getValue()).thenReturn(null); + + ExpirationAttributes expirationAttrs = expiry.getExpiry(entry); + + assertThat(expirationAttrs).isEqualTo(new ExpirationAttributes(1, ExpirationAction.DESTROY)); + } +}