Improve Hazelcast integration tests

Resolves: #1534
This commit is contained in:
Vedran Pavic
2019-10-08 09:37:06 +02:00
parent 927008bdc8
commit 2d06e1159c
11 changed files with 28 additions and 332 deletions

View File

@@ -35,16 +35,13 @@ public class HazelcastHttpSessionConfig {
@Bean
public HazelcastInstance hazelcastInstance() {
Config config = new Config();
MapAttributeConfig attributeConfig = new MapAttributeConfig()
.setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
.setExtractor(PrincipalNameExtractor.class.getName());
Config config = new Config();
config.getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME) // <2>
.addMapAttributeConfig(attributeConfig).addMapIndexConfig(
new MapIndexConfig(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));
return Hazelcast.newHazelcastInstance(config); // <3>
}

View File

@@ -23,49 +23,32 @@ import com.hazelcast.config.NetworkConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.springframework.util.SocketUtils;
/**
* Utility class for Hazelcast integration tests.
*
* @author Vedran Pavic
*/
public final class HazelcastITestUtils {
final class HazelcastITestUtils {
private HazelcastITestUtils() {
}
/**
* Creates {@link HazelcastInstance} for use in integration tests.
* @param port the port for Hazelcast to bind to
* @return the Hazelcast instance
*/
public static HazelcastInstance embeddedHazelcastServer(int port) {
static HazelcastInstance embeddedHazelcastServer() {
Config config = new Config();
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(0);
networkConfig.getJoin().getMulticastConfig().setEnabled(false);
MapAttributeConfig attributeConfig = new MapAttributeConfig()
.setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
.setExtractor(PrincipalNameExtractor.class.getName());
Config config = new Config();
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(port);
networkConfig.getJoin().getMulticastConfig().setEnabled(false);
config.getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME)
.addMapAttributeConfig(attributeConfig).addMapIndexConfig(
new MapIndexConfig(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));
return Hazelcast.newHazelcastInstance(config);
}
/**
* Creates {@link HazelcastInstance} for use in integration tests.
* @return the Hazelcast instance
*/
public static HazelcastInstance embeddedHazelcastServer() {
return embeddedHazelcastServer(SocketUtils.findAvailableTcpPort());
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.hazelcast.config.annotation.web.http;
package org.springframework.session.hazelcast;
import java.time.Duration;
import java.time.Instant;
@@ -38,8 +38,7 @@ import org.springframework.session.SessionRepository;
import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.session.hazelcast.HazelcastITestUtils;
import org.springframework.session.hazelcast.SessionEventRegistry;
import org.springframework.session.hazelcast.config.annotation.web.http.EnableHazelcastHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
@@ -57,7 +56,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@ContextConfiguration
@WebAppConfiguration
class EnableHazelcastHttpSessionEventsTests<S extends Session> {
class SessionEventHazelcastIndexedSessionRepositoryTests<S extends Session> {
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;

View File

@@ -24,7 +24,7 @@ import java.util.concurrent.ConcurrentMap;
import org.springframework.context.ApplicationListener;
import org.springframework.session.events.AbstractSessionEvent;
public class SessionEventRegistry implements ApplicationListener<AbstractSessionEvent> {
class SessionEventRegistry implements ApplicationListener<AbstractSessionEvent> {
private Map<String, AbstractSessionEvent> events = new HashMap<>();
@@ -40,17 +40,17 @@ public class SessionEventRegistry implements ApplicationListener<AbstractSession
}
}
public void clear() {
void clear() {
this.events.clear();
this.locks.clear();
}
public boolean receivedEvent(String sessionId) throws InterruptedException {
boolean receivedEvent(String sessionId) throws InterruptedException {
return waitForEvent(sessionId) != null;
}
@SuppressWarnings("unchecked")
public <E extends AbstractSessionEvent> E getEvent(String sessionId) throws InterruptedException {
<E extends AbstractSessionEvent> E getEvent(String sessionId) throws InterruptedException {
return (E) waitForEvent(sessionId);
}

View File

@@ -1,127 +0,0 @@
/*
* Copyright 2014-2019 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
*
* https://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.hazelcast.config.annotation.web.http;
import java.time.Duration;
import com.hazelcast.config.ClasspathXmlConfig;
import com.hazelcast.config.Config;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test the different configuration options for the {@link EnableHazelcastHttpSession}
* annotation.
*
* @author Tommy Ludwig
*/
public class HazelcastHttpSessionConfigurationXmlTests<S extends Session> {
@ExtendWith(SpringExtension.class)
@ContextConfiguration
@WebAppConfiguration
static class CustomXmlMapNameTest<S extends Session> {
@Autowired
private SessionRepository<S> repository;
@Test
void saveSessionTest() {
S sessionToSave = this.repository.createSession();
this.repository.save(sessionToSave);
S session = this.repository.findById(sessionToSave.getId());
assertThat(session.getId()).isEqualTo(sessionToSave.getId());
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofMinutes(30));
}
@Configuration
@EnableHazelcastHttpSession(sessionMapName = "my-sessions")
static class HazelcastSessionXmlConfigCustomMapName {
@Bean
HazelcastInstance embeddedHazelcast() {
Config hazelcastConfig = new ClasspathXmlConfig(
"org/springframework/session/hazelcast/config/annotation/web/http/hazelcast-custom-map-name.xml");
NetworkConfig netConfig = new NetworkConfig();
netConfig.setPort(SocketUtils.findAvailableTcpPort());
hazelcastConfig.setNetworkConfig(netConfig);
return Hazelcast.newHazelcastInstance(hazelcastConfig);
}
}
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration
@WebAppConfiguration
static class CustomXmlMapNameAndIdleTest<S extends Session> {
@Autowired
private SessionRepository<S> repository;
@Test
void saveSessionTest() {
S sessionToSave = this.repository.createSession();
this.repository.save(sessionToSave);
S session = this.repository.findById(sessionToSave.getId());
assertThat(session.getId()).isEqualTo(sessionToSave.getId());
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofMinutes(20));
}
@Configuration
@EnableHazelcastHttpSession(sessionMapName = "test-sessions", maxInactiveIntervalInSeconds = 1200)
static class HazelcastSessionXmlConfigCustomMapNameAndIdle {
@Bean
HazelcastInstance embeddedHazelcast() {
Config hazelcastConfig = new ClasspathXmlConfig(
"org/springframework/session/hazelcast/config/annotation/web/http/hazelcast-custom-idle-time-map-name.xml");
NetworkConfig netConfig = new NetworkConfig();
netConfig.setPort(SocketUtils.findAvailableTcpPort());
hazelcastConfig.setNetworkConfig(netConfig);
return Hazelcast.newHazelcastInstance(hazelcastConfig);
}
}
}
}

View File

@@ -3,6 +3,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config https://www.hazelcast.com/schema/config/hazelcast-config-3.12.xsd">
<network>
<join>
<multicast enabled="false"/>
</join>
</network>
<user-code-deployment enabled="true">
<class-cache-mode>ETERNAL</class-cache-mode>
<provider-mode>LOCAL_AND_CACHED_CLASSES</provider-mode>

View File

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config https://www.hazelcast.com/schema/config/hazelcast-config-3.12.xsd">
<group>
<name>spring-session-it-test-idle-time-map-name</name>
<password>test-pass</password>
</group>
<network>
<port auto-increment="true" port-count="100">5701</port>
<outbound-ports>
<ports>0</ports>
</outbound-ports>
<join>
<multicast enabled="false"/>
</join>
</network>
<map name="test-sessions">
<in-memory-format>BINARY</in-memory-format>
<backup-count>1</backup-count>
<async-backup-count>0</async-backup-count>
<time-to-live-seconds>0</time-to-live-seconds>
<max-idle-seconds>300</max-idle-seconds>
<merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
<attributes>
<attribute extractor="org.springframework.session.hazelcast.PrincipalNameExtractor">principalName</attribute>
</attributes>
<indexes>
<index ordered="false">principalName</index>
</indexes>
</map>
</hazelcast>

View File

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config https://www.hazelcast.com/schema/config/hazelcast-config-3.12.xsd">
<group>
<name>spring-session-it-test-map-name</name>
<password>test-pass</password>
</group>
<network>
<port auto-increment="true" port-count="100">5701</port>
<outbound-ports>
<ports>0</ports>
</outbound-ports>
<join>
<multicast enabled="false"/>
</join>
</network>
<map name="my-sessions">
<in-memory-format>BINARY</in-memory-format>
<backup-count>1</backup-count>
<async-backup-count>0</async-backup-count>
<time-to-live-seconds>0</time-to-live-seconds>
<max-idle-seconds>0</max-idle-seconds>
<merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
<attributes>
<attribute extractor="org.springframework.session.hazelcast.PrincipalNameExtractor">principalName</attribute>
</attributes>
<indexes>
<index ordered="false">principalName</index>
</indexes>
</map>
</hazelcast>

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2014-2019 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
*
* https://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 sample;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.StreamSerializer;
/**
* A {@link StreamSerializer} that uses Java serialization to persist the session. This is
* certainly not the most efficient way to persist sessions, but the example is intended
* to demonstrate using minimal dependencies. For better serialization methods try using
* <a href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
*
* @author Rob Winch
*
*/
public class ObjectStreamSerializer implements StreamSerializer<Object> {
@Override
public int getTypeId() {
return 2;
}
@Override
public void write(ObjectDataOutput objectDataOutput, Object object) throws IOException {
ObjectOutputStream out = new ObjectOutputStream((OutputStream) objectDataOutput);
out.writeObject(object);
out.flush();
}
@Override
public Object read(ObjectDataInput objectDataInput) throws IOException {
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
try {
return in.readObject();
}
catch (ClassNotFoundException ex) {
throw new IOException(ex);
}
}
@Override
public void destroy() {
}
}

View File

@@ -19,7 +19,7 @@ package sample;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapAttributeConfig;
import com.hazelcast.config.MapIndexConfig;
import com.hazelcast.config.SerializerConfig;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
@@ -28,7 +28,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository;
import org.springframework.session.hazelcast.PrincipalNameExtractor;
import org.springframework.session.hazelcast.config.annotation.web.http.EnableHazelcastHttpSession;
import org.springframework.util.SocketUtils;
// tag::class[]
@EnableHazelcastHttpSession(maxInactiveIntervalInSeconds = 300)
@@ -38,26 +37,15 @@ public class SessionConfig {
@Bean(destroyMethod = "shutdown")
public HazelcastInstance hazelcastInstance() {
Config config = new Config();
int port = SocketUtils.findAvailableTcpPort();
config.getNetworkConfig().setPort(port).getJoin().getMulticastConfig().setEnabled(false);
System.out.println("Hazelcast port #: " + port);
SerializerConfig serializer = new SerializerConfig().setImplementation(new ObjectStreamSerializer())
.setTypeClass(Object.class);
config.getSerializationConfig().addSerializerConfig(serializer);
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(0);
networkConfig.getJoin().getMulticastConfig().setEnabled(false);
MapAttributeConfig attributeConfig = new MapAttributeConfig()
.setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
.setExtractor(PrincipalNameExtractor.class.getName());
config.getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME)
.addMapAttributeConfig(attributeConfig).addMapIndexConfig(
new MapIndexConfig(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));
return Hazelcast.newHazelcastInstance(config);
}

View File

@@ -16,8 +16,6 @@
package sample;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.EnumSet;
import java.util.Map;
@@ -28,6 +26,7 @@ import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import com.hazelcast.config.Config;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
@@ -62,21 +61,11 @@ public class Initializer implements ServletContextListener {
private HazelcastInstance createHazelcastInstance() {
Config config = new Config();
config.getNetworkConfig().setPort(getAvailablePort()).getJoin().getMulticastConfig().setEnabled(false);
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(0);
networkConfig.getJoin().getMulticastConfig().setEnabled(false);
config.getMapConfig(SESSION_MAP_NAME).setTimeToLiveSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
return Hazelcast.newHazelcastInstance(config);
}
private static int getAvailablePort() {
try (ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}