Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ba76d0375 | ||
|
|
eb29949996 | ||
|
|
02a990d00e | ||
|
|
56809eacb2 | ||
|
|
4ff8f73b84 | ||
|
|
0ad389633e | ||
|
|
5a9046e391 | ||
|
|
690f734307 | ||
|
|
823e323f68 | ||
|
|
444b5ad85a | ||
|
|
b4a8c7e516 |
@@ -3,9 +3,10 @@ name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- 2.4.x
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # Once per day at 10am UTC
|
||||
workflow_dispatch: # Manual trigger
|
||||
|
||||
env:
|
||||
GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
|
||||
|
||||
12
build.gradle
12
build.gradle
@@ -4,21 +4,13 @@ buildscript {
|
||||
snapshotBuild = version.endsWith('SNAPSHOT')
|
||||
milestoneBuild = !(releaseBuild || snapshotBuild)
|
||||
|
||||
springBootVersion = '2.4.2'
|
||||
springBootVersion = '2.4.0-M4'
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven { url 'https://repo.spring.io/plugins-release/' }
|
||||
maven {
|
||||
url = 'https://repo.spring.io/plugins-snapshot'
|
||||
if (project.hasProperty('artifactoryUsername')) {
|
||||
credentials {
|
||||
username "$artifactoryUsername"
|
||||
password "$artifactoryPassword"
|
||||
}
|
||||
}
|
||||
}
|
||||
maven { url 'https://repo.spring.io/plugins-snapshot' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.parallel=true
|
||||
version=2.5.0-M1
|
||||
version=2.4.2
|
||||
|
||||
@@ -3,8 +3,8 @@ dependencyManagement {
|
||||
mavenBom 'io.projectreactor:reactor-bom:2020.0.3'
|
||||
mavenBom 'org.junit:junit-bom:5.7.0'
|
||||
mavenBom 'org.springframework:spring-framework-bom:5.3.3'
|
||||
mavenBom 'org.springframework.data:spring-data-bom:2021.0.0-M2'
|
||||
mavenBom 'org.springframework.security:spring-security-bom:5.5.0-M1'
|
||||
mavenBom 'org.springframework.data:spring-data-bom:2020.0.3'
|
||||
mavenBom 'org.springframework.security:spring-security-bom:5.4.2'
|
||||
mavenBom 'org.testcontainers:testcontainers-bom:1.15.1'
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ dependencyManagement {
|
||||
dependency 'junit:junit:4.13.1'
|
||||
dependency 'mysql:mysql-connector-java:8.0.22'
|
||||
dependency 'org.apache.derby:derby:10.14.2.0'
|
||||
dependency 'org.assertj:assertj-core:3.18.1'
|
||||
dependency 'org.assertj:assertj-core:3.18.0'
|
||||
dependency 'org.hsqldb:hsqldb:2.5.1'
|
||||
dependency 'org.mariadb.jdbc:mariadb-java-client:2.7.1'
|
||||
dependency 'org.mockito:mockito-core:3.7.7'
|
||||
dependency 'org.mariadb.jdbc:mariadb-java-client:2.7.0'
|
||||
dependency 'org.mockito:mockito-core:3.5.15'
|
||||
dependency 'org.postgresql:postgresql:42.2.18'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.session.data.redis;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -37,7 +36,6 @@ import org.springframework.data.redis.core.BoundHashOperations;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.util.ByteUtils;
|
||||
import org.springframework.session.DelegatingIndexResolver;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.FlushMode;
|
||||
@@ -88,7 +86,7 @@ import org.springframework.util.Assert;
|
||||
* details.
|
||||
*
|
||||
* <pre>
|
||||
* HMSET spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe creationTime 1404360000000 maxInactiveInterval 1800 lastAccessedTime 1404360000000 sessionAttr:attrName someAttrValue sessionAttr:attrName2 someAttrValue2
|
||||
* HMSET spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe creationTime 1404360000000 maxInactiveInterval 1800 lastAccessedTime 1404360000000 sessionAttr:attrName someAttrValue sessionAttr2:attrName someAttrValue2
|
||||
* EXPIRE spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe 2100
|
||||
* APPEND spring:session:sessions:expires:33fdd1b6-b496-4b33-9f7d-df96679d32fe ""
|
||||
* EXPIRE spring:session:sessions:expires:33fdd1b6-b496-4b33-9f7d-df96679d32fe 1800
|
||||
@@ -131,8 +129,8 @@ import org.springframework.util.Assert;
|
||||
* The {@link RedisIndexedSessionRepository.RedisSession} keeps track of the properties
|
||||
* that have changed and only updates those. This means if an attribute is written once
|
||||
* and read many times we only need to write that attribute once. For example, assume the
|
||||
* session attribute "attrName2" from earlier was updated. The following would be executed
|
||||
* upon saving:
|
||||
* session attribute "sessionAttr2" from earlier was updated. The following would be
|
||||
* executed upon saving:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
@@ -274,20 +272,10 @@ public class RedisIndexedSessionRepository
|
||||
|
||||
private String sessionCreatedChannelPrefix;
|
||||
|
||||
private byte[] sessionCreatedChannelPrefixBytes;
|
||||
|
||||
private String sessionDeletedChannel;
|
||||
|
||||
private byte[] sessionDeletedChannelBytes;
|
||||
|
||||
private String sessionExpiredChannel;
|
||||
|
||||
private byte[] sessionExpiredChannelBytes;
|
||||
|
||||
private String expiredKeyPrefix;
|
||||
|
||||
private byte[] expiredKeyPrefixBytes;
|
||||
|
||||
private final RedisOperations<Object, Object> sessionRedisOperations;
|
||||
|
||||
private final RedisSessionExpirationPolicy expirationPolicy;
|
||||
@@ -393,13 +381,8 @@ public class RedisIndexedSessionRepository
|
||||
|
||||
private void configureSessionChannels() {
|
||||
this.sessionCreatedChannelPrefix = this.namespace + "event:" + this.database + ":created:";
|
||||
this.sessionCreatedChannelPrefixBytes = this.sessionCreatedChannelPrefix.getBytes();
|
||||
this.sessionDeletedChannel = "__keyevent@" + this.database + "__:del";
|
||||
this.sessionDeletedChannelBytes = this.sessionDeletedChannel.getBytes();
|
||||
this.sessionExpiredChannel = "__keyevent@" + this.database + "__:expired";
|
||||
this.sessionExpiredChannelBytes = this.sessionExpiredChannel.getBytes();
|
||||
this.expiredKeyPrefix = this.namespace + "sessions:expires:";
|
||||
this.expiredKeyPrefixBytes = this.expiredKeyPrefix.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -518,24 +501,25 @@ public class RedisIndexedSessionRepository
|
||||
@Override
|
||||
public void onMessage(Message message, byte[] pattern) {
|
||||
byte[] messageChannel = message.getChannel();
|
||||
byte[] messageBody = message.getBody();
|
||||
|
||||
if (ByteUtils.startsWith(messageChannel, this.sessionCreatedChannelPrefixBytes)) {
|
||||
String channel = new String(messageChannel);
|
||||
|
||||
if (channel.startsWith(this.sessionCreatedChannelPrefix)) {
|
||||
// TODO: is this thread safe?
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Object, Object> loaded = (Map<Object, Object>) this.defaultSerializer.deserialize(message.getBody());
|
||||
handleCreated(loaded, new String(messageChannel));
|
||||
handleCreated(loaded, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] messageBody = message.getBody();
|
||||
|
||||
if (!ByteUtils.startsWith(messageBody, this.expiredKeyPrefixBytes)) {
|
||||
String body = new String(messageBody);
|
||||
if (!body.startsWith(getExpiredKeyPrefix())) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isDeleted = Arrays.equals(messageChannel, this.sessionDeletedChannelBytes);
|
||||
if (isDeleted || Arrays.equals(messageChannel, this.sessionExpiredChannelBytes)) {
|
||||
String body = new String(messageBody);
|
||||
boolean isDeleted = channel.equals(this.sessionDeletedChannel);
|
||||
if (isDeleted || channel.equals(this.sessionExpiredChannel)) {
|
||||
int beginIndex = body.lastIndexOf(":") + 1;
|
||||
int endIndex = body.length();
|
||||
String sessionId = body.substring(beginIndex, endIndex);
|
||||
@@ -627,7 +611,7 @@ public class RedisIndexedSessionRepository
|
||||
}
|
||||
|
||||
private String getExpiredKeyPrefix() {
|
||||
return this.expiredKeyPrefix;
|
||||
return this.namespace + "sessions:expires:";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -42,13 +42,13 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class RedisSessionRepository implements SessionRepository<RedisSessionRepository.RedisSession> {
|
||||
|
||||
private static final String DEFAULT_KEY_NAMESPACE = "spring:session";
|
||||
private static final String DEFAULT_KEY_NAMESPACE = "spring:session:";
|
||||
|
||||
private final RedisOperations<String, Object> sessionRedisOperations;
|
||||
|
||||
private Duration defaultMaxInactiveInterval = Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
|
||||
|
||||
private String keyNamespace = DEFAULT_KEY_NAMESPACE + ":";
|
||||
private String keyNamespace = DEFAULT_KEY_NAMESPACE;
|
||||
|
||||
private FlushMode flushMode = FlushMode.ON_SAVE;
|
||||
|
||||
@@ -76,23 +76,12 @@ public class RedisSessionRepository implements SessionRepository<RedisSessionRep
|
||||
/**
|
||||
* Set the key namespace.
|
||||
* @param keyNamespace the key namespace
|
||||
* @deprecated since 2.4.0 in favor of {@link #setRedisKeyNamespace(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setKeyNamespace(String keyNamespace) {
|
||||
Assert.hasText(keyNamespace, "keyNamespace must not be empty");
|
||||
this.keyNamespace = keyNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Redis key namespace.
|
||||
* @param namespace the Redis key namespace
|
||||
*/
|
||||
public void setRedisKeyNamespace(String namespace) {
|
||||
Assert.hasText(namespace, "namespace must not be empty");
|
||||
this.keyNamespace = namespace.trim() + ":";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the flush mode.
|
||||
* @param flushMode the flush mode
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -102,36 +102,18 @@ class RedisSessionRepositoryTests {
|
||||
assertThat(ReflectionTestUtils.getField(this.sessionRepository, "keyNamespace")).isEqualTo("test:");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setRedisKeyNamespace_ValidNamespace_ShouldSetNamespace() {
|
||||
this.sessionRepository.setRedisKeyNamespace("test");
|
||||
assertThat(ReflectionTestUtils.getField(this.sessionRepository, "keyNamespace")).isEqualTo("test:");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setKeyNamespace_NullNamespace_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.sessionRepository.setKeyNamespace(null))
|
||||
.withMessage("keyNamespace must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setRedisKeyNamespace_NullNamespace_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.sessionRepository.setRedisKeyNamespace(null))
|
||||
.withMessage("namespace must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setKeyNamespace_EmptyNamespace_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.sessionRepository.setKeyNamespace(" "))
|
||||
.withMessage("keyNamespace must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setRedisKeyNamespace_EmptyNamespace_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.sessionRepository.setRedisKeyNamespace(" "))
|
||||
.withMessage("namespace must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setFlushMode_ValidFlushMode_ShouldSetFlushMode() {
|
||||
this.sessionRepository.setFlushMode(FlushMode.IMMEDIATE);
|
||||
@@ -203,7 +185,7 @@ class RedisSessionRepositoryTests {
|
||||
|
||||
@Test
|
||||
void save_NewSessionAndCustomKeyNamespace_ShouldSaveSession() {
|
||||
this.sessionRepository.setRedisKeyNamespace("custom");
|
||||
this.sessionRepository.setKeyNamespace("custom:");
|
||||
RedisSession session = this.sessionRepository.createSession();
|
||||
this.sessionRepository.save(session);
|
||||
String key = "custom:sessions:" + session.getId();
|
||||
|
||||
@@ -791,7 +791,7 @@ HMSET spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe creationTime
|
||||
maxInactiveInterval 1800 \
|
||||
lastAccessedTime 1404360000000 \
|
||||
sessionAttr:attrName someAttrValue \
|
||||
sessionAttr:attrName2 someAttrValue2
|
||||
sessionAttr2:attrName someAttrValue2
|
||||
EXPIRE spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe 2100
|
||||
APPEND spring:session:sessions:expires:33fdd1b6-b496-4b33-9f7d-df96679d32fe ""
|
||||
EXPIRE spring:session:sessions:expires:33fdd1b6-b496-4b33-9f7d-df96679d32fe 1800
|
||||
@@ -814,7 +814,7 @@ HMSET spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe creationTime
|
||||
maxInactiveInterval 1800 \
|
||||
lastAccessedTime 1404360000000 \
|
||||
sessionAttr:attrName someAttrValue \
|
||||
sessionAttr:attrName2 someAttrValue2
|
||||
sessionAttr2:attrName someAttrValue2
|
||||
----
|
||||
====
|
||||
|
||||
@@ -833,7 +833,7 @@ The second session attribute is named `attrName2`, with a value of `someAttrValu
|
||||
|
||||
The `Session` instances managed by `RedisIndexedSessionRepository` keeps track of the properties that have changed and updates only those.
|
||||
This means that, if an attribute is written once and read many times, we need to write that attribute only once.
|
||||
For example, assume the `attrName2` session attribute from the lsiting in the preceding section was updated.
|
||||
For example, assume the `sessionAttr2` session attribute from the lsiting in the preceding section was updated.
|
||||
The following command would be run upon saving:
|
||||
|
||||
====
|
||||
@@ -1406,8 +1406,11 @@ Spring Session is Open Source software released under the https://www.apache.org
|
||||
|===
|
||||
| Name | Location
|
||||
|
||||
| Spring Session OrientDB
|
||||
| https://github.com/maseev/spring-session-orientdb
|
||||
|
||||
| Spring Session Infinispan
|
||||
| https://infinispan.org/infinispan-spring-boot/master/spring_boot_starter.html#_enabling_spring_session_support
|
||||
| https://infinispan.org/docs/dev/user_guide/user_guide.html#externalizing_session_using_spring_session
|
||||
|
||||
|===
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ artifacts {
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-session-core')
|
||||
optional "com.hazelcast:hazelcast:4.1.1"
|
||||
optional "com.hazelcast:hazelcast:4.0.3"
|
||||
compile "org.springframework:spring-context"
|
||||
compile "javax.annotation:javax.annotation-api"
|
||||
|
||||
@@ -42,7 +42,7 @@ dependencies {
|
||||
testRuntime "org.junit.jupiter:junit-jupiter-engine"
|
||||
|
||||
integrationTestCompile "org.testcontainers:testcontainers"
|
||||
integrationTestCompile "com.hazelcast:hazelcast:4.1.1"
|
||||
integrationTestCompile "com.hazelcast:hazelcast:4.0.3"
|
||||
integrationTestCompile project(":spring-session-hazelcast")
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
||||
@WebAppConfiguration
|
||||
class ClientServerHazelcast4IndexedSessionRepositoryITests extends AbstractHazelcast4IndexedSessionRepositoryITests {
|
||||
|
||||
private static GenericContainer container = new GenericContainer<>("hazelcast/hazelcast:4.1.1")
|
||||
private static GenericContainer container = new GenericContainer<>("hazelcast/hazelcast:4.0.2")
|
||||
.withExposedPorts(5701).withCopyFileToContainer(MountableFile.forClasspathResource("/hazelcast-server.xml"),
|
||||
"/opt/hazelcast/hazelcast.xml");
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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-4.1.xsd">
|
||||
xsi:schemaLocation="http://www.hazelcast.com/schema/config https://www.hazelcast.com/schema/config/hazelcast-config-4.0.xsd">
|
||||
|
||||
<network>
|
||||
<join>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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.13.xsd">
|
||||
xsi:schemaLocation="http://www.hazelcast.com/schema/config https://www.hazelcast.com/schema/config/hazelcast-config-3.12.xsd">
|
||||
|
||||
<network>
|
||||
<join>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -29,15 +29,8 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.jdbc.support.lob.DefaultLobHandler;
|
||||
import org.springframework.jdbc.support.lob.LobCreator;
|
||||
import org.springframework.jdbc.support.lob.LobHandler;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
@@ -45,7 +38,6 @@ import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
import org.springframework.session.jdbc.JdbcIndexedSessionRepository.JdbcSession;
|
||||
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
@@ -53,8 +45,6 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Base class for {@link JdbcIndexedSessionRepository} integration tests.
|
||||
@@ -67,27 +57,15 @@ abstract class AbstractJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
private static final String INDEX_NAME = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private JdbcIndexedSessionRepository repository;
|
||||
|
||||
private JdbcOperations jdbcOperations;
|
||||
|
||||
private LobHandler lobHandler;
|
||||
|
||||
private SecurityContext context;
|
||||
|
||||
private SecurityContext changedContext;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.jdbcOperations = new JdbcTemplate(this.dataSource);
|
||||
this.lobHandler = new DefaultLobHandler();
|
||||
this.context = SecurityContextHolder.createEmptyContext();
|
||||
this.context.setAuthentication(new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), "na",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
@@ -781,32 +759,6 @@ abstract class AbstractJdbcIndexedSessionRepositoryITests {
|
||||
assertThat((byte[]) session.getAttribute(attributeName)).hasSize(arraySize);
|
||||
}
|
||||
|
||||
@Test // gh-1213
|
||||
void saveNewSessionAttributeConcurrently() {
|
||||
JdbcSession session = this.repository.createSession();
|
||||
this.repository.save(session);
|
||||
String attributeName = "attribute1";
|
||||
String attributeValue = "value1";
|
||||
try (LobCreator lobCreator = this.lobHandler.getLobCreator()) {
|
||||
this.jdbcOperations.update("INSERT INTO SPRING_SESSION_ATTRIBUTES VALUES (?, ?, ?)", (ps) -> {
|
||||
ps.setString(1, (String) ReflectionTestUtils.getField(session, "primaryKey"));
|
||||
ps.setString(2, attributeName);
|
||||
lobCreator.setBlobAsBytes(ps, 3, "value2".getBytes());
|
||||
});
|
||||
}
|
||||
session.setAttribute(attributeName, attributeValue);
|
||||
if (this.applicationContext.getBeansOfType(SessionRepositoryCustomizer.class).isEmpty()) {
|
||||
// without DB specific upsert configured we're seeing duplicate key error
|
||||
assertThatExceptionOfType(DuplicateKeyException.class).isThrownBy(() -> this.repository.save(session));
|
||||
}
|
||||
else {
|
||||
// with DB specific upsert configured we're fine
|
||||
assertThatCode(() -> this.repository.save(session)).doesNotThrowAnyException();
|
||||
assertThat((String) this.repository.findById(session.getId()).getAttribute(attributeName))
|
||||
.isEqualTo(attributeValue);
|
||||
}
|
||||
}
|
||||
|
||||
private String getSecurityName() {
|
||||
return this.context.getAuthentication().getName();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.session.jdbc;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import org.testcontainers.containers.Db2Container;
|
||||
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||
@@ -37,42 +38,169 @@ final class DatabaseContainers {
|
||||
private DatabaseContainers() {
|
||||
}
|
||||
|
||||
static Db2Container db2() {
|
||||
return new Db2Container("ibmcom/db2:11.5.4.0");
|
||||
static Db211Container db211() {
|
||||
return new Db211Container();
|
||||
}
|
||||
|
||||
static MariaDBContainer<?> mariaDb() {
|
||||
return new MariaDBContainer<>("mariadb:10.5.7");
|
||||
static MariaDBContainer mariaDb5() {
|
||||
return new MariaDb5Container();
|
||||
}
|
||||
|
||||
static MySQLContainer<?> mySql() {
|
||||
return new MySQLContainer<>("mysql:8.0.22");
|
||||
static MariaDBContainer mariaDb10() {
|
||||
return new MariaDb10Container();
|
||||
}
|
||||
|
||||
static OracleContainer oracle() {
|
||||
return new OracleContainer() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
this.waitStrategy = new LogMessageWaitStrategy().withRegEx(".*DATABASE IS READY TO USE!.*\\s")
|
||||
.withStartupTimeout(Duration.ofMinutes(10));
|
||||
addEnv("ORACLE_PWD", getPassword());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void waitUntilContainerStarted() {
|
||||
getWaitStrategy().waitUntilReady(this);
|
||||
}
|
||||
|
||||
};
|
||||
static MySQLContainer mySql5() {
|
||||
return new MySql5Container();
|
||||
}
|
||||
|
||||
static PostgreSQLContainer<?> postgreSql() {
|
||||
return new PostgreSQLContainer<>("postgres:13.0");
|
||||
static MySQLContainer mySql8() {
|
||||
return new MySql8Container();
|
||||
}
|
||||
|
||||
static MSSQLServerContainer<?> sqlServer() {
|
||||
return new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04");
|
||||
static OracleXeContainer oracleXe() {
|
||||
return new OracleXeContainer();
|
||||
}
|
||||
|
||||
static PostgreSQLContainer postgreSql9() {
|
||||
return new PostgreSql9Container();
|
||||
}
|
||||
|
||||
static PostgreSQLContainer postgreSql10() {
|
||||
return new PostgreSql10Container();
|
||||
}
|
||||
|
||||
static PostgreSQLContainer postgreSql11() {
|
||||
return new PostgreSql11Container();
|
||||
}
|
||||
|
||||
static MSSQLServerContainer sqlServer2017() {
|
||||
return new SqlServer2017Container();
|
||||
}
|
||||
|
||||
private static class Db211Container extends Db2Container {
|
||||
|
||||
Db211Container() {
|
||||
super("ibmcom/db2:11.5.0.0a");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MariaDb5Container extends MariaDBContainer<MariaDb5Container> {
|
||||
|
||||
MariaDb5Container() {
|
||||
super("mariadb:5.5.64");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
setCommand("mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci",
|
||||
"--innodb_large_prefix", "--innodb_file_format=barracuda", "--innodb-file-per-table");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MariaDb10Container extends MariaDBContainer<MariaDb10Container> {
|
||||
|
||||
MariaDb10Container() {
|
||||
super("mariadb:10.4.8");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
setCommand("mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MySql5Container extends MySQLContainer<MySql5Container> {
|
||||
|
||||
MySql5Container() {
|
||||
super("mysql:5.7.27");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
setCommand("mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverClassName() {
|
||||
return "com.mysql.cj.jdbc.Driver";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MySql8Container extends MySQLContainer<MySql8Container> {
|
||||
|
||||
MySql8Container() {
|
||||
super("mysql:8.0.17");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
setCommand("mysqld", "--default-authentication-plugin=mysql_native_password");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverClassName() {
|
||||
return "com.mysql.cj.jdbc.Driver";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class OracleXeContainer extends OracleContainer {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
this.waitStrategy = new LogMessageWaitStrategy().withRegEx(".*DATABASE IS READY TO USE!.*\\s")
|
||||
.withStartupTimeout(Duration.of(10, ChronoUnit.MINUTES));
|
||||
setShmSize(1024L * 1024L * 1024L);
|
||||
addEnv("ORACLE_PWD", getPassword());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void waitUntilContainerStarted() {
|
||||
getWaitStrategy().waitUntilReady(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PostgreSql9Container extends PostgreSQLContainer<PostgreSql9Container> {
|
||||
|
||||
PostgreSql9Container() {
|
||||
super("postgres:9.6.15");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PostgreSql10Container extends PostgreSQLContainer<PostgreSql10Container> {
|
||||
|
||||
PostgreSql10Container() {
|
||||
super("postgres:10.10");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PostgreSql11Container extends PostgreSQLContainer<PostgreSql11Container> {
|
||||
|
||||
PostgreSql11Container() {
|
||||
super("postgres:11.5");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SqlServer2017Container extends MSSQLServerContainer<SqlServer2017Container> {
|
||||
|
||||
SqlServer2017Container() {
|
||||
super("mcr.microsoft.com/mssql/server:2017-CU16");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -27,21 +27,21 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using IBM DB2 database.
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using IBM DB2 11.x database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class Db2JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
class Db211JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
Db2Container databaseContainer() {
|
||||
Db2Container databaseContainer = DatabaseContainers.db2();
|
||||
Db2Container databaseContainer = DatabaseContainers.db211();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using IBM DB2 database with
|
||||
* {@link Db2JdbcIndexedSessionRepositoryCustomizer}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class Db2JdbcIndexedSessionRepositoryCustomizerITests extends Db2JdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class CustomizerConfig extends Config {
|
||||
|
||||
@Bean
|
||||
Db2JdbcIndexedSessionRepositoryCustomizer db2JdbcIndexedSessionRepositoryCustomizer() {
|
||||
return new Db2JdbcIndexedSessionRepositoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.testcontainers.containers.MariaDBContainer;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MariaDB 10.x database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class MariaDb10JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
MariaDBContainer databaseContainer() {
|
||||
MariaDBContainer databaseContainer = DatabaseContainers.mariaDb10();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceDatabasePopulator databasePopulator() {
|
||||
return DatabasePopulators.mySql();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -27,21 +27,21 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MariaDB database.
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MariaDB 5.x database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class MariaDbJdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
class MariaDb5JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
MariaDBContainer<?> databaseContainer() {
|
||||
MariaDBContainer<?> databaseContainer = DatabaseContainers.mariaDb();
|
||||
MariaDBContainer databaseContainer() {
|
||||
MariaDBContainer databaseContainer = DatabaseContainers.mariaDb5();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MariaDB database with
|
||||
* {@link MySqlJdbcIndexedSessionRepositoryCustomizer}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class MariaDbJdbcIndexedSessionRepositoryCustomizerITests extends MariaDbJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class CustomizerConfig extends Config {
|
||||
|
||||
@Bean
|
||||
MySqlJdbcIndexedSessionRepositoryCustomizer mySqlJdbcIndexedSessionRepositoryCustomizer() {
|
||||
return new MySqlJdbcIndexedSessionRepositoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -27,21 +27,21 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MySQL database.
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MySQL 5.x database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class MySqlJdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
class MySql5JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
MySQLContainer<?> databaseContainer() {
|
||||
MySQLContainer<?> databaseContainer = DatabaseContainers.mySql();
|
||||
MySQLContainer databaseContainer() {
|
||||
MySQLContainer databaseContainer = DatabaseContainers.mySql5();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.testcontainers.containers.MySQLContainer;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MySQL 8.x database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class MySql8JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
MySQLContainer databaseContainer() {
|
||||
MySQLContainer databaseContainer = DatabaseContainers.mySql8();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceDatabasePopulator databasePopulator() {
|
||||
return DatabasePopulators.mySql();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using MySQL database with
|
||||
* {@link MySqlJdbcIndexedSessionRepositoryCustomizer}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class MySqlJdbcIndexedSessionRepositoryCustomizerITests extends MySqlJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class CustomizerConfig extends Config {
|
||||
|
||||
@Bean
|
||||
MySqlJdbcIndexedSessionRepositoryCustomizer mySqlJdbcIndexedSessionRepositoryCustomizer() {
|
||||
return new MySqlJdbcIndexedSessionRepositoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using Oracle database with
|
||||
* {@link OracleJdbcIndexedSessionRepositoryCustomizer}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class OracleJdbcIndexedSessionRepositoryCustomizerITests extends OracleJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class CustomizerConfig extends Config {
|
||||
|
||||
@Bean
|
||||
OracleJdbcIndexedSessionRepositoryCustomizer oracleJdbcIndexedSessionRepositoryCustomizer() {
|
||||
return new OracleJdbcIndexedSessionRepositoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -54,7 +54,7 @@ class OracleJdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcInde
|
||||
|
||||
@Bean
|
||||
OracleContainer databaseContainer() {
|
||||
OracleContainer databaseContainer = DatabaseContainers.oracle();
|
||||
OracleContainer databaseContainer = DatabaseContainers.oracleXe();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using PostgreSQL 10.x
|
||||
* database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class PostgreSql10JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
PostgreSQLContainer databaseContainer() {
|
||||
PostgreSQLContainer databaseContainer = DatabaseContainers.postgreSql10();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceDatabasePopulator databasePopulator() {
|
||||
return DatabasePopulators.postgreSql();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using PostgreSQL 11.x
|
||||
* database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class PostgreSql11JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
PostgreSQLContainer databaseContainer() {
|
||||
PostgreSQLContainer databaseContainer = DatabaseContainers.postgreSql11();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceDatabasePopulator databasePopulator() {
|
||||
return DatabasePopulators.postgreSql();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -27,21 +27,22 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using PostgreSQL database.
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using PostgreSQL 9.x
|
||||
* database.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class PostgreSqlJdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
class PostgreSql9JdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
PostgreSQLContainer<?> databaseContainer() {
|
||||
PostgreSQLContainer<?> databaseContainer = DatabaseContainers.postgreSql();
|
||||
PostgreSQLContainer databaseContainer() {
|
||||
PostgreSQLContainer databaseContainer = DatabaseContainers.postgreSql9();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using PostgreSQL database
|
||||
* with {@link PostgreSqlJdbcIndexedSessionRepositoryCustomizer}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class PostgreSqlJdbcIndexedSessionRepositoryCustomizerITests extends PostgreSqlJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class CustomizerConfig extends Config {
|
||||
|
||||
@Bean
|
||||
PostgreSqlJdbcIndexedSessionRepositoryCustomizer postgreSqlJdbcIndexedSessionRepositoryCustomizer() {
|
||||
return new PostgreSqlJdbcIndexedSessionRepositoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JdbcIndexedSessionRepository} using SQL Server database
|
||||
* with {@link SqlServerJdbcIndexedSessionRepositoryCustomizer}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration
|
||||
class SqlServerJdbcIndexedSessionRepositoryCustomizerITests extends SqlServerJdbcIndexedSessionRepositoryITests {
|
||||
|
||||
@Configuration
|
||||
static class CustomizerConfig extends Config {
|
||||
|
||||
@Bean
|
||||
SqlServerJdbcIndexedSessionRepositoryCustomizer sqlServerJdbcIndexedSessionRepositoryCustomizer() {
|
||||
return new SqlServerJdbcIndexedSessionRepositoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -41,8 +41,8 @@ class SqlServerJdbcIndexedSessionRepositoryITests extends AbstractContainerJdbcI
|
||||
static class Config extends BaseContainerConfig {
|
||||
|
||||
@Bean
|
||||
MSSQLServerContainer<?> databaseContainer() {
|
||||
MSSQLServerContainer<?> databaseContainer = DatabaseContainers.sqlServer();
|
||||
MSSQLServerContainer databaseContainer() {
|
||||
MSSQLServerContainer databaseContainer = DatabaseContainers.sqlServer2017();
|
||||
databaseContainer.start();
|
||||
return databaseContainer;
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
ibmcom/db2:11.5.4.0
|
||||
mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04
|
||||
ibmcom/db2:11.5.0.0a
|
||||
mcr.microsoft.com/mssql/server:2017-CU16
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
|
||||
/**
|
||||
* A {@link SessionRepositoryCustomizer} implementation that applies IBM DB2 specific
|
||||
* optimized SQL statements to {@link JdbcIndexedSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public class Db2JdbcIndexedSessionRepositoryCustomizer
|
||||
implements SessionRepositoryCustomizer<JdbcIndexedSessionRepository> {
|
||||
|
||||
// @formatter:off
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "MERGE INTO %TABLE_NAME%_ATTRIBUTES SA "
|
||||
+ "USING ( "
|
||||
+ " VALUES (?, ?, ?) "
|
||||
+ ") A (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ "ON (SA.SESSION_PRIMARY_ID = A.SESSION_PRIMARY_ID and SA.ATTRIBUTE_NAME = A.ATTRIBUTE_NAME) "
|
||||
+ "WHEN MATCHED THEN "
|
||||
+ " UPDATE SET ATTRIBUTE_BYTES = A.ATTRIBUTE_BYTES "
|
||||
+ "WHEN NOT MATCHED THEN "
|
||||
+ " INSERT (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ " VALUES (A.SESSION_PRIMARY_ID, A.ATTRIBUTE_NAME, A.ATTRIBUTE_BYTES)";
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public void customize(JdbcIndexedSessionRepository sessionRepository) {
|
||||
sessionRepository.setCreateSessionAttributeQuery(CREATE_SESSION_ATTRIBUTE_QUERY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -40,8 +40,6 @@ import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.serializer.support.DeserializingConverter;
|
||||
import org.springframework.core.serializer.support.SerializingConverter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
@@ -141,64 +139,55 @@ public class JdbcIndexedSessionRepository
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
// @formatter:off
|
||||
private static final String CREATE_SESSION_QUERY = ""
|
||||
+ "INSERT INTO %TABLE_NAME% (PRIMARY_ID, SESSION_ID, CREATION_TIME, LAST_ACCESS_TIME, MAX_INACTIVE_INTERVAL, EXPIRY_TIME, PRINCIPAL_NAME) "
|
||||
private static final String CREATE_SESSION_QUERY = "INSERT INTO %TABLE_NAME%(PRIMARY_ID, SESSION_ID, CREATION_TIME, LAST_ACCESS_TIME, MAX_INACTIVE_INTERVAL, EXPIRY_TIME, PRINCIPAL_NAME) "
|
||||
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "INSERT INTO %TABLE_NAME%_ATTRIBUTES (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ "VALUES (?, ?, ?)";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String GET_SESSION_QUERY = ""
|
||||
+ "SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES "
|
||||
+ "FROM %TABLE_NAME% S "
|
||||
+ "LEFT JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID "
|
||||
+ "WHERE S.SESSION_ID = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String UPDATE_SESSION_QUERY = ""
|
||||
+ "UPDATE %TABLE_NAME% "
|
||||
+ "SET SESSION_ID = ?, LAST_ACCESS_TIME = ?, MAX_INACTIVE_INTERVAL = ?, EXPIRY_TIME = ?, PRINCIPAL_NAME = ? "
|
||||
+ "WHERE PRIMARY_ID = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String UPDATE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "UPDATE %TABLE_NAME%_ATTRIBUTES "
|
||||
+ "SET ATTRIBUTE_BYTES = ? "
|
||||
+ "WHERE SESSION_PRIMARY_ID = ? "
|
||||
+ "AND ATTRIBUTE_NAME = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String DELETE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "DELETE FROM %TABLE_NAME%_ATTRIBUTES "
|
||||
+ "WHERE SESSION_PRIMARY_ID = ? "
|
||||
+ "AND ATTRIBUTE_NAME = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String DELETE_SESSION_QUERY = ""
|
||||
+ "DELETE FROM %TABLE_NAME% "
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY = "INSERT INTO %TABLE_NAME%_ATTRIBUTES(SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ "SELECT PRIMARY_ID, ?, ? "
|
||||
+ "FROM %TABLE_NAME% "
|
||||
+ "WHERE SESSION_ID = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String LIST_SESSIONS_BY_PRINCIPAL_NAME_QUERY = ""
|
||||
+ "SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES "
|
||||
private static final String GET_SESSION_QUERY = "SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES "
|
||||
+ "FROM %TABLE_NAME% S "
|
||||
+ "LEFT JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID "
|
||||
+ "LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID "
|
||||
+ "WHERE S.SESSION_ID = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String UPDATE_SESSION_QUERY = "UPDATE %TABLE_NAME% SET SESSION_ID = ?, LAST_ACCESS_TIME = ?, MAX_INACTIVE_INTERVAL = ?, EXPIRY_TIME = ?, PRINCIPAL_NAME = ? "
|
||||
+ "WHERE PRIMARY_ID = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String UPDATE_SESSION_ATTRIBUTE_QUERY = "UPDATE %TABLE_NAME%_ATTRIBUTES SET ATTRIBUTE_BYTES = ? "
|
||||
+ "WHERE SESSION_PRIMARY_ID = ? "
|
||||
+ "AND ATTRIBUTE_NAME = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String DELETE_SESSION_ATTRIBUTE_QUERY = "DELETE FROM %TABLE_NAME%_ATTRIBUTES "
|
||||
+ "WHERE SESSION_PRIMARY_ID = ? "
|
||||
+ "AND ATTRIBUTE_NAME = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String DELETE_SESSION_QUERY = "DELETE FROM %TABLE_NAME% "
|
||||
+ "WHERE SESSION_ID = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String LIST_SESSIONS_BY_PRINCIPAL_NAME_QUERY = "SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES "
|
||||
+ "FROM %TABLE_NAME% S "
|
||||
+ "LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID "
|
||||
+ "WHERE S.PRINCIPAL_NAME = ?";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String DELETE_SESSIONS_BY_EXPIRY_TIME_QUERY = ""
|
||||
+ "DELETE FROM %TABLE_NAME% "
|
||||
private static final String DELETE_SESSIONS_BY_EXPIRY_TIME_QUERY = "DELETE FROM %TABLE_NAME% "
|
||||
+ "WHERE EXPIRY_TIME < ?";
|
||||
// @formatter:on
|
||||
|
||||
@@ -279,7 +268,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setCreateSessionQuery(String createSessionQuery) {
|
||||
Assert.hasText(createSessionQuery, "Query must not be empty");
|
||||
this.createSessionQuery = getQuery(createSessionQuery);
|
||||
this.createSessionQuery = createSessionQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,7 +277,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setCreateSessionAttributeQuery(String createSessionAttributeQuery) {
|
||||
Assert.hasText(createSessionAttributeQuery, "Query must not be empty");
|
||||
this.createSessionAttributeQuery = getQuery(createSessionAttributeQuery);
|
||||
this.createSessionAttributeQuery = createSessionAttributeQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,7 +286,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setGetSessionQuery(String getSessionQuery) {
|
||||
Assert.hasText(getSessionQuery, "Query must not be empty");
|
||||
this.getSessionQuery = getQuery(getSessionQuery);
|
||||
this.getSessionQuery = getSessionQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,7 +295,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setUpdateSessionQuery(String updateSessionQuery) {
|
||||
Assert.hasText(updateSessionQuery, "Query must not be empty");
|
||||
this.updateSessionQuery = getQuery(updateSessionQuery);
|
||||
this.updateSessionQuery = updateSessionQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,7 +304,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setUpdateSessionAttributeQuery(String updateSessionAttributeQuery) {
|
||||
Assert.hasText(updateSessionAttributeQuery, "Query must not be empty");
|
||||
this.updateSessionAttributeQuery = getQuery(updateSessionAttributeQuery);
|
||||
this.updateSessionAttributeQuery = updateSessionAttributeQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,7 +313,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setDeleteSessionAttributeQuery(String deleteSessionAttributeQuery) {
|
||||
Assert.hasText(deleteSessionAttributeQuery, "Query must not be empty");
|
||||
this.deleteSessionAttributeQuery = getQuery(deleteSessionAttributeQuery);
|
||||
this.deleteSessionAttributeQuery = deleteSessionAttributeQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,7 +322,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setDeleteSessionQuery(String deleteSessionQuery) {
|
||||
Assert.hasText(deleteSessionQuery, "Query must not be empty");
|
||||
this.deleteSessionQuery = getQuery(deleteSessionQuery);
|
||||
this.deleteSessionQuery = deleteSessionQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,7 +331,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setListSessionsByPrincipalNameQuery(String listSessionsByPrincipalNameQuery) {
|
||||
Assert.hasText(listSessionsByPrincipalNameQuery, "Query must not be empty");
|
||||
this.listSessionsByPrincipalNameQuery = getQuery(listSessionsByPrincipalNameQuery);
|
||||
this.listSessionsByPrincipalNameQuery = listSessionsByPrincipalNameQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,7 +340,7 @@ public class JdbcIndexedSessionRepository
|
||||
*/
|
||||
public void setDeleteSessionsByExpiryTimeQuery(String deleteSessionsByExpiryTimeQuery) {
|
||||
Assert.hasText(deleteSessionsByExpiryTimeQuery, "Query must not be empty");
|
||||
this.deleteSessionsByExpiryTimeQuery = getQuery(deleteSessionsByExpiryTimeQuery);
|
||||
this.deleteSessionsByExpiryTimeQuery = deleteSessionsByExpiryTimeQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,49 +463,30 @@ public class JdbcIndexedSessionRepository
|
||||
Assert.notEmpty(attributeNames, "attributeNames must not be null or empty");
|
||||
try (LobCreator lobCreator = this.lobHandler.getLobCreator()) {
|
||||
if (attributeNames.size() > 1) {
|
||||
try {
|
||||
this.jdbcOperations.batchUpdate(this.createSessionAttributeQuery,
|
||||
new BatchPreparedStatementSetter() {
|
||||
this.jdbcOperations.batchUpdate(this.createSessionAttributeQuery, new BatchPreparedStatementSetter() {
|
||||
|
||||
@Override
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
String attributeName = attributeNames.get(i);
|
||||
ps.setString(1, session.primaryKey);
|
||||
ps.setString(2, attributeName);
|
||||
lobCreator.setBlobAsBytes(ps, 3, serialize(session.getAttribute(attributeName)));
|
||||
}
|
||||
@Override
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
String attributeName = attributeNames.get(i);
|
||||
ps.setString(1, attributeName);
|
||||
lobCreator.setBlobAsBytes(ps, 2, serialize(session.getAttribute(attributeName)));
|
||||
ps.setString(3, session.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchSize() {
|
||||
return attributeNames.size();
|
||||
}
|
||||
@Override
|
||||
public int getBatchSize() {
|
||||
return attributeNames.size();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
catch (DuplicateKeyException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (DataIntegrityViolationException ex) {
|
||||
// parent record not found - we are ignoring this error because we
|
||||
// assume that a concurrent request has removed the session
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
try {
|
||||
this.jdbcOperations.update(this.createSessionAttributeQuery, (ps) -> {
|
||||
String attributeName = attributeNames.get(0);
|
||||
ps.setString(1, session.primaryKey);
|
||||
ps.setString(2, attributeName);
|
||||
lobCreator.setBlobAsBytes(ps, 3, serialize(session.getAttribute(attributeName)));
|
||||
});
|
||||
}
|
||||
catch (DuplicateKeyException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (DataIntegrityViolationException ex) {
|
||||
// parent record not found - we are ignoring this error because we
|
||||
// assume that a concurrent request has removed the session
|
||||
}
|
||||
this.jdbcOperations.update(this.createSessionAttributeQuery, (ps) -> {
|
||||
String attributeName = attributeNames.get(0);
|
||||
ps.setString(1, attributeName);
|
||||
lobCreator.setBlobAsBytes(ps, 2, serialize(session.getAttribute(attributeName)));
|
||||
ps.setString(3, session.getId());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
|
||||
/**
|
||||
* A {@link SessionRepositoryCustomizer} implementation that applies MySQL specific
|
||||
* optimized SQL statements to {@link JdbcIndexedSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public class MySqlJdbcIndexedSessionRepositoryCustomizer
|
||||
implements SessionRepositoryCustomizer<JdbcIndexedSessionRepository> {
|
||||
|
||||
// @formatter:off
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "INSERT INTO %TABLE_NAME%_ATTRIBUTES (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ "VALUES (?, ?, ?) "
|
||||
+ "ON DUPLICATE KEY UPDATE ATTRIBUTE_BYTES = VALUES(ATTRIBUTE_BYTES)";
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public void customize(JdbcIndexedSessionRepository sessionRepository) {
|
||||
sessionRepository.setCreateSessionAttributeQuery(CREATE_SESSION_ATTRIBUTE_QUERY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
|
||||
/**
|
||||
* A {@link SessionRepositoryCustomizer} implementation that applies Oracle specific
|
||||
* optimized SQL statements to {@link JdbcIndexedSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public class OracleJdbcIndexedSessionRepositoryCustomizer
|
||||
implements SessionRepositoryCustomizer<JdbcIndexedSessionRepository> {
|
||||
|
||||
// @formatter:off
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "MERGE INTO %TABLE_NAME%_ATTRIBUTES SA "
|
||||
+ "USING ( "
|
||||
+ " SELECT ? AS SESSION_PRIMARY_ID, ? AS ATTRIBUTE_NAME, ? AS ATTRIBUTE_BYTES "
|
||||
+ " FROM DUAL "
|
||||
+ ") A "
|
||||
+ "ON (SA.SESSION_PRIMARY_ID = A.SESSION_PRIMARY_ID and SA.ATTRIBUTE_NAME = A.ATTRIBUTE_NAME) "
|
||||
+ "WHEN MATCHED THEN "
|
||||
+ " UPDATE SET ATTRIBUTE_BYTES = A.ATTRIBUTE_BYTES "
|
||||
+ "WHEN NOT MATCHED THEN "
|
||||
+ " INSERT (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ " VALUES (A.SESSION_PRIMARY_ID, A.ATTRIBUTE_NAME, A.ATTRIBUTE_BYTES)";
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public void customize(JdbcIndexedSessionRepository sessionRepository) {
|
||||
sessionRepository.setCreateSessionAttributeQuery(CREATE_SESSION_ATTRIBUTE_QUERY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
|
||||
/**
|
||||
* A {@link SessionRepositoryCustomizer} implementation that applies PostgreSQL specific
|
||||
* optimized SQL statements to {@link JdbcIndexedSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public class PostgreSqlJdbcIndexedSessionRepositoryCustomizer
|
||||
implements SessionRepositoryCustomizer<JdbcIndexedSessionRepository> {
|
||||
|
||||
// @formatter:off
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "INSERT INTO %TABLE_NAME%_ATTRIBUTES (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ "VALUES (?, ?, ?) "
|
||||
+ "ON CONFLICT (SESSION_PRIMARY_ID, ATTRIBUTE_NAME) "
|
||||
+ "DO UPDATE SET ATTRIBUTE_BYTES = EXCLUDED.ATTRIBUTE_BYTES";
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public void customize(JdbcIndexedSessionRepository sessionRepository) {
|
||||
sessionRepository.setCreateSessionAttributeQuery(CREATE_SESSION_ATTRIBUTE_QUERY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.jdbc;
|
||||
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
|
||||
/**
|
||||
* A {@link SessionRepositoryCustomizer} implementation that applies SQL Server specific
|
||||
* optimized SQL statements to {@link JdbcIndexedSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public class SqlServerJdbcIndexedSessionRepositoryCustomizer
|
||||
implements SessionRepositoryCustomizer<JdbcIndexedSessionRepository> {
|
||||
|
||||
// @formatter:off
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY = ""
|
||||
+ "MERGE INTO %TABLE_NAME%_ATTRIBUTES SA "
|
||||
+ "USING ( "
|
||||
+ " VALUES (?, ?, ?) "
|
||||
+ ") A (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ "ON (SA.SESSION_PRIMARY_ID = A.SESSION_PRIMARY_ID and SA.ATTRIBUTE_NAME = A.ATTRIBUTE_NAME) "
|
||||
+ "WHEN MATCHED THEN "
|
||||
+ " UPDATE SET ATTRIBUTE_BYTES = A.ATTRIBUTE_BYTES "
|
||||
+ "WHEN NOT MATCHED THEN "
|
||||
+ " INSERT (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) "
|
||||
+ " VALUES (A.SESSION_PRIMARY_ID, A.ATTRIBUTE_NAME, A.ATTRIBUTE_BYTES);";
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public void customize(JdbcIndexedSessionRepository sessionRepository) {
|
||||
sessionRepository.setCreateSessionAttributeQuery(CREATE_SESSION_ATTRIBUTE_QUERY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -290,9 +290,9 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
this.repository.save(session);
|
||||
|
||||
assertThat(session.isNew()).isFalse();
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION ("),
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION("),
|
||||
isA(PreparedStatementSetter.class));
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES ("),
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
|
||||
isA(PreparedStatementSetter.class));
|
||||
verifyNoMoreInteractions(this.jdbcOperations);
|
||||
}
|
||||
@@ -306,9 +306,9 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
this.repository.save(session);
|
||||
|
||||
assertThat(session.isNew()).isFalse();
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION ("),
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION("),
|
||||
isA(PreparedStatementSetter.class));
|
||||
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES ("),
|
||||
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
|
||||
isA(BatchPreparedStatementSetter.class));
|
||||
verifyNoMoreInteractions(this.jdbcOperations);
|
||||
}
|
||||
@@ -321,7 +321,7 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
this.repository.save(session);
|
||||
|
||||
assertThat(session.isNew()).isFalse();
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES ("),
|
||||
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
|
||||
isA(PreparedStatementSetter.class));
|
||||
verifyNoMoreInteractions(this.jdbcOperations);
|
||||
}
|
||||
@@ -335,7 +335,7 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
this.repository.save(session);
|
||||
|
||||
assertThat(session.isNew()).isFalse();
|
||||
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES ("),
|
||||
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
|
||||
isA(BatchPreparedStatementSetter.class));
|
||||
verifyNoMoreInteractions(this.jdbcOperations);
|
||||
}
|
||||
@@ -424,7 +424,7 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
this.repository.save(session);
|
||||
|
||||
assertThat(session.isNew()).isFalse();
|
||||
verify(this.jdbcOperations).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES ("),
|
||||
verify(this.jdbcOperations).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
|
||||
isA(PreparedStatementSetter.class));
|
||||
verifyNoMoreInteractions(this.jdbcOperations);
|
||||
}
|
||||
@@ -679,7 +679,7 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
JdbcSession session = this.repository.new JdbcSession(new MapSession(), "primaryKey", false);
|
||||
String attrName = "someAttribute";
|
||||
session.setAttribute(attrName, "someValue");
|
||||
verify(this.jdbcOperations).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES ("),
|
||||
verify(this.jdbcOperations).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
|
||||
isA(PreparedStatementSetter.class));
|
||||
verifyNoMoreInteractions(this.jdbcOperations);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.12.1'
|
||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.11.3'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -6,7 +6,7 @@ dependencies {
|
||||
compile "org.springframework.boot:spring-boot-starter-web"
|
||||
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
|
||||
compile "org.springframework.boot:spring-boot-starter-security"
|
||||
compile "com.hazelcast:hazelcast:4.1.1"
|
||||
compile "com.hazelcast:hazelcast:4.0.3"
|
||||
compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect"
|
||||
compile "org.webjars:bootstrap"
|
||||
compile "org.webjars:html5shiv"
|
||||
|
||||
Reference in New Issue
Block a user