Remove DataSerializable serialization logic from GemFireSession and GemFireSessionAttributes classes.
Move Delta serialization logic to new DeltaCapableGemFireSession and DeltaCapableGemFireSessionAttributes subclasses. Fix up all test class compilation issues and failures. Resolves Issue #2.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.session.data.gemfire;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.asArray;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -25,9 +26,7 @@ import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -37,9 +36,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionAttributes;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
@@ -51,10 +48,10 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
|
||||
import org.springframework.data.gemfire.client.PoolFactoryBean;
|
||||
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerConfigurer;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer;
|
||||
import org.springframework.data.gemfire.support.ConnectionEndpoint;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
@@ -71,31 +68,36 @@ import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.SocketUtils;
|
||||
|
||||
/**
|
||||
* Integration tests to test the functionality of GemFire-backed Spring Sessions using
|
||||
* the GemFire client-server topology.
|
||||
* Integration tests testing the functionality of Apache Geode / Pivotal GemFire backed Spring Sessions
|
||||
* using the GemFire client-server topology.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.1.0
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.session.Session
|
||||
* @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
||||
* @see org.springframework.test.annotation.DirtiesContext
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @see org.springframework.test.context.web.WebAppConfiguration
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.apache.geode.cache.client.Pool
|
||||
* @see org.apache.geode.cache.server.CacheServer
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
|
||||
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
|
||||
* @see org.springframework.session.Session
|
||||
* @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
||||
* @see org.springframework.session.events.SessionCreatedEvent
|
||||
* @see org.springframework.session.events.SessionDeletedEvent
|
||||
* @see org.springframework.session.events.SessionExpiredEvent
|
||||
* @see org.springframework.test.annotation.DirtiesContext
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @see org.springframework.test.context.web.WebAppConfiguration
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes =
|
||||
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionDataGemFireClientConfiguration.class)
|
||||
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.TestGemFireClientConfiguration.class)
|
||||
@DirtiesContext
|
||||
@WebAppConfiguration
|
||||
public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
@@ -109,9 +111,10 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
private static Process gemfireServer;
|
||||
|
||||
private static final String SPRING_SESSION_GEMFIRE_REGION_NAME = "TestClientServerSessions";
|
||||
private static final String TEST_SESSION_REGION_NAME = "TestClientServerSessions";
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("all")
|
||||
private SessionEventListener sessionEventListener;
|
||||
|
||||
@BeforeClass
|
||||
@@ -122,7 +125,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
int port = SocketUtils.findAvailableTcpPort();
|
||||
|
||||
System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n",
|
||||
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port);
|
||||
TestGemFireServerConfiguration.SERVER_HOSTNAME, port);
|
||||
|
||||
System.setProperty("spring.session.data.gemfire.port", String.valueOf(port));
|
||||
|
||||
@@ -131,10 +134,10 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
processWorkingDirectory = createDirectory(processWorkingDirectoryPathname);
|
||||
|
||||
gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory,
|
||||
gemfireServer = run(TestGemFireServerConfiguration.class, processWorkingDirectory,
|
||||
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
|
||||
|
||||
assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))
|
||||
assertThat(waitForCacheServerToStart(TestGemFireServerConfiguration.SERVER_HOSTNAME, port))
|
||||
.isTrue();
|
||||
|
||||
System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0);
|
||||
@@ -164,7 +167,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
assertThat(GemFireUtils.isClient(gemfireCache)).isTrue();
|
||||
|
||||
Region<Object, Session> springSessionGemFireRegion =
|
||||
gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME);
|
||||
gemfireCache.getRegion(TEST_SESSION_REGION_NAME);
|
||||
|
||||
assertThat(springSessionGemFireRegion).isNotNull();
|
||||
|
||||
@@ -257,53 +260,25 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
assertThat(deletedSession).isNull();
|
||||
}
|
||||
|
||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
||||
@ClientCacheApplication(logLevel = "warning", pingInterval = 5000, readTimeout = 2500, retryAttempts = 1,
|
||||
subscriptionEnabled = true)
|
||||
@EnableGemFireHttpSession(regionName = TEST_SESSION_REGION_NAME, poolName = "DEFAULT",
|
||||
clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY,
|
||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
@SuppressWarnings("unused")
|
||||
static class SpringSessionDataGemFireClientConfiguration {
|
||||
static class TestGemFireClientConfiguration {
|
||||
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() {
|
||||
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientCacheFactoryBean gemfireCache() {
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean();
|
||||
|
||||
clientCacheFactory.setClose(true);
|
||||
clientCacheFactory.setProperties(gemfireProperties());
|
||||
|
||||
return clientCacheFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
PoolFactoryBean gemfirePool(
|
||||
ClientCacheConfigurer clientCacheDefaultPoolPortConfigurer(
|
||||
@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
|
||||
|
||||
PoolFactoryBean poolFactory = new PoolFactoryBean();
|
||||
|
||||
poolFactory.setKeepAlive(false);
|
||||
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
|
||||
poolFactory.setReadTimeout(2000); // 2 seconds
|
||||
poolFactory.setRetryAttempts(1);
|
||||
poolFactory.setSubscriptionEnabled(true);
|
||||
|
||||
poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint(
|
||||
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)));
|
||||
|
||||
return poolFactory;
|
||||
return (beanName, clientCacheFactoryBean) ->
|
||||
clientCacheFactoryBean.setServers(asArray(new ConnectionEndpoint("localhost", port)));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -316,7 +291,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
public static void main(String[] args) {
|
||||
|
||||
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(
|
||||
SpringSessionDataGemFireClientConfiguration.class);
|
||||
TestGemFireClientConfiguration.class);
|
||||
|
||||
applicationContext.registerShutdownHook();
|
||||
|
||||
@@ -329,10 +304,12 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
}
|
||||
}
|
||||
|
||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
||||
@CacheServerApplication(name = "ClientServerGemFireOperationsSessionRepositoryIntegrationTests",
|
||||
logLevel = "warning")
|
||||
@EnableGemFireHttpSession(regionName = TEST_SESSION_REGION_NAME,
|
||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
@SuppressWarnings("unused")
|
||||
static class SpringSessionDataGemFireServerConfiguration {
|
||||
static class TestGemFireServerConfiguration {
|
||||
|
||||
static final String SERVER_HOSTNAME = "localhost";
|
||||
|
||||
@@ -341,53 +318,20 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() {
|
||||
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", name());
|
||||
gemfireProperties.setProperty("mcast-port", "0");
|
||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
String name() {
|
||||
return ClientServerGemFireOperationsSessionRepositoryIntegrationTests.class.getName();
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheFactoryBean gemfireCache() {
|
||||
|
||||
CacheFactoryBean gemfireCache = new CacheFactoryBean();
|
||||
|
||||
gemfireCache.setClose(true);
|
||||
gemfireCache.setProperties(gemfireProperties());
|
||||
|
||||
return gemfireCache;
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheServerFactoryBean gemfireCacheServer(GemFireCache gemfireCache,
|
||||
CacheServerConfigurer cacheServerPortConfigurer(
|
||||
@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
|
||||
|
||||
CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean();
|
||||
|
||||
cacheServerFactory.setCache((Cache) gemfireCache);
|
||||
cacheServerFactory.setAutoStartup(true);
|
||||
cacheServerFactory.setBindAddress(SERVER_HOSTNAME);
|
||||
cacheServerFactory.setPort(port);
|
||||
|
||||
return cacheServerFactory;
|
||||
return (beanName, cacheServerFactoryBean) -> cacheServerFactoryBean.setPort(port);
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
AnnotationConfigApplicationContext context =
|
||||
new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class);
|
||||
AnnotationConfigApplicationContext applicationContext =
|
||||
new AnnotationConfigApplicationContext(TestGemFireServerConfiguration.class);
|
||||
|
||||
context.registerShutdownHook();
|
||||
applicationContext.registerShutdownHook();
|
||||
|
||||
writeProcessControlFile(WORKING_DIRECTORY);
|
||||
}
|
||||
|
||||
@@ -48,29 +48,33 @@ import org.springframework.session.Session;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Integration test to test the {@code findByPrincipalName} query method
|
||||
* on {@link GemFireOperationsSessionRepository}.
|
||||
* Integration test to test the {@code findByPrincipalName} query method on {@link GemFireOperationsSessionRepository}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.1.0
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.query.QueryService
|
||||
* @see org.apache.geode.pdx.PdxSerializable
|
||||
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
|
||||
* @see org.springframework.security.core.context.SecurityContext
|
||||
* @see org.springframework.session.Session
|
||||
* @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests
|
||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
|
||||
* @see org.springframework.test.annotation.DirtiesContext
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @see org.springframework.test.context.web.WebAppConfiguration
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.Region
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration
|
||||
@DirtiesContext
|
||||
@WebAppConfiguration
|
||||
@@ -328,8 +332,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
||||
|
||||
((AbstractGemFireOperationsSessionRepository.GemFireSession) expectedSession).setPrincipalName("jblum");
|
||||
|
||||
List<String> expectedAttributeNames = Arrays.asList("booleanAttribute", "numericAttribute", "stringAttribute",
|
||||
"personAttribute");
|
||||
List<String> expectedAttributeNames =
|
||||
Arrays.asList("booleanAttribute", "numericAttribute", "stringAttribute", "personAttribute");
|
||||
|
||||
Person jonDoe = new Person("Jon", "Doe");
|
||||
|
||||
@@ -406,13 +410,13 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
||||
pdxWriter.writeString("lastName", getLastName());
|
||||
}
|
||||
|
||||
public void fromData(final PdxReader pdxReader) {
|
||||
public void fromData(PdxReader pdxReader) {
|
||||
this.firstName = pdxReader.readString("firstName");
|
||||
this.lastName = pdxReader.readString("lastName");
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public int compareTo(final Person person) {
|
||||
public int compareTo(Person person) {
|
||||
|
||||
int compareValue = getLastName().compareTo(person.getLastName());
|
||||
|
||||
@@ -420,7 +424,7 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.session.data.gemfire;
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
@@ -32,6 +34,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.geode.DataSerializable;
|
||||
import org.apache.geode.DataSerializer;
|
||||
@@ -93,7 +96,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
public abstract class AbstractGemFireOperationsSessionRepository extends CacheListenerAdapter<Object, Session>
|
||||
implements ApplicationEventPublisherAware, FindByIndexNameSessionRepository<Session>, InitializingBean {
|
||||
|
||||
private boolean usingDataSerialization = false;
|
||||
private static final AtomicBoolean usingDataSerialization = new AtomicBoolean(false);
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() {
|
||||
|
||||
@@ -246,7 +249,7 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
* @param useDataSerialization boolean indicating whether the DataSerialization framework has been configured.
|
||||
*/
|
||||
public void setUseDataSerialization(boolean useDataSerialization) {
|
||||
this.usingDataSerialization = useDataSerialization;
|
||||
usingDataSerialization.set(useDataSerialization);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,8 +257,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
*
|
||||
* @return a boolean indicating whether the DataSerialization framework has been configured.
|
||||
*/
|
||||
protected boolean isUsingDataSerialization() {
|
||||
return this.usingDataSerialization;
|
||||
protected static boolean isUsingDataSerialization() {
|
||||
return usingDataSerialization.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,9 +295,6 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
this.fullyQualifiedRegionName = region.getFullPath();
|
||||
|
||||
region.getAttributesMutator().addCacheListener(this);
|
||||
|
||||
Instantiator.register(GemFireSessionInstantiator.create());
|
||||
Instantiator.register(GemFireSessionAttributesInstantiator.create());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -524,22 +524,57 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
return session;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class DeltaCapableGemFireSession extends GemFireSession<DeltaCapableGemFireSessionAttributes>
|
||||
implements Delta {
|
||||
|
||||
public DeltaCapableGemFireSession() { }
|
||||
|
||||
public DeltaCapableGemFireSession(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public DeltaCapableGemFireSession(Session session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DeltaCapableGemFireSessionAttributes newSessionAttributes(Object lock) {
|
||||
return new DeltaCapableGemFireSessionAttributes();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void toDelta(DataOutput out) throws IOException {
|
||||
|
||||
out.writeUTF(getId());
|
||||
out.writeLong(getLastAccessedTime().toEpochMilli());
|
||||
out.writeLong(getMaxInactiveInterval().getSeconds());
|
||||
getAttributes().toDelta(out);
|
||||
clearDelta();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void fromDelta(DataInput in) throws IOException {
|
||||
|
||||
setId(in.readUTF());
|
||||
setLastAccessedTime(Instant.ofEpochMilli(in.readLong()));
|
||||
setMaxInactiveInterval(Duration.ofSeconds(in.readLong()));
|
||||
getAttributes().fromDelta(in);
|
||||
clearDelta();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link GemFireSession} is a GemFire model for a Spring {@link Session} that stores and manages {@link Session}
|
||||
* state in GemFire. This class implements GemFire's {@link DataSerializable} interface to better handle
|
||||
* replication of {@link Session} state across the GemFire cluster.
|
||||
* {@link GemFireSession} is a Abstract Data Type (ADT) for a Spring {@link Session} that stores and manages
|
||||
* {@link Session} state in Apache Geode or Pivotal GemFire.
|
||||
*
|
||||
* @see java.lang.Comparable
|
||||
* @see org.apache.geode.DataSerializable
|
||||
* @see org.apache.geode.Delta
|
||||
* @see org.springframework.session.Session
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public static class GemFireSession implements Comparable<Session>, DataSerializable, Delta, Session {
|
||||
public static class GemFireSession<T extends GemFireSessionAttributes> implements Comparable<Session>, Session {
|
||||
|
||||
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
|
||||
|
||||
private static final Duration DEFAULT_MAX_INACTIVE_INTERVAL = Duration.ZERO;
|
||||
protected static final Duration DEFAULT_MAX_INACTIVE_INTERVAL = Duration.ZERO;
|
||||
|
||||
protected static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
@@ -547,8 +582,6 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
|
||||
private Duration maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL;
|
||||
|
||||
private transient final GemFireSessionAttributes sessionAttributes = new GemFireSessionAttributes(this);
|
||||
|
||||
private Instant creationTime;
|
||||
private Instant lastAccessedTime;
|
||||
|
||||
@@ -556,6 +589,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
|
||||
private String id;
|
||||
|
||||
private transient final T sessionAttributes = newSessionAttributes(this);
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected GemFireSession() {
|
||||
this(generateId());
|
||||
@@ -582,13 +617,19 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static GemFireSession copy(Session session) {
|
||||
return new GemFireSession(session);
|
||||
return (isUsingDataSerialization() ? new DeltaCapableGemFireSession(session) : new GemFireSession(session));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static GemFireSession create() {
|
||||
return create(DEFAULT_MAX_INACTIVE_INTERVAL);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static GemFireSession create(Duration maxInactiveInterval) {
|
||||
|
||||
GemFireSession session = new GemFireSession();
|
||||
GemFireSession session =
|
||||
(isUsingDataSerialization() ? new DeltaCapableGemFireSession() : new GemFireSession());
|
||||
|
||||
session.setMaxInactiveInterval(maxInactiveInterval);
|
||||
|
||||
@@ -596,8 +637,9 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static GemFireSession from(Session session) {
|
||||
return (session instanceof GemFireSession ? (GemFireSession) session : copy(session));
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends GemFireSession> T from(Session session) {
|
||||
return (T) (session instanceof GemFireSession ? (GemFireSession) session : copy(session));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,32 +654,53 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private static String validateId(String id) {
|
||||
|
||||
return Optional.ofNullable(id).filter(StringUtils::hasText)
|
||||
.orElseThrow(() -> new IllegalArgumentException("ID is required"));
|
||||
.orElseThrow(() -> newIllegalArgumentException("ID is required"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T newSessionAttributes(Object lock) {
|
||||
return (T) new GemFireSessionAttributes(lock);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected boolean allowJavaSerialization() {
|
||||
return DEFAULT_ALLOW_JAVA_SERIALIZATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String changeSessionId() {
|
||||
|
||||
this.id = generateId();
|
||||
triggerDelta();
|
||||
|
||||
return getId();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized String getId() {
|
||||
return this.id;
|
||||
public synchronized void clearDelta() {
|
||||
this.delta = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized Instant getCreationTime() {
|
||||
return this.creationTime;
|
||||
public synchronized boolean hasDelta() {
|
||||
return (this.delta || this.sessionAttributes.hasDelta());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unused")
|
||||
protected void triggerDelta() {
|
||||
triggerDelta(true);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected synchronized void triggerDelta(boolean condition) {
|
||||
this.delta |= condition;
|
||||
}
|
||||
|
||||
synchronized void setId(String id) {
|
||||
this.id = validateId(id);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -661,10 +724,15 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public GemFireSessionAttributes getAttributes() {
|
||||
public T getAttributes() {
|
||||
return this.sessionAttributes;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized Instant getCreationTime() {
|
||||
return this.creationTime;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized boolean isExpired() {
|
||||
|
||||
@@ -688,7 +756,7 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
this.delta |= !ObjectUtils.nullSafeEquals(this.lastAccessedTime, lastAccessedTime);
|
||||
triggerDelta(!ObjectUtils.nullSafeEquals(this.lastAccessedTime, lastAccessedTime));
|
||||
this.lastAccessedTime = lastAccessedTime;
|
||||
}
|
||||
|
||||
@@ -699,7 +767,7 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void setMaxInactiveInterval(Duration maxInactiveIntervalInSeconds) {
|
||||
this.delta |= !ObjectUtils.nullSafeEquals(this.maxInactiveInterval, maxInactiveIntervalInSeconds);
|
||||
triggerDelta(!ObjectUtils.nullSafeEquals(this.maxInactiveInterval, maxInactiveIntervalInSeconds));
|
||||
this.maxInactiveInterval = maxInactiveIntervalInSeconds;
|
||||
}
|
||||
|
||||
@@ -733,79 +801,6 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
return principalName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void toData(DataOutput out) throws IOException {
|
||||
|
||||
out.writeUTF(getId());
|
||||
out.writeLong(getCreationTime().toEpochMilli());
|
||||
out.writeLong(getLastAccessedTime().toEpochMilli());
|
||||
out.writeLong(getMaxInactiveInterval().getSeconds());
|
||||
|
||||
String principalName = getPrincipalName();
|
||||
|
||||
int length = (StringUtils.hasText(principalName) ? principalName.length() : 0);
|
||||
|
||||
out.writeInt(length);
|
||||
|
||||
if (length > 0) {
|
||||
out.writeUTF(principalName);
|
||||
}
|
||||
|
||||
writeObject(this.sessionAttributes, out);
|
||||
|
||||
this.delta = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
DataSerializer.writeObject(obj, out, allowJavaSerialization());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void fromData(DataInput in) throws ClassNotFoundException, IOException {
|
||||
|
||||
this.id = in.readUTF();
|
||||
this.creationTime = Instant.ofEpochMilli(in.readLong());
|
||||
setLastAccessedTime(Instant.ofEpochMilli(in.readLong()));
|
||||
setMaxInactiveInterval(Duration.ofSeconds(in.readLong()));
|
||||
|
||||
int principalNameLength = in.readInt();
|
||||
|
||||
if (principalNameLength > 0) {
|
||||
setPrincipalName(in.readUTF());
|
||||
}
|
||||
|
||||
this.sessionAttributes.from(this.<GemFireSessionAttributes>readObject(in));
|
||||
|
||||
this.delta = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
<T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
return DataSerializer.readObject(in);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized boolean hasDelta() {
|
||||
return (this.delta || this.sessionAttributes.hasDelta());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void toDelta(DataOutput out) throws IOException {
|
||||
out.writeLong(getLastAccessedTime().toEpochMilli());
|
||||
out.writeLong(getMaxInactiveInterval().getSeconds());
|
||||
getAttributes().toDelta(out);
|
||||
this.delta = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public synchronized void fromDelta(DataInput in) throws IOException {
|
||||
setLastAccessedTime(Instant.ofEpochMilli(in.readLong()));
|
||||
setMaxInactiveInterval(Duration.ofSeconds(in.readLong()));
|
||||
getAttributes().fromDelta(in);
|
||||
this.delta = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
public int compareTo(Session session) {
|
||||
@@ -851,24 +846,120 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GemFireSessionInstantiator is a GemFire {@link Instantiator} use to instantiate instances
|
||||
* of the {@link GemFireSession} object used in GemFire's data serialization framework when
|
||||
* persisting Session state in GemFire.
|
||||
*/
|
||||
public static class GemFireSessionInstantiator extends Instantiator {
|
||||
@SuppressWarnings("unused")
|
||||
public static class DeltaCapableGemFireSessionAttributes extends GemFireSessionAttributes implements Delta {
|
||||
|
||||
public static GemFireSessionInstantiator create() {
|
||||
return new GemFireSessionInstantiator(GemFireSession.class, 800813552);
|
||||
private transient final Map<String, Object> sessionAttributeDeltas = new HashMap<>();
|
||||
|
||||
public DeltaCapableGemFireSessionAttributes() {
|
||||
}
|
||||
|
||||
public GemFireSessionInstantiator(Class<? extends DataSerializable> type, int id) {
|
||||
super(type, id);
|
||||
public DeltaCapableGemFireSessionAttributes(Object lock) {
|
||||
super(lock);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public Object setAttribute(String attributeName, Object attributeValue) {
|
||||
|
||||
synchronized (getLock()) {
|
||||
|
||||
if (attributeValue != null) {
|
||||
|
||||
Object previousAttributeValue = super.setAttribute(attributeName, attributeValue);
|
||||
|
||||
if (!attributeValue.equals(previousAttributeValue)) {
|
||||
this.sessionAttributeDeltas.put(attributeName, attributeValue);
|
||||
}
|
||||
|
||||
return previousAttributeValue;
|
||||
}
|
||||
else {
|
||||
return removeAttribute(attributeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Override
|
||||
public DataSerializable newInstance() {
|
||||
return new GemFireSession();
|
||||
public Object removeAttribute(String attributeName) {
|
||||
|
||||
synchronized (getLock()) {
|
||||
|
||||
return Optional.ofNullable(super.removeAttribute(attributeName))
|
||||
.map(previousAttributeValue -> {
|
||||
this.sessionAttributeDeltas.put(attributeName, null);
|
||||
return previousAttributeValue;
|
||||
})
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void toDelta(DataOutput out) throws IOException {
|
||||
|
||||
synchronized (getLock()) {
|
||||
|
||||
out.writeInt(this.sessionAttributeDeltas.size());
|
||||
|
||||
for (Map.Entry<String, Object> entry : this.sessionAttributeDeltas.entrySet()) {
|
||||
out.writeUTF(entry.getKey());
|
||||
writeObject(entry.getValue(), out);
|
||||
}
|
||||
|
||||
clearDelta();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected void writeObject(Object value, DataOutput out) throws IOException {
|
||||
DataSerializer.writeObject(value, out);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Override
|
||||
public boolean hasDelta() {
|
||||
|
||||
synchronized (getLock()) {
|
||||
return !this.sessionAttributeDeltas.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void fromDelta(DataInput in) throws InvalidDeltaException, IOException {
|
||||
|
||||
synchronized (getLock()) {
|
||||
try {
|
||||
int count = in.readInt();
|
||||
|
||||
Map<String, Object> deltas = new HashMap<>(count);
|
||||
|
||||
while (count-- > 0) {
|
||||
deltas.put(in.readUTF(), readObject(in));
|
||||
}
|
||||
|
||||
deltas.forEach((key, value) -> {
|
||||
setAttribute(key, value);
|
||||
this.sessionAttributeDeltas.remove(key);
|
||||
});
|
||||
}
|
||||
catch (ClassNotFoundException cause) {
|
||||
throw new InvalidDeltaException("Class type in data not found", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected <T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
return DataSerializer.readObject(in);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Override
|
||||
public void clearDelta() {
|
||||
|
||||
synchronized (getLock()) {
|
||||
this.sessionAttributeDeltas.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -885,13 +976,9 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
* @see org.apache.geode.Delta
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public static class GemFireSessionAttributes extends AbstractMap<String, Object>
|
||||
implements DataSerializable, Delta {
|
||||
|
||||
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
|
||||
public static class GemFireSessionAttributes extends AbstractMap<String, Object> {
|
||||
|
||||
private transient final Map<String, Object> sessionAttributes = new HashMap<>();
|
||||
private transient final Map<String, Object> sessionAttributeDeltas = new HashMap<>();
|
||||
|
||||
private transient final Object lock;
|
||||
|
||||
@@ -916,52 +1003,40 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
protected Object getLock() {
|
||||
return this.lock;
|
||||
}
|
||||
|
||||
synchronized (this.lock) {
|
||||
if (attributeValue != null) {
|
||||
if (!attributeValue.equals(this.sessionAttributes.put(attributeName, attributeValue))) {
|
||||
this.sessionAttributeDeltas.put(attributeName, attributeValue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
removeAttribute(attributeName);
|
||||
}
|
||||
/* (non-Javadoc) */
|
||||
public Object setAttribute(String attributeName, Object attributeValue) {
|
||||
synchronized (getLock()) {
|
||||
return (attributeValue != null ? this.sessionAttributes.put(attributeName, attributeValue)
|
||||
: removeAttribute(attributeName));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void removeAttribute(String attributeName) {
|
||||
|
||||
synchronized (this.lock) {
|
||||
if (this.sessionAttributes.remove(attributeName) != null) {
|
||||
this.sessionAttributeDeltas.put(attributeName, null);
|
||||
}
|
||||
public Object removeAttribute(String attributeName) {
|
||||
synchronized (getLock()) {
|
||||
return this.sessionAttributes.remove(attributeName);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getAttribute(String attributeName) {
|
||||
|
||||
synchronized (this.lock) {
|
||||
synchronized (getLock()) {
|
||||
return (T) this.sessionAttributes.get(attributeName);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public Set<String> getAttributeNames() {
|
||||
|
||||
synchronized (this.lock) {
|
||||
synchronized (getLock()) {
|
||||
return Collections.unmodifiableSet(new HashSet<>(this.sessionAttributes.keySet()));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected boolean allowJavaSerialization() {
|
||||
return DEFAULT_ALLOW_JAVA_SERIALIZATION;
|
||||
}
|
||||
|
||||
/* (non-Javadoc); NOTE: entrySet implementation is not Thread-safe. */
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
@@ -982,109 +1057,39 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
};
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void clearDelta() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void from(Session session) {
|
||||
|
||||
synchronized (this.lock) {
|
||||
synchronized (getLock()) {
|
||||
session.getAttributeNames().forEach(attributeName ->
|
||||
setAttribute(attributeName, session.getAttribute(attributeName)));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void from(Map<String, Object> map) {
|
||||
|
||||
synchronized (getLock()) {
|
||||
map.forEach(this::setAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void from(GemFireSessionAttributes sessionAttributes) {
|
||||
|
||||
synchronized (this.lock) {
|
||||
synchronized (getLock()) {
|
||||
sessionAttributes.getAttributeNames().forEach(attributeName ->
|
||||
setAttribute(attributeName, sessionAttributes.getAttribute(attributeName)));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void toData(DataOutput out) throws IOException {
|
||||
|
||||
synchronized (this.lock) {
|
||||
|
||||
Set<String> attributeNames = getAttributeNames();
|
||||
|
||||
out.writeInt(attributeNames.size());
|
||||
|
||||
for (String attributeName : attributeNames) {
|
||||
out.writeUTF(attributeName);
|
||||
writeObject(getAttribute(attributeName), out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
DataSerializer.writeObject(obj, out, allowJavaSerialization());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void fromData(DataInput in) throws IOException, ClassNotFoundException {
|
||||
|
||||
synchronized (this.lock) {
|
||||
|
||||
for (int count = in.readInt(); count > 0; count--) {
|
||||
setAttribute(in.readUTF(), readObject(in));
|
||||
}
|
||||
|
||||
this.sessionAttributeDeltas.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
<T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
return DataSerializer.readObject(in);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean hasDelta() {
|
||||
|
||||
synchronized (this.lock) {
|
||||
return !this.sessionAttributeDeltas.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void toDelta(DataOutput out) throws IOException {
|
||||
|
||||
synchronized (this.lock) {
|
||||
|
||||
out.writeInt(this.sessionAttributeDeltas.size());
|
||||
|
||||
for (Map.Entry<String, Object> entry : this.sessionAttributeDeltas.entrySet()) {
|
||||
out.writeUTF(entry.getKey());
|
||||
writeObject(entry.getValue(), out);
|
||||
}
|
||||
|
||||
this.sessionAttributeDeltas.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void fromDelta(DataInput in) throws InvalidDeltaException, IOException {
|
||||
|
||||
synchronized (this.lock) {
|
||||
try {
|
||||
int count = in.readInt();
|
||||
|
||||
Map<String, Object> deltas = new HashMap<>(count);
|
||||
|
||||
while (count-- > 0) {
|
||||
deltas.put(in.readUTF(), readObject(in));
|
||||
}
|
||||
|
||||
deltas.forEach((key, value) -> {
|
||||
setAttribute(key, value);
|
||||
this.sessionAttributeDeltas.remove(key);
|
||||
});
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new InvalidDeltaException("class type in data not found", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1092,25 +1097,4 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
return this.sessionAttributes.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GemFireSessionAttributesInstantiator is a GemFire {@link Instantiator} use to instantiate instances
|
||||
* of the {@link GemFireSessionAttributes} object used in GemFire's data serialization framework when
|
||||
* persisting Session attributes state in GemFire.
|
||||
*/
|
||||
public static class GemFireSessionAttributesInstantiator extends Instantiator {
|
||||
|
||||
public static GemFireSessionAttributesInstantiator create() {
|
||||
return new GemFireSessionAttributesInstantiator(GemFireSessionAttributes.class, 800828008);
|
||||
}
|
||||
|
||||
public GemFireSessionAttributesInstantiator(Class<? extends DataSerializable> type, int id) {
|
||||
super(type, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSerializable newInstance() {
|
||||
return new GemFireSessionAttributes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newI
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.apache.geode.DataSerializer;
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.ExpirationAction;
|
||||
@@ -43,7 +45,6 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -408,6 +409,14 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
||||
.orElse(DEFAULT_SESSION_SERIALIZER_BEAN_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the configured serialization strategy is using Apache Geode / Pivotal GemFire's
|
||||
* DataSerialization framework.
|
||||
*
|
||||
* @return a boolean value indicating whether the configured serialization strategy is using Apache Geode
|
||||
* / Pivotal GemFire's DataSerialization framework.
|
||||
* @see #getSessionSerializerBeanName()
|
||||
*/
|
||||
protected boolean isUsingDataSerialization() {
|
||||
return SESSION_DATA_SERIALIZER_BEAN_NAME.equals(getSessionSerializerBeanName());
|
||||
}
|
||||
@@ -444,13 +453,20 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
||||
|
||||
setSessionSerializerBeanName(
|
||||
enableGemFireHttpSessionAttributes.getString("sessionSerializerBeanName"));
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
|
||||
System.err.printf("SETTING SYSTEM PROPERTY (%s) TO (%s) %n", SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME,
|
||||
getSessionSerializerBeanName());
|
||||
|
||||
System.setProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME, getSessionSerializerBeanName());
|
||||
|
||||
getBeanFactory().registerAlias(getSessionSerializerBeanName(), SESSION_SERIALIZER_REGISTERED_ALIAS);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn({ SESSION_DATA_SERIALIZER_BEAN_NAME, SESSION_PDX_SERIALIZER_BEAN_NAME })
|
||||
public ClientCacheConfigurer sessionClientCacheConfigurer(
|
||||
@Qualifier(SESSION_SERIALIZER_REGISTERED_ALIAS) SessionSerializer sessionSerializer) {
|
||||
|
||||
@@ -458,6 +474,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn({ SESSION_DATA_SERIALIZER_BEAN_NAME, SESSION_PDX_SERIALIZER_BEAN_NAME })
|
||||
public PeerCacheConfigurer sessionPeerCacheConfigurer(
|
||||
@Qualifier(SESSION_SERIALIZER_REGISTERED_ALIAS) SessionSerializer sessionSerializer) {
|
||||
|
||||
@@ -618,13 +635,13 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
||||
}
|
||||
|
||||
@Bean(SESSION_DATA_SERIALIZER_BEAN_NAME)
|
||||
@Conditional(DataSerializableSessionSerializerCondition.class)
|
||||
//@Conditional(DataSerializableSessionSerializerCondition.class)
|
||||
public Object sessionDataSerializer() {
|
||||
return new PdxSerializableSessionSerializer();
|
||||
}
|
||||
|
||||
@Bean(SESSION_PDX_SERIALIZER_BEAN_NAME)
|
||||
@Conditional(PdxSerializableSessionSerializerCondition.class)
|
||||
//@Conditional(PdxSerializableSessionSerializerCondition.class)
|
||||
public Object sessionPdxSerializer() {
|
||||
return new DataSerializableSessionSerializer();
|
||||
}
|
||||
@@ -683,6 +700,15 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
|
||||
System.err.printf("%1$s-System.getProperty(%2$s) = '%3$s'%n", getClass().getSimpleName(),
|
||||
SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME,
|
||||
System.getProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME));
|
||||
|
||||
System.err.printf("%1$s-Environment.get(%2$s) = '%3$s'%n", getClass().getSimpleName(),
|
||||
SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME,
|
||||
context.getEnvironment().getProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME));
|
||||
|
||||
return SESSION_DATA_SERIALIZER_BEAN_NAME
|
||||
.equals(context.getEnvironment().getProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME));
|
||||
}
|
||||
@@ -692,6 +718,15 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
|
||||
System.err.printf("%1$s-System.getProperty(%2$s) = '%3$s'%n", getClass().getSimpleName(),
|
||||
SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME,
|
||||
System.getProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME));
|
||||
|
||||
System.err.printf("%1$s-Environment.get(%2$s) = '%3$s'%n", getClass().getSimpleName(),
|
||||
SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME,
|
||||
context.getEnvironment().getProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME));
|
||||
|
||||
return SESSION_PDX_SERIALIZER_BEAN_NAME
|
||||
.equals(context.getEnvironment().getProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME));
|
||||
}
|
||||
|
||||
@@ -27,28 +27,6 @@ import java.util.Optional;
|
||||
*/
|
||||
public interface SessionSerializer<T, IN, OUT> {
|
||||
|
||||
/**
|
||||
* Determines whether the given {@link Object} can be de/serialized by this {@link SessionSerializer}.
|
||||
*
|
||||
* @param obj {@link Object} to evaluate for whether de/serialization is supported.
|
||||
* @return a boolean value indicating whether the specified {@link Object} can be de/serialized
|
||||
* by this {@link SessionSerializer}.
|
||||
* @see #canSerialize(Class)
|
||||
*/
|
||||
default boolean canSerialize(Object obj) {
|
||||
return Optional.ofNullable(obj).map(Object::getClass).map(this::canSerialize).orElse(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given {@link Class type} can be de/serialized by this {@link SessionSerializer}.
|
||||
*
|
||||
* @param type {@link Class} to evaluate for whether de/serialization is supported.
|
||||
* @return a boolean value indicating whether the specified {@link Class type} can be de/serialized
|
||||
* by this {@link SessionSerializer}.
|
||||
* @see #canSerialize(Object)
|
||||
*/
|
||||
boolean canSerialize(Class<?> type);
|
||||
|
||||
/**
|
||||
* Serializes the given {@link Object} to the provided {@code out} stream.
|
||||
*
|
||||
@@ -65,4 +43,26 @@ public interface SessionSerializer<T, IN, OUT> {
|
||||
*/
|
||||
T deserialize(IN in);
|
||||
|
||||
/**
|
||||
* Determines whether the given {@link Class type} can be de/serialized by this {@link SessionSerializer}.
|
||||
*
|
||||
* @param type {@link Class} to evaluate for whether de/serialization is supported.
|
||||
* @return a boolean value indicating whether the specified {@link Class type} can be de/serialized
|
||||
* by this {@link SessionSerializer}.
|
||||
* @see #canSerialize(Object)
|
||||
*/
|
||||
boolean canSerialize(Class<?> type);
|
||||
|
||||
/**
|
||||
* Determines whether the given {@link Object} can be de/serialized by this {@link SessionSerializer}.
|
||||
*
|
||||
* @param obj {@link Object} to evaluate for whether de/serialization is supported.
|
||||
* @return a boolean value indicating whether the specified {@link Object} can be de/serialized
|
||||
* by this {@link SessionSerializer}.
|
||||
* @see #canSerialize(Class)
|
||||
*/
|
||||
default boolean canSerialize(Object obj) {
|
||||
return Optional.ofNullable(obj).map(Object::getClass).map(this::canSerialize).orElse(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ import org.springframework.session.data.gemfire.serialization.SessionSerializer;
|
||||
public abstract class AbstractDataSerializableSessionSerializer<T> extends DataSerializer
|
||||
implements SessionSerializer<T, DataInput, DataOutput> {
|
||||
|
||||
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x0A11ACE5;
|
||||
@@ -52,6 +54,10 @@ public abstract class AbstractDataSerializableSessionSerializer<T> extends DataS
|
||||
return new Class[0];
|
||||
}
|
||||
|
||||
protected boolean allowJavaSerialization() {
|
||||
return DEFAULT_ALLOW_JAVA_SERIALIZATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean canSerialize(Class<?> type) {
|
||||
@@ -72,11 +78,23 @@ public abstract class AbstractDataSerializableSessionSerializer<T> extends DataS
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
public void serializeObject(Object obj, DataOutput out) throws IOException {
|
||||
serializeObject(obj, out, allowJavaSerialization());
|
||||
}
|
||||
|
||||
public void serializeObject(Object obj, DataOutput out, boolean allowJavaSerialization) throws IOException {
|
||||
writeObject(obj, out, allowJavaSerialization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fromData(DataInput in) throws IOException, ClassNotFoundException {
|
||||
return deserialize(in);
|
||||
}
|
||||
|
||||
public <T> T deserializeObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
return DataSerializer.readObject(in);
|
||||
}
|
||||
|
||||
protected <T> T safeRead(DataInput in, DataInputReader<T> reader) {
|
||||
try {
|
||||
return reader.doRead(in);
|
||||
|
||||
@@ -24,8 +24,6 @@ import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.geode.DataSerializer;
|
||||
|
||||
import org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer;
|
||||
|
||||
/**
|
||||
@@ -64,8 +62,10 @@ public class DataSerializableSessionAttributesSerializer
|
||||
|
||||
attributeNames.forEach(attributeName -> {
|
||||
safeWrite(out, output -> output.writeUTF(attributeName));
|
||||
safeWrite(out, output -> writeObject(sessionAttributes.getAttribute(attributeName), output));
|
||||
safeWrite(out, output -> serializeObject(sessionAttributes.getAttribute(attributeName), output));
|
||||
});
|
||||
|
||||
sessionAttributes.clearDelta();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,9 +75,11 @@ public class DataSerializableSessionAttributesSerializer
|
||||
GemFireSessionAttributes sessionAttributes = GemFireSessionAttributes.create();
|
||||
|
||||
for (int count = safeRead(in, DataInput::readInt); count > 0; count--) {
|
||||
sessionAttributes.setAttribute(safeRead(in, DataInput::readUTF), safeRead(in, DataSerializer::readObject));
|
||||
sessionAttributes.setAttribute(safeRead(in, DataInput::readUTF), safeRead(in, this::deserializeObject));
|
||||
}
|
||||
|
||||
sessionAttributes.clearDelta();
|
||||
|
||||
return sessionAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,6 @@ import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.geode.DataSerializer;
|
||||
|
||||
import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession;
|
||||
import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
|
||||
import org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer;
|
||||
@@ -78,7 +76,10 @@ public class DataSerializableSessionSerializer extends AbstractDataSerializableS
|
||||
safeWrite(out, output -> output.writeUTF(principalName));
|
||||
}
|
||||
|
||||
safeWrite(out, output -> writeObject(session.getAttributes(), out));
|
||||
safeWrite(out, output -> serializeObject(session.getAttributes(), out));
|
||||
|
||||
session.clearDelta();
|
||||
session.getAttributes().clearDelta();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +120,9 @@ public class DataSerializableSessionSerializer extends AbstractDataSerializableS
|
||||
session.setPrincipalName(safeRead(in, DataInput::readUTF));
|
||||
}
|
||||
|
||||
session.getAttributes().from(this.<GemFireSessionAttributes>safeRead(in, DataSerializer::readObject));
|
||||
session.getAttributes().from(this.<GemFireSessionAttributes>safeRead(in, this::deserializeObject));
|
||||
session.getAttributes().clearDelta();
|
||||
session.clearDelta();
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
package org.springframework.session.data.gemfire.serialization.pdx.provider;
|
||||
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -56,11 +57,16 @@ public class PdxSerializableSessionSerializer extends AbstractPdxSerializableSes
|
||||
writer.writeLong("lastAccessedTime", session.getLastAccessedTime().toEpochMilli());
|
||||
writer.writeLong("maxInactiveIntervalInSeconds", session.getMaxInactiveInterval().getSeconds());
|
||||
writer.writeString("principalName", session.getPrincipalName());
|
||||
writer.writeObject("attributes", session.getAttributes());
|
||||
writer.writeObject("attributes", newMap(session.getAttributes()));
|
||||
}
|
||||
}
|
||||
|
||||
protected <K, V> Map<K, V> newMap(Map<K, V> map) {
|
||||
return new HashMap<>(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public GemFireSession deserialize(PdxReader reader) {
|
||||
|
||||
GemFireSession session = GemFireSession.from(new AbstractSession() {
|
||||
@@ -92,7 +98,7 @@ public class PdxSerializableSessionSerializer extends AbstractPdxSerializableSes
|
||||
});
|
||||
|
||||
session.setPrincipalName(reader.readString("principalName"));
|
||||
session.getAttributes().from((GemFireSessionAttributes) reader.readObject("attributes"));
|
||||
session.getAttributes().from((Map<String, Object>) reader.readObject("attributes"));
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -57,7 +58,8 @@ public class ComposablePdxSerializer implements Iterable<PdxSerializer>, PdxSeri
|
||||
public static PdxSerializer compose(Iterable<PdxSerializer> pdxSerializers) {
|
||||
|
||||
List<PdxSerializer> pdxSerializerList =
|
||||
stream(nullSafeIterable(pdxSerializers).spliterator(), false).collect(Collectors.toList());
|
||||
stream(nullSafeIterable(pdxSerializers).spliterator(), false)
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
return (pdxSerializerList.isEmpty() ? null
|
||||
: (pdxSerializerList.size() == 1 ? pdxSerializerList.get(0)
|
||||
|
||||
@@ -23,80 +23,84 @@ import java.util.Set;
|
||||
import org.springframework.session.Session;
|
||||
|
||||
/**
|
||||
* The AbstractSession class...
|
||||
* The {@link AbstractSession} abstract class is a base implementation of the {@link Session} interface
|
||||
* to simplify the implementation of various {@link Session} types and their capabilities.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
* @see org.springframework.session.data.gemfire.support.AbstractSession
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class AbstractSession implements Session {
|
||||
|
||||
public static final String NOT_IMPLEMENTED = "Not Implemented";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getAttribute(String attributeName) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getAttributeOrDefault(String name, T defaultValue) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getRequiredAttribute(String name) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAttributeNames() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getCreationTime() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getLastAccessedTime() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxInactiveInterval(Duration interval) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getMaxInactiveInterval() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String changeSessionId() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String attributeName) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,14 @@ import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.asSet;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.DeltaCapableGemFireSession;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.DeltaCapableGemFireSessionAttributes;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
@@ -104,7 +105,7 @@ import org.apache.commons.logging.Log;
|
||||
* @see edu.umd.cs.mtc.TestFramework
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
public class AbstractGemFireOperationsSessionRepositoryTests {
|
||||
|
||||
protected static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600;
|
||||
|
||||
@@ -123,20 +124,11 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
@Override
|
||||
Log newLogger() {
|
||||
return AbstractGemFireOperationsSessionRepositoryTest.this.mockLog;
|
||||
return mockLog;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <E> Set<E> asSet(E... elements) {
|
||||
|
||||
Set<E> set = new HashSet<>(elements.length);
|
||||
|
||||
Collections.addAll(set, elements);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> EntryEvent<K, V> mockEntryEvent(Operation operation, K key, V oldValue, V newValue) {
|
||||
|
||||
@@ -151,11 +143,11 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> Region mockRegion(String name, DataPolicy dataPolicy) {
|
||||
protected <K, V> Region<K, V> mockRegion(String name, DataPolicy dataPolicy) {
|
||||
|
||||
Region<K, V> mockRegion = mock(Region.class, name);
|
||||
|
||||
RegionAttributes<K, V> mockRegionAttributes = mock(RegionAttributes.class);
|
||||
RegionAttributes<K, V> mockRegionAttributes = mockRegionAttributes(name);
|
||||
|
||||
given(mockRegion.getAttributes()).willReturn(mockRegionAttributes);
|
||||
given(mockRegionAttributes.getDataPolicy()).willReturn(dataPolicy);
|
||||
@@ -163,6 +155,11 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
return mockRegion;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> RegionAttributes<K, V> mockRegionAttributes(String name) {
|
||||
return mock(RegionAttributes.class, name);
|
||||
}
|
||||
|
||||
protected Session mockSession(String sessionId, long creationAndLastAccessedTime,
|
||||
long maxInactiveIntervalInSeconds) {
|
||||
|
||||
@@ -387,7 +384,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isEqualTo(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -430,7 +427,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -553,7 +550,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isEqualTo(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -593,7 +590,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -632,7 +629,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -674,7 +671,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isEqualTo(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -713,7 +710,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -752,7 +749,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -802,7 +799,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isEqualTo(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -874,7 +871,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isEqualTo(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -906,7 +903,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource()).isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSource()).isEqualTo(AbstractGemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId);
|
||||
|
||||
@@ -956,8 +953,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
Instant beforeOrAtCreationTime = Instant.now();
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession();
|
||||
GemFireSession session = new GemFireSession();
|
||||
|
||||
assertThat(session.getId()).isNotNull();
|
||||
assertThat(session.getCreationTime().compareTo(beforeOrAtCreationTime)).isGreaterThanOrEqualTo(0);
|
||||
@@ -972,8 +968,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
Instant beforeOrAtCreationTime = Instant.now();
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("1");
|
||||
GemFireSession session = new GemFireSession("1");
|
||||
|
||||
assertThat(session.getId()).isEqualTo("1");
|
||||
assertThat(session.getCreationTime().compareTo(beforeOrAtCreationTime)).isGreaterThanOrEqualTo(0);
|
||||
@@ -986,7 +981,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructGemFireSessionWithUnspecifiedId() {
|
||||
try {
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession(" ");
|
||||
new GemFireSession(" ");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertThat(expected).hasMessage("ID is required");
|
||||
@@ -1013,8 +1008,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
given(mockSession.getAttribute(eq("attrOne"))).willReturn("testOne");
|
||||
given(mockSession.getAttribute(eq("attrTwo"))).willReturn("testTwo");
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession gemfireSession =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession(mockSession);
|
||||
GemFireSession gemfireSession = new GemFireSession(mockSession);
|
||||
|
||||
assertThat(gemfireSession.getId()).isEqualTo("2");
|
||||
assertThat(gemfireSession.getCreationTime()).isEqualTo(expectedCreationTime);
|
||||
@@ -1036,7 +1030,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructGemFireSessionWithNullSession() {
|
||||
try {
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession((Session) null);
|
||||
new GemFireSession((Session) null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertThat(expected).hasMessage("The Session to copy cannot be null");
|
||||
@@ -1053,8 +1047,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
Duration maxInactiveInterval = Duration.ofSeconds(120L);
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(maxInactiveInterval);
|
||||
GemFireSession<?> session = GemFireSession.create(maxInactiveInterval);
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getId()).isNotNull();
|
||||
@@ -1062,7 +1055,23 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(session.getCreationTime());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(maxInactiveInterval);
|
||||
assertThat(session.getAttributeNames()).isNotNull();
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createNewGemFireSessionWithDefaultMaxInactiveInterval() {
|
||||
|
||||
Instant beforeOrAtCreationTime = Instant.now();
|
||||
|
||||
GemFireSession<?> session = GemFireSession.create();
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getId()).isNotNull();
|
||||
assertThat(session.getCreationTime().compareTo(beforeOrAtCreationTime)).isGreaterThanOrEqualTo(0);
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(session.getCreationTime());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(GemFireSession.DEFAULT_MAX_INACTIVE_INTERVAL);
|
||||
assertThat(session.getAttributeNames()).isNotNull();
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1078,8 +1087,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
given(mockSession.getAttributeNames()).willReturn(Collections.emptySet());
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession gemfireSession =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.from(mockSession);
|
||||
GemFireSession<?> gemfireSession = GemFireSession.from(mockSession);
|
||||
|
||||
assertThat(gemfireSession).isNotNull();
|
||||
assertThat(gemfireSession.getId()).isEqualTo("4");
|
||||
@@ -1100,11 +1108,9 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void fromExistingGemFireSessionIsGemFireSession() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession gemfireSession =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(Duration.ofSeconds(300));
|
||||
GemFireSession<?> gemfireSession = GemFireSession.create();
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession fromGemFireSession =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.from(gemfireSession);
|
||||
GemFireSession<?> fromGemFireSession = GemFireSession.from(gemfireSession);
|
||||
|
||||
assertThat(fromGemFireSession).isSameAs(gemfireSession);
|
||||
}
|
||||
@@ -1112,12 +1118,10 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void setGetAndRemoveAttribute() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(Duration.ofSeconds(60));
|
||||
GemFireSession<?> session = GemFireSession.create();
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(60));
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
|
||||
session.setAttribute("attrOne", "testOne");
|
||||
|
||||
@@ -1149,8 +1153,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
Duration expectedMaxInactiveIntervalInSeconds = Duration.ofSeconds(-1);
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(expectedMaxInactiveIntervalInSeconds);
|
||||
GemFireSession<?> session = GemFireSession.create(expectedMaxInactiveIntervalInSeconds);
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(expectedMaxInactiveIntervalInSeconds);
|
||||
@@ -1162,8 +1165,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
Duration expectedMaxInactiveIntervalInSeconds = Duration.ZERO;
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(expectedMaxInactiveIntervalInSeconds);
|
||||
GemFireSession<?> session = GemFireSession.create(expectedMaxInactiveIntervalInSeconds);
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(expectedMaxInactiveIntervalInSeconds);
|
||||
@@ -1175,12 +1177,11 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
long expectedMaxInactiveIntervalInSeconds = TimeUnit.HOURS.toSeconds(2);
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(
|
||||
Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
GemFireSession<?> session = GemFireSession.create(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
|
||||
Instant now = Instant.now();
|
||||
|
||||
@@ -1195,12 +1196,11 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
int expectedMaxInactiveIntervalInSeconds = 60;
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(
|
||||
Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
GemFireSession<?> session = GemFireSession.create(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
|
||||
Instant twoHoursAgo = Instant.ofEpochMilli(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2));
|
||||
|
||||
@@ -1213,8 +1213,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void setAndGetPrincipalName() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(Duration.ZERO);
|
||||
GemFireSession<?> session = GemFireSession.create(Duration.ZERO);
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getPrincipalName()).isNull();
|
||||
@@ -1236,141 +1235,6 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(session.getPrincipalName()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionToData() throws Exception {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("1") {
|
||||
|
||||
@Override
|
||||
void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
assertThat(obj).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes.class);
|
||||
assertThat(out).isNotNull();
|
||||
}
|
||||
};
|
||||
|
||||
session.setLastAccessedTime(Instant.ofEpochMilli(123L));
|
||||
session.setMaxInactiveInterval(Duration.ofSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS));
|
||||
session.setPrincipalName("jblum");
|
||||
|
||||
DataOutput mockDataOutput = mock(DataOutput.class);
|
||||
|
||||
session.toData(mockDataOutput);
|
||||
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("1"));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getCreationTime().toEpochMilli()));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getLastAccessedTime().toEpochMilli()));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getMaxInactiveInterval().getSeconds()));
|
||||
verify(mockDataOutput, times(1)).writeInt(eq("jblum".length()));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq(session.getPrincipalName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionFromData() throws Exception {
|
||||
|
||||
long expectedCreationTime = 1L;
|
||||
long expectedLastAccessedTime = 2L;
|
||||
long expectedMaxInactiveIntervalInSeconds = TimeUnit.HOURS.toSeconds(6);
|
||||
|
||||
String expectedPrincipalName = "jblum";
|
||||
String expectedSessionId = "2";
|
||||
|
||||
DataInput mockDataInput = mock(DataInput.class);
|
||||
|
||||
given(mockDataInput.readUTF()).willReturn(expectedSessionId).willReturn(expectedPrincipalName);
|
||||
given(mockDataInput.readLong()).willReturn(expectedCreationTime).willReturn(expectedLastAccessedTime)
|
||||
.willReturn(expectedMaxInactiveIntervalInSeconds);
|
||||
given(mockDataInput.readInt()).willReturn(expectedPrincipalName.length());
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("1") {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
|
||||
assertThat(in).isNotNull();
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes();
|
||||
|
||||
sessionAttributes.setAttribute("attrOne", "testOne");
|
||||
sessionAttributes.setAttribute("attrTwo", "testTwo");
|
||||
|
||||
return (T) sessionAttributes;
|
||||
}
|
||||
};
|
||||
|
||||
session.fromData(mockDataInput);
|
||||
|
||||
Set<String> expectedAttributeNames =
|
||||
asSet("attrOne", "attrTwo", FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
|
||||
assertThat(session.getId()).isEqualTo(expectedSessionId);
|
||||
assertThat(session.getCreationTime()).isEqualTo(Instant.ofEpochMilli(expectedCreationTime));
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(Instant.ofEpochMilli(expectedLastAccessedTime));
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
assertThat(session.getPrincipalName()).isEqualTo(expectedPrincipalName);
|
||||
assertThat(session.getAttributeNames()).hasSize(3);
|
||||
assertThat(session.getAttributeNames()).containsAll(expectedAttributeNames);
|
||||
assertThat(session.<String>getAttribute("attrOne")).isEqualTo("testOne");
|
||||
assertThat(session.<String>getAttribute("attrTwo")).isEqualTo("testTwo");
|
||||
assertThat(session.<String>getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME))
|
||||
.isEqualTo(expectedPrincipalName);
|
||||
|
||||
verify(mockDataInput, times(2)).readUTF();
|
||||
verify(mockDataInput, times(3)).readLong();
|
||||
verify(mockDataInput, times(1)).readInt();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionToDataThenFromDataWhenPrincipalNameIsNullGetsHandledProperly()
|
||||
throws ClassNotFoundException, IOException {
|
||||
|
||||
Instant beforeOrAtCreationTime = Instant.now();
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession expectedSession =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("123") {
|
||||
|
||||
@Override
|
||||
void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
assertThat(obj).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes.class);
|
||||
assertThat(out).isNotNull();
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(expectedSession.getId()).isEqualTo("123");
|
||||
assertThat(expectedSession.getCreationTime().compareTo(beforeOrAtCreationTime)).isGreaterThanOrEqualTo(0);
|
||||
assertThat(expectedSession.getLastAccessedTime().compareTo(beforeOrAtCreationTime)).isGreaterThanOrEqualTo(0);
|
||||
assertThat(expectedSession.getMaxInactiveInterval()).isEqualTo(Duration.ZERO);
|
||||
assertThat(expectedSession.getPrincipalName()).isNull();
|
||||
|
||||
ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
|
||||
|
||||
expectedSession.toData(new DataOutputStream(outBytes));
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession deserializedSession =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("0") {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
return (T) new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes();
|
||||
}
|
||||
};
|
||||
|
||||
deserializedSession.fromData(new DataInputStream(new ByteArrayInputStream(outBytes.toByteArray())));
|
||||
|
||||
assertThat(deserializedSession).isEqualTo(expectedSession);
|
||||
assertThat(deserializedSession.getCreationTime()).isEqualTo(expectedSession.getCreationTime());
|
||||
assertThat(deserializedSession.getLastAccessedTime()).isEqualTo(expectedSession.getLastAccessedTime());
|
||||
assertThat(deserializedSession.getMaxInactiveInterval()).isEqualTo(expectedSession.getMaxInactiveInterval());
|
||||
assertThat(deserializedSession.getPrincipalName()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasDeltaWhenNoSessionChangesIsFalse() {
|
||||
assertThat(new AbstractGemFireOperationsSessionRepository.GemFireSession().hasDelta()).isFalse();
|
||||
@@ -1379,8 +1243,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void hasDeltaWhenSessionAttributesChangeIsTrue() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession();
|
||||
GemFireSession session = new DeltaCapableGemFireSession();
|
||||
|
||||
assertThat(session.hasDelta()).isFalse();
|
||||
|
||||
@@ -1439,15 +1302,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
DataOutput mockDataOutput = mock(DataOutput.class);
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession() {
|
||||
|
||||
@Override
|
||||
void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
assertThat(String.valueOf(obj)).isEqualTo("test");
|
||||
assertThat(out).isSameAs(mockDataOutput);
|
||||
}
|
||||
};
|
||||
DeltaCapableGemFireSession session = new DeltaCapableGemFireSession();
|
||||
|
||||
session.setLastAccessedTime(Instant.ofEpochMilli(1L));
|
||||
session.setMaxInactiveInterval(Duration.ofSeconds(300L));
|
||||
@@ -1470,31 +1325,24 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
DataInput mockDataInput = mock(DataInput.class);
|
||||
|
||||
given(mockDataInput.readUTF()).willReturn("1");
|
||||
given(mockDataInput.readLong()).willReturn(1L).willReturn(600L);
|
||||
given(mockDataInput.readInt()).willReturn(0);
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession() {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
assertThat(in).isSameAs(mockDataInput);
|
||||
return (T) "test";
|
||||
}
|
||||
};
|
||||
DeltaCapableGemFireSession session = new DeltaCapableGemFireSession();
|
||||
|
||||
session.fromDelta(mockDataInput);
|
||||
|
||||
assertThat(session.hasDelta()).isFalse();
|
||||
assertThat(session.getId()).isEqualTo("1");
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(Instant.ofEpochMilli(1L));
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(600L));
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
|
||||
verify(mockDataInput, times(1)).readUTF();
|
||||
verify(mockDataInput, times(2)).readLong();
|
||||
verify(mockDataInput, times(1)).readInt();
|
||||
verify(mockDataInput, never()).readUTF();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1502,12 +1350,10 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
Instant twoHoursAgo = Instant.now().minusMillis(TimeUnit.HOURS.toMillis(2));
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession sessionOne =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession(
|
||||
mockSession("1", twoHoursAgo.toEpochMilli(), MAX_INACTIVE_INTERVAL_IN_SECONDS));
|
||||
GemFireSession<?> sessionOne =
|
||||
new GemFireSession<>(mockSession("1", twoHoursAgo.toEpochMilli(), MAX_INACTIVE_INTERVAL_IN_SECONDS));
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession sessionTwo =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("2");
|
||||
GemFireSession<?> sessionTwo = new GemFireSession<>("2");
|
||||
|
||||
assertThat(sessionOne.getCreationTime()).isEqualTo(twoHoursAgo);
|
||||
assertThat(sessionTwo.getCreationTime().isAfter(twoHoursAgo)).isTrue();
|
||||
@@ -1519,15 +1365,13 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void sessionEqualsDifferentSessionBasedOnId() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession sessionOne =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("1");
|
||||
GemFireSession sessionOne = new GemFireSession("1");
|
||||
|
||||
sessionOne.setLastAccessedTime(Instant.ofEpochSecond(12345L));
|
||||
sessionOne.setMaxInactiveInterval(Duration.ofSeconds(120L));
|
||||
sessionOne.setPrincipalName("jblum");
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession sessionTwo =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("1");
|
||||
GemFireSession sessionTwo = new GemFireSession("1");
|
||||
|
||||
sessionTwo.setLastAccessedTime(Instant.ofEpochSecond(67890L));
|
||||
sessionTwo.setMaxInactiveInterval(Duration.ofSeconds(300L));
|
||||
@@ -1543,8 +1387,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void sessionHashCodeIsNotEqualToStringIdHashCode() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("1");
|
||||
GemFireSession session = new GemFireSession("1");
|
||||
|
||||
assertThat(session.getId()).isEqualTo("1");
|
||||
assertThat(session.hashCode()).isNotEqualTo("1".hashCode());
|
||||
@@ -1559,8 +1402,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
given(mockSession.getAttribute(eq("attrOne"))).willReturn("testOne");
|
||||
given(mockSession.getAttribute(eq("attrTwo"))).willReturn("testTwo");
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes();
|
||||
GemFireSessionAttributes sessionAttributes = new GemFireSessionAttributes();
|
||||
|
||||
assertThat(sessionAttributes.getAttributeNames().isEmpty()).isTrue();
|
||||
|
||||
@@ -1585,8 +1427,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
source.setAttribute("attrOne", "testOne");
|
||||
source.setAttribute("attrTwo", "testTwo");
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes target =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes();
|
||||
GemFireSessionAttributes target = new GemFireSessionAttributes();
|
||||
|
||||
assertThat(target.getAttributeNames().isEmpty()).isTrue();
|
||||
|
||||
@@ -1598,69 +1439,6 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(target.<String>getAttribute("attrTwo")).isEqualTo("testTwo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionAttributesToData() throws Exception {
|
||||
|
||||
DataOutput mockDataOutput = mock(DataOutput.class);
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
assertThat(Arrays.asList("testOne", "testTwo").get(count++)).isEqualTo(String.valueOf(obj));
|
||||
assertThat(out).isSameAs(mockDataOutput);
|
||||
}
|
||||
};
|
||||
|
||||
sessionAttributes.setAttribute("attrOne", "testOne");
|
||||
sessionAttributes.setAttribute("attrTwo", "testTwo");
|
||||
|
||||
sessionAttributes.toData(mockDataOutput);
|
||||
|
||||
verify(mockDataOutput, times(1)).writeInt(eq(2));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("attrOne"));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("attrTwo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionAttributesFromData() throws Exception {
|
||||
|
||||
DataInput mockDataInput = mock(DataInput.class);
|
||||
|
||||
given(mockDataInput.readInt()).willReturn(2);
|
||||
given(mockDataInput.readUTF()).willReturn("attrOne").willReturn("attrTwo");
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
assertThat(in).isSameAs(mockDataInput);
|
||||
return (T) Arrays.asList("testOne", "testTwo").get(count++);
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(sessionAttributes.getAttributeNames().isEmpty()).isTrue();
|
||||
|
||||
sessionAttributes.fromData(mockDataInput);
|
||||
|
||||
assertThat(sessionAttributes.getAttributeNames().size()).isEqualTo(2);
|
||||
assertThat(sessionAttributes.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue();
|
||||
assertThat(sessionAttributes.<String>getAttribute("attrOne")).isEqualTo("testOne");
|
||||
assertThat(sessionAttributes.<String>getAttribute("attrTwo")).isEqualTo("testTwo");
|
||||
|
||||
verify(mockDataInput, times(1)).readInt();
|
||||
verify(mockDataInput, times(2)).readUTF();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionAttributesHasDeltaIsFalse() {
|
||||
assertThat(new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes().hasDelta()).isFalse();
|
||||
@@ -1669,8 +1447,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void sessionAttributesHasDeltaIsTrue() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes();
|
||||
GemFireSessionAttributes sessionAttributes = new DeltaCapableGemFireSessionAttributes();
|
||||
|
||||
assertThat(sessionAttributes.hasDelta()).isFalse();
|
||||
|
||||
@@ -1686,13 +1463,12 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
DataOutput mockDataOutput = mock(DataOutput.class);
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() {
|
||||
DeltaCapableGemFireSessionAttributes sessionAttributes = new DeltaCapableGemFireSessionAttributes() {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
protected void writeObject(Object obj, DataOutput out) throws IOException {
|
||||
assertThat(Arrays.asList("testOne", "testTwo", "testThree").get(count++)).isEqualTo(String.valueOf(obj));
|
||||
assertThat(out).isSameAs(mockDataOutput);
|
||||
}
|
||||
@@ -1741,14 +1517,13 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
given(mockDataInput.readUTF()).willReturn("attrOne").willReturn("attrTwo");
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() {
|
||||
DeltaCapableGemFireSessionAttributes sessionAttributes = new DeltaCapableGemFireSessionAttributes() {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
protected <T> T readObject(DataInput in) throws ClassNotFoundException, IOException {
|
||||
assertThat(in).isSameAs(mockDataInput);
|
||||
return (T) Arrays.asList("testOne", "testTwo", "testThree").get(count++);
|
||||
}
|
||||
@@ -1802,8 +1577,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Test
|
||||
public void sessionAttributesEntrySetIteratesAttributeNameValues() {
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes();
|
||||
GemFireSessionAttributes sessionAttributes = new GemFireSessionAttributes();
|
||||
|
||||
sessionAttributes.setAttribute("keyOne", "valueOne");
|
||||
sessionAttributes.setAttribute("keyTwo", "valueTwo");
|
||||
@@ -1813,8 +1587,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(sessionAttributeEntries).isNotNull();
|
||||
assertThat(sessionAttributeEntries.size()).isEqualTo(2);
|
||||
|
||||
Set<String> expectedNames = asSet("keyOne", "keyTwo");
|
||||
Set<?> expectedValues = asSet("valueOne", "valueTwo");
|
||||
Set<String> expectedNames = new HashSet<>(asSet("keyOne", "keyTwo"));
|
||||
Set<?> expectedValues = new HashSet<>(asSet("valueOne", "valueTwo"));
|
||||
|
||||
for (Map.Entry<String, Object> entry : sessionAttributeEntries) {
|
||||
expectedNames.remove(entry.getKey());
|
||||
@@ -1828,8 +1602,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
assertThat(sessionAttributeEntries.size()).isEqualTo(3);
|
||||
|
||||
expectedNames = asSet("keyOne", "keyTwo");
|
||||
expectedValues = asSet("valueOne", "valueTwo");
|
||||
expectedNames = new HashSet<>(asSet("keyOne", "keyTwo"));
|
||||
expectedValues = new HashSet<>(asSet("valueOne", "valueTwo"));
|
||||
|
||||
for (Map.Entry<String, Object> entry : sessionAttributeEntries) {
|
||||
expectedNames.remove(entry.getKey());
|
||||
@@ -1858,7 +1632,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@SuppressWarnings("unused")
|
||||
protected static final class ThreadSafeSessionTest extends MultithreadedTestCase {
|
||||
|
||||
private AbstractGemFireOperationsSessionRepository.GemFireSession session;
|
||||
private GemFireSession<?> session;
|
||||
|
||||
private final Instant beforeOrAtCreationTime = Instant.now();
|
||||
|
||||
@@ -1867,7 +1641,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Override
|
||||
public void initialize() {
|
||||
|
||||
this.session = new AbstractGemFireOperationsSessionRepository.GemFireSession("1");
|
||||
this.session = new GemFireSession<>("1");
|
||||
|
||||
assertThat(this.session).isNotNull();
|
||||
assertThat(this.session.getId()).isEqualTo("1");
|
||||
@@ -74,7 +74,7 @@ import org.springframework.session.events.SessionDeletedEvent;
|
||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GemFireOperationsSessionRepositoryTest {
|
||||
public class GemFireOperationsSessionRepositoryTests {
|
||||
|
||||
protected static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600;
|
||||
|
||||
@@ -271,7 +271,7 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
.isSameAs(GemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isSameAs(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
||||
|
||||
@@ -393,7 +393,7 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource()).isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSource()).isSameAs(GemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isSameAs(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
||||
|
||||
@@ -423,7 +423,7 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource()).isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSource()).isSameAs(GemFireOperationsSessionRepositoryTests.this.sessionRepository);
|
||||
assertThat(sessionEvent.<Session>getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -41,6 +42,8 @@ import org.apache.geode.cache.RegionShortcut;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.gemfire.GemfireOperations;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
@@ -50,26 +53,36 @@ import org.springframework.session.data.gemfire.GemFireOperationsSessionReposito
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean;
|
||||
|
||||
/**
|
||||
* The GemFireHttpSessionConfigurationTest class is a test suite of test cases testing the
|
||||
* contract and functionality of the {@link GemFireHttpSessionConfiguration} class.
|
||||
* Unit tests for {@link GemFireHttpSessionConfiguration} class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.1.0
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.data.gemfire.GemfireOperations
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.ExpirationAttributes
|
||||
* @see org.apache.geode.cache.RegionAttributes
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.core.type.AnnotationMetadata
|
||||
* @see org.springframework.data.gemfire.GemfireOperations
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.session.Session
|
||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
||||
*/
|
||||
public class GemFireHttpSessionConfigurationTest {
|
||||
public class GemFireHttpSessionConfigurationTests {
|
||||
|
||||
private GemFireHttpSessionConfiguration gemfireConfiguration;
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
System.clearProperty(GemFireHttpSessionConfiguration.SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T getField(Object obj, String fieldName) {
|
||||
try {
|
||||
@@ -197,7 +210,7 @@ public class GemFireHttpSessionConfigurationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetSpringSessionGemFireRegionName() {
|
||||
public void setAndGetSessionRegionName() {
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo(
|
||||
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME);
|
||||
@@ -222,6 +235,61 @@ public class GemFireHttpSessionConfigurationTest {
|
||||
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetSessionSerializerBeanName() {
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName())
|
||||
.isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_SESSION_SERIALIZER_BEAN_NAME);
|
||||
|
||||
this.gemfireConfiguration.setSessionSerializerBeanName(
|
||||
GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME);
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName())
|
||||
.isEqualTo(GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME);
|
||||
|
||||
this.gemfireConfiguration.setSessionSerializerBeanName(null);
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName())
|
||||
.isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_SESSION_SERIALIZER_BEAN_NAME);
|
||||
|
||||
this.gemfireConfiguration.setSessionSerializerBeanName(
|
||||
GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME);
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName())
|
||||
.isEqualTo(GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUsingDataSerializationIsFalse() {
|
||||
|
||||
this.gemfireConfiguration.setSessionSerializerBeanName("test");
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName()).isEqualTo("test");
|
||||
assertThat(this.gemfireConfiguration.isUsingDataSerialization()).isFalse();
|
||||
|
||||
this.gemfireConfiguration.setSessionSerializerBeanName(
|
||||
GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME);
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName())
|
||||
.isEqualTo(GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME);
|
||||
|
||||
assertThat(this.gemfireConfiguration.isUsingDataSerialization()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUsingDataSerializationIsTrue() {
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName())
|
||||
.isEqualTo(GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME);
|
||||
assertThat(this.gemfireConfiguration.isUsingDataSerialization()).isTrue();
|
||||
|
||||
this.gemfireConfiguration.setSessionSerializerBeanName(null);
|
||||
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName())
|
||||
.isEqualTo(GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME);
|
||||
assertThat(this.gemfireConfiguration.isUsingDataSerialization()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setsImportMetadata() {
|
||||
|
||||
@@ -235,6 +303,7 @@ public class GemFireHttpSessionConfigurationTest {
|
||||
annotationAttributes.put("poolName", "TestPool");
|
||||
annotationAttributes.put("serverRegionShortcut", RegionShortcut.REPLICATE);
|
||||
annotationAttributes.put("regionName", "TEST");
|
||||
annotationAttributes.put("sessionSerializerBeanName", "testSessionSerializer");
|
||||
|
||||
given(mockAnnotationMetadata.getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName())))
|
||||
.willReturn(annotationAttributes);
|
||||
@@ -247,8 +316,36 @@ public class GemFireHttpSessionConfigurationTest {
|
||||
assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo("TestPool");
|
||||
assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.REPLICATE);
|
||||
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo("TEST");
|
||||
assertThat(this.gemfireConfiguration.getSessionSerializerBeanName()).isEqualTo("testSessionSerializer");
|
||||
|
||||
verify(mockAnnotationMetadata, times(1)).getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName()));
|
||||
verify(mockAnnotationMetadata, times(1))
|
||||
.getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postConstructInitSetsSystemPropertyAndRegistersBeanAlias() {
|
||||
|
||||
ConfigurableListableBeanFactory mockBeanFactory = mock(ConfigurableListableBeanFactory.class);
|
||||
|
||||
ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class);
|
||||
|
||||
given(mockApplicationContext.getBeanFactory()).willReturn(mockBeanFactory);
|
||||
|
||||
assertThat(System.getProperty(GemFireHttpSessionConfiguration.SESSION_SERIALIZER_REGISTERED_ALIAS)).isNull();
|
||||
|
||||
this.gemfireConfiguration.setApplicationContext(mockApplicationContext);
|
||||
this.gemfireConfiguration.setSessionSerializerBeanName("testSessionSerializer");
|
||||
this.gemfireConfiguration.init();
|
||||
|
||||
assertThat(this.gemfireConfiguration.getApplicationContext()).isSameAs(mockApplicationContext);
|
||||
assertThat(System.getProperty(GemFireHttpSessionConfiguration.SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME))
|
||||
.isEqualTo("testSessionSerializer");
|
||||
|
||||
verify(mockApplicationContext, times(1)).getBeanFactory();
|
||||
|
||||
verify(mockBeanFactory, times(1)).registerAlias(eq("testSessionSerializer"),
|
||||
eq(GemFireHttpSessionConfiguration.SESSION_SERIALIZER_REGISTERED_ALIAS));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -39,7 +39,7 @@ import org.springframework.data.gemfire.client.Interest;
|
||||
import org.springframework.session.Session;
|
||||
|
||||
/**
|
||||
* The GemFireCacheTypeAwareRegionFactoryBeanTest class is a test suite of test cases
|
||||
* The GemFireCacheTypeAwareRegionFactoryBeanTests class is a test suite of test cases
|
||||
* testing the contract and functionality of the GemFireCacheTypeAwareRegionFactoryBean
|
||||
* class.
|
||||
*
|
||||
@@ -60,7 +60,7 @@ import org.springframework.session.Session;
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GemFireCacheTypeAwareRegionFactoryBeanTest {
|
||||
public class GemFireCacheTypeAwareRegionFactoryBeanTests {
|
||||
|
||||
@Mock
|
||||
Cache mockCache;
|
||||
@@ -89,13 +89,13 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest {
|
||||
@Override
|
||||
protected Region<Object, Session> newClientRegion(GemFireCache gemfireCache) throws Exception {
|
||||
assertThat(gemfireCache).isSameAs(expectedCache);
|
||||
return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockClientRegion;
|
||||
return GemFireCacheTypeAwareRegionFactoryBeanTests.this.mockClientRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region<Object, Session> newServerRegion(GemFireCache gemfireCache) throws Exception {
|
||||
assertThat(gemfireCache).isSameAs(expectedCache);
|
||||
return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockServerRegion;
|
||||
return GemFireCacheTypeAwareRegionFactoryBeanTests.this.mockServerRegion;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.session.data.gemfire.serialization.data.provider;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.asSet;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DataSerializableSessionAttributesSerializer}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mock
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.mockito.Spy
|
||||
* @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes
|
||||
* @see org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionAttributesSerializer
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DataSerializableSessionAttributesSerializerTests {
|
||||
|
||||
private DataSerializableSessionAttributesSerializer sessionAttributesSerializer =
|
||||
spy(new DataSerializableSessionAttributesSerializer());
|
||||
|
||||
@Test
|
||||
public void getIdReturnsSameValue() {
|
||||
|
||||
int id = this.sessionAttributesSerializer.getId();
|
||||
|
||||
assertThat(id).isNotEqualTo(0);
|
||||
assertThat(id).isEqualTo(this.sessionAttributesSerializer.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportedClassesContainsGemFireSessionAttributes() {
|
||||
assertThat(this.sessionAttributesSerializer.getSupportedClasses()).contains(GemFireSessionAttributes.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionAttributesToData() throws Exception {
|
||||
|
||||
DataOutput mockDataOutput = mock(DataOutput.class);
|
||||
|
||||
GemFireSessionAttributes sessionAttributes = GemFireSessionAttributes.create();
|
||||
|
||||
sessionAttributes.setAttribute("attrOne", "testOne");
|
||||
sessionAttributes.setAttribute("attrTwo", "testTwo");
|
||||
|
||||
doAnswer(invocation -> {
|
||||
|
||||
DataOutput dataOutput = invocation.getArgument(1);
|
||||
|
||||
dataOutput.writeUTF(invocation.getArgument(0));
|
||||
|
||||
return null;
|
||||
|
||||
}).when(sessionAttributesSerializer).serializeObject(any(), any(DataOutput.class));
|
||||
|
||||
sessionAttributesSerializer.serialize(sessionAttributes, mockDataOutput);
|
||||
|
||||
verify(mockDataOutput, times(1)).writeInt(eq(2));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("attrOne"));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("testOne"));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("attrTwo"));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("testTwo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionAttributesFromData() throws Exception {
|
||||
|
||||
AtomicInteger count = new AtomicInteger(0);
|
||||
|
||||
DataInput mockDataInput = mock(DataInput.class);
|
||||
|
||||
given(mockDataInput.readInt()).willReturn(2);
|
||||
given(mockDataInput.readUTF()).willReturn("attrOne").willReturn("attrTwo");
|
||||
|
||||
doAnswer(invocation -> Arrays.asList("testOne", "testTwo").get(count.getAndIncrement()))
|
||||
.when(sessionAttributesSerializer).deserializeObject(any(DataInput.class));
|
||||
|
||||
GemFireSessionAttributes sessionAttributes = sessionAttributesSerializer.deserialize(mockDataInput);
|
||||
|
||||
assertThat(sessionAttributes).isNotNull();
|
||||
assertThat(sessionAttributes.getAttributeNames()).hasSize(2);
|
||||
assertThat(sessionAttributes.getAttributeNames()).containsAll(asSet("attrOne", "attrTwo"));
|
||||
assertThat(sessionAttributes.<String>getAttribute("attrOne")).isEqualTo("testOne");
|
||||
assertThat(sessionAttributes.<String>getAttribute("attrTwo")).isEqualTo("testTwo");
|
||||
|
||||
verify(mockDataInput, times(1)).readInt();
|
||||
verify(mockDataInput, times(2)).readUTF();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.session.data.gemfire.serialization.data.provider;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.asSet;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession;
|
||||
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DataSerializableSessionSerializer}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mock
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.mockito.Spy
|
||||
* @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession
|
||||
* @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes
|
||||
* @see org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionSerializer
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DataSerializableSessionSerializerTests {
|
||||
|
||||
private DataSerializableSessionSerializer sessionSerializer = spy(new DataSerializableSessionSerializer());
|
||||
|
||||
@Test
|
||||
public void getIdReturnsSameValue() {
|
||||
|
||||
int id = this.sessionSerializer.getId();
|
||||
|
||||
assertThat(id).isNotEqualTo(0);
|
||||
assertThat(id).isEqualTo((this.sessionSerializer.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportedClassContainsGemFireSession() {
|
||||
assertThat(this.sessionSerializer.getSupportedClasses()).contains(GemFireSession.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionToData() throws Exception {
|
||||
|
||||
GemFireSession<?> session = GemFireSession.create();
|
||||
|
||||
session.setLastAccessedTime(Instant.ofEpochMilli(123L));
|
||||
session.setMaxInactiveInterval(Duration.ofSeconds(60L));
|
||||
session.setPrincipalName("jblum");
|
||||
|
||||
DataOutput mockDataOutput = mock(DataOutput.class);
|
||||
|
||||
doAnswer(invocation -> {
|
||||
assertThat(invocation.<GemFireSessionAttributes>getArgument(0)).isEqualTo(session.getAttributes());
|
||||
assertThat(invocation.<DataOutput>getArgument(1)).isEqualTo(mockDataOutput);
|
||||
return null;
|
||||
}).when(this.sessionSerializer).serializeObject(any(), any(DataOutput.class));
|
||||
|
||||
assertThat(session.hasDelta()).isTrue();
|
||||
|
||||
this.sessionSerializer.serialize(session, mockDataOutput);
|
||||
|
||||
assertThat(session.hasDelta()).isFalse();
|
||||
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq(session.getId()));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getCreationTime().toEpochMilli()));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getLastAccessedTime().toEpochMilli()));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getMaxInactiveInterval().getSeconds()));
|
||||
verify(mockDataOutput, times(1)).writeInt(eq("jblum".length()));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq(session.getPrincipalName()));
|
||||
verify(this.sessionSerializer, times(1))
|
||||
.serializeObject(eq(session.getAttributes()), eq(mockDataOutput));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionFromData() throws Exception {
|
||||
|
||||
long expectedCreationTime = 1L;
|
||||
long expectedLastAccessedTime = 2L;
|
||||
long expectedMaxInactiveIntervalInSeconds = TimeUnit.HOURS.toSeconds(2);
|
||||
|
||||
String expectedPrincipalName = "jblum";
|
||||
String expectedSessionId = "2";
|
||||
|
||||
DataInput mockDataInput = mock(DataInput.class);
|
||||
|
||||
given(mockDataInput.readUTF()).willReturn(expectedSessionId).willReturn(expectedPrincipalName);
|
||||
given(mockDataInput.readLong()).willReturn(expectedCreationTime).willReturn(expectedLastAccessedTime)
|
||||
.willReturn(expectedMaxInactiveIntervalInSeconds);
|
||||
given(mockDataInput.readInt()).willReturn(expectedPrincipalName.length());
|
||||
|
||||
doAnswer(invocation -> {
|
||||
|
||||
GemFireSessionAttributes sessionAttributes = GemFireSessionAttributes.create();
|
||||
|
||||
sessionAttributes.setAttribute("attrOne", "testOne");
|
||||
sessionAttributes.setAttribute("attrTwo", "testTwo");
|
||||
|
||||
return sessionAttributes;
|
||||
|
||||
}).when(this.sessionSerializer).deserializeObject(any(DataInput.class));
|
||||
|
||||
GemFireSession<?> session = this.sessionSerializer.deserialize(mockDataInput);
|
||||
|
||||
Set<String> expectedAttributeNames =
|
||||
asSet("attrOne", "attrTwo", FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
|
||||
assertThat(session.getId()).isEqualTo(expectedSessionId);
|
||||
assertThat(session.getCreationTime()).isEqualTo(Instant.ofEpochMilli(expectedCreationTime));
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(Instant.ofEpochMilli(expectedLastAccessedTime));
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(expectedMaxInactiveIntervalInSeconds));
|
||||
assertThat(session.getPrincipalName()).isEqualTo(expectedPrincipalName);
|
||||
assertThat(session.hasDelta()).isFalse();
|
||||
assertThat(session.getAttributeNames()).hasSize(3);
|
||||
assertThat(session.getAttributeNames()).containsAll(expectedAttributeNames);
|
||||
assertThat(session.<String>getAttribute("attrOne")).isEqualTo("testOne");
|
||||
assertThat(session.<String>getAttribute("attrTwo")).isEqualTo("testTwo");
|
||||
assertThat(session.<String>getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME))
|
||||
.isEqualTo(expectedPrincipalName);
|
||||
|
||||
verify(mockDataInput, times(2)).readUTF();
|
||||
verify(mockDataInput, times(3)).readLong();
|
||||
verify(mockDataInput, times(1)).readInt();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionToDataThenFromDataWhenPrincipalNameIsNullGetsHandledProperly()
|
||||
throws ClassNotFoundException, IOException {
|
||||
|
||||
Instant beforeOrAtCreationTime = Instant.now();
|
||||
|
||||
GemFireSession<?> expectedSession = GemFireSession.create();
|
||||
|
||||
assertThat(expectedSession.getId()).isNotNull();
|
||||
assertThat(expectedSession.getCreationTime().compareTo(beforeOrAtCreationTime)).isGreaterThanOrEqualTo(0);
|
||||
assertThat(expectedSession.getLastAccessedTime().compareTo(beforeOrAtCreationTime)).isGreaterThanOrEqualTo(0);
|
||||
assertThat(expectedSession.getMaxInactiveInterval()).isEqualTo(Duration.ZERO);
|
||||
assertThat(expectedSession.getPrincipalName()).isNull();
|
||||
|
||||
ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
|
||||
|
||||
doAnswer(invocation -> null).when(this.sessionSerializer).serializeObject(any(), any(DataOutput.class));
|
||||
|
||||
doAnswer(invocation -> GemFireSessionAttributes.create())
|
||||
.when(this.sessionSerializer).deserializeObject(any(DataInput.class));
|
||||
|
||||
this.sessionSerializer.serialize(expectedSession, new DataOutputStream(outBytes));
|
||||
|
||||
GemFireSession<?> deserializedSession =
|
||||
this.sessionSerializer.deserialize(new DataInputStream(new ByteArrayInputStream(outBytes.toByteArray())));
|
||||
|
||||
assertThat(deserializedSession).isEqualTo(expectedSession);
|
||||
assertThat(deserializedSession.getCreationTime()).isEqualTo(expectedSession.getCreationTime());
|
||||
assertThat(deserializedSession.getLastAccessedTime()).isEqualTo(expectedSession.getLastAccessedTime());
|
||||
assertThat(deserializedSession.getMaxInactiveInterval()).isEqualTo(expectedSession.getMaxInactiveInterval());
|
||||
assertThat(deserializedSession.getPrincipalName()).isNull();
|
||||
|
||||
verify(this.sessionSerializer, times(1))
|
||||
.serializeObject(eq(expectedSession.getAttributes()), isA(DataOutput.class));
|
||||
|
||||
verify(this.sessionSerializer, times(1)).deserializeObject(isA(DataInput.class));
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.session.data.gemfire.support.GemFireUtils
|
||||
*/
|
||||
public class GemFireUtilsTest {
|
||||
public class GemFireUtilsTests {
|
||||
|
||||
@Test
|
||||
public void closeNonNullCloseableSuccessfullyReturnsTrue() throws IOException {
|
||||
Reference in New Issue
Block a user