Ensure that Session JDBC schema is in place before DB is accessed
Fixes gh-27208
This commit is contained in:
@@ -20,12 +20,16 @@ import java.time.Duration;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import liquibase.integration.spring.SpringLiquibase;
|
||||
import org.flywaydb.core.Flyway;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -81,15 +85,40 @@ class JdbcSessionConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JdbcIndexedSessionRepositoryDependencyConfiguration {
|
||||
|
||||
@Bean
|
||||
JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor dataSourceInitializerJdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor() {
|
||||
return new JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor(
|
||||
JdbcSessionDataSourceInitializer.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "org.flywaydb.core.Flyway")
|
||||
JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor flywayJdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor() {
|
||||
return new JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor(FlywayMigrationInitializer.class,
|
||||
Flyway.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "liquibase.integration.spring.SpringLiquibase")
|
||||
JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor liquibaseJdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor() {
|
||||
return new JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor(FlywayMigrationInitializer.class,
|
||||
SpringLiquibase.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Post processor to ensure that {@link JdbcIndexedSessionRepository} beans depend on
|
||||
* any {@link JdbcSessionDataSourceInitializer} beans.
|
||||
* {@link AbstractDependsOnBeanFactoryPostProcessor} for Spring Session JDBC's
|
||||
* {@link JdbcIndexedSessionRepository}.
|
||||
*/
|
||||
static class DataSourceInitializationJdbcIndexedSessionRepositoryDependencyConfiguration
|
||||
static class JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor
|
||||
extends AbstractDependsOnBeanFactoryPostProcessor {
|
||||
|
||||
DataSourceInitializationJdbcIndexedSessionRepositoryDependencyConfiguration() {
|
||||
super(JdbcIndexedSessionRepository.class, JdbcSessionDataSourceInitializer.class);
|
||||
JdbcIndexedSessionRepositoryDependsOnBeanFactoryPostProcessor(Class<?>... dependencyTypes) {
|
||||
super(JdbcIndexedSessionRepository.class, dependencyTypes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,10 +21,13 @@ import javax.sql.DataSource;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.session.JdbcSessionConfiguration.SpringBootJdbcHttpSessionConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.jdbc.DataSourceInitializationMode;
|
||||
@@ -57,9 +60,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
|
||||
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class,
|
||||
SessionAutoConfiguration.class))
|
||||
.withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class,
|
||||
JdbcTemplateAutoConfiguration.class, SessionAutoConfiguration.class))
|
||||
.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true");
|
||||
|
||||
@Test
|
||||
@@ -190,6 +193,51 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void sessionRepositoryBeansDependOnJdbcSessionDataSourceInitializer() {
|
||||
this.contextRunner.withPropertyValues("spring.session.store-type=jdbc").run((context) -> {
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
String[] sessionRepositoryNames = beanFactory.getBeanNamesForType(JdbcIndexedSessionRepository.class);
|
||||
assertThat(sessionRepositoryNames).isNotEmpty();
|
||||
for (String sessionRepositoryName : sessionRepositoryNames) {
|
||||
assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn())
|
||||
.contains("jdbcSessionDataSourceInitializer");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void sessionRepositoryBeansDependOnFlyway() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
|
||||
.withPropertyValues("spring.session.store-type=jdbc", "spring.session.jdbc.initialize-schema=never")
|
||||
.run((context) -> {
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
String[] sessionRepositoryNames = beanFactory
|
||||
.getBeanNamesForType(JdbcIndexedSessionRepository.class);
|
||||
assertThat(sessionRepositoryNames).isNotEmpty();
|
||||
for (String sessionRepositoryName : sessionRepositoryNames) {
|
||||
assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn())
|
||||
.contains("flyway", "flywayInitializer");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void sessionRepositoryBeansDependOnLiquibase() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class))
|
||||
.withPropertyValues("spring.session.store-type=jdbc", "spring.session.jdbc.initialize-schema=never")
|
||||
.run((context) -> {
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
String[] sessionRepositoryNames = beanFactory
|
||||
.getBeanNamesForType(JdbcIndexedSessionRepository.class);
|
||||
assertThat(sessionRepositoryNames).isNotEmpty();
|
||||
for (String sessionRepositoryName : sessionRepositoryNames) {
|
||||
assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn())
|
||||
.contains("liquibase");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SessionDataSourceConfiguration {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user