Group jdbc-related batch properties beneath spring.batch.jdbc

See gh-25316
pull/25369/head
Mukul Chaundhyan 4 years ago committed by Stephane Nicoll
parent 9a3889baec
commit d093807f95

@ -38,6 +38,7 @@ import org.springframework.transaction.PlatformTransactionManager;
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Kazuki Shimizu * @author Kazuki Shimizu
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Mukul Kumar Chaundhyan
* @since 1.0.0 * @since 1.0.0
*/ */
public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean { public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean {
@ -111,7 +112,7 @@ public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean {
PropertyMapper map = PropertyMapper.get(); PropertyMapper map = PropertyMapper.get();
JobExplorerFactoryBean factory = new JobExplorerFactoryBean(); JobExplorerFactoryBean factory = new JobExplorerFactoryBean();
factory.setDataSource(this.dataSource); factory.setDataSource(this.dataSource);
map.from(this.properties::getTablePrefix).whenHasText().to(factory::setTablePrefix); map.from(this.properties.getJdbc()::getTablePrefix).whenHasText().to(factory::setTablePrefix);
factory.afterPropertiesSet(); factory.afterPropertiesSet();
return factory.getObject(); return factory.getObject();
} }
@ -128,7 +129,7 @@ public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean {
PropertyMapper map = PropertyMapper.get(); PropertyMapper map = PropertyMapper.get();
map.from(this.dataSource).to(factory::setDataSource); map.from(this.dataSource).to(factory::setDataSource);
map.from(this::determineIsolationLevel).whenNonNull().to(factory::setIsolationLevelForCreate); map.from(this::determineIsolationLevel).whenNonNull().to(factory::setIsolationLevelForCreate);
map.from(this.properties::getTablePrefix).whenHasText().to(factory::setTablePrefix); map.from(this.properties.getJdbc()::getTablePrefix).whenHasText().to(factory::setTablePrefix);
map.from(this::getTransactionManager).to(factory::setTransactionManager); map.from(this::getTransactionManager).to(factory::setTransactionManager);
factory.afterPropertiesSet(); factory.afterPropertiesSet();
return factory.getObject(); return factory.getObject();

@ -57,6 +57,7 @@ import org.springframework.util.StringUtils;
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Kazuki Shimizu * @author Kazuki Shimizu
* @author Mahmoud Ben Hassine * @author Mahmoud Ben Hassine
* @author Mukul Kumar Chaundhyan
* @since 1.0.0 * @since 1.0.0
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ -107,11 +108,13 @@ public class BatchAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.batch.jdbc", name = "enabled", havingValue = "true",
matchIfMissing = true)
BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource, BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource,
@BatchDataSource ObjectProvider<DataSource> batchDataSource, ResourceLoader resourceLoader, @BatchDataSource ObjectProvider<DataSource> batchDataSource, ResourceLoader resourceLoader,
BatchProperties properties) { BatchProperties properties) {
return new BatchDataSourceInitializer(batchDataSource.getIfAvailable(() -> dataSource), resourceLoader, return new BatchDataSourceInitializer(batchDataSource.getIfAvailable(() -> dataSource), resourceLoader,
properties); properties.getJdbc());
} }
} }

@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.batch;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.batch.BatchProperties.Jdbc;
import org.springframework.boot.jdbc.AbstractDataSourceInitializer; import org.springframework.boot.jdbc.AbstractDataSourceInitializer;
import org.springframework.boot.jdbc.DataSourceInitializationMode; import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
@ -28,27 +29,27 @@ import org.springframework.util.Assert;
* *
* @author Dave Syer * @author Dave Syer
* @author Vedran Pavic * @author Vedran Pavic
* @author Mukul Kumar Chaundhyan
* @since 1.0.0 * @since 1.0.0
*/ */
public class BatchDataSourceInitializer extends AbstractDataSourceInitializer { public class BatchDataSourceInitializer extends AbstractDataSourceInitializer {
private final BatchProperties properties; private final Jdbc jdbcProperties;
public BatchDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader, public BatchDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader, Jdbc jdbcProperties) {
BatchProperties properties) {
super(dataSource, resourceLoader); super(dataSource, resourceLoader);
Assert.notNull(properties, "BatchProperties must not be null"); Assert.notNull(jdbcProperties, "Jdbc Batch Properties must not be null");
this.properties = properties; this.jdbcProperties = jdbcProperties;
} }
@Override @Override
protected DataSourceInitializationMode getMode() { protected DataSourceInitializationMode getMode() {
return this.properties.getInitializeSchema(); return this.jdbcProperties.getInitializeSchema();
} }
@Override @Override
protected String getSchemaLocation() { protected String getSchemaLocation() {
return this.properties.getSchema(); return this.jdbcProperties.getSchema();
} }
@Override @Override

@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.batch; package org.springframework.boot.autoconfigure.batch;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.jdbc.DataSourceInitializationMode; import org.springframework.boot.jdbc.DataSourceInitializationMode;
/** /**
@ -25,59 +26,51 @@ import org.springframework.boot.jdbc.DataSourceInitializationMode;
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Vedran Pavic * @author Vedran Pavic
* @author Mukul Kumar Chaundhyan
* @since 1.2.0 * @since 1.2.0
*/ */
@ConfigurationProperties(prefix = "spring.batch") @ConfigurationProperties(prefix = "spring.batch")
public class BatchProperties { public class BatchProperties {
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
+ "batch/core/schema-@@platform@@.sql";
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = DEFAULT_SCHEMA_LOCATION;
/**
* Table prefix for all the batch meta-data tables.
*/
private String tablePrefix;
/**
* Database schema initialization mode.
*/
private DataSourceInitializationMode initializeSchema = DataSourceInitializationMode.EMBEDDED;
private final Job job = new Job(); private final Job job = new Job();
private final Jdbc jdbc = new Jdbc();
@DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc")
public String getSchema() { public String getSchema() {
return this.schema; return this.jdbc.getSchema();
} }
public void setSchema(String schema) { public void setSchema(String schema) {
this.schema = schema; this.jdbc.setSchema(schema);
} }
@DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc")
public String getTablePrefix() { public String getTablePrefix() {
return this.tablePrefix; return this.jdbc.getTablePrefix();
} }
public void setTablePrefix(String tablePrefix) { public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix; this.jdbc.setTablePrefix(tablePrefix);
} }
@DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc")
public DataSourceInitializationMode getInitializeSchema() { public DataSourceInitializationMode getInitializeSchema() {
return this.initializeSchema; return this.jdbc.getInitializeSchema();
} }
public void setInitializeSchema(DataSourceInitializationMode initializeSchema) { public void setInitializeSchema(DataSourceInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema; this.jdbc.setInitializeSchema(initializeSchema);
} }
public Job getJob() { public Job getJob() {
return this.job; return this.job;
} }
public Jdbc getJdbc() {
return this.jdbc;
}
public static class Job { public static class Job {
/** /**
@ -96,4 +89,56 @@ public class BatchProperties {
} }
/**
* JDBC configuration properties for Spring Batch.
*
* @author Mukul Kumar Chaundhyan
* @since 2.5.0
*/
public static class Jdbc {
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
+ "batch/core/schema-@@platform@@.sql";
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = DEFAULT_SCHEMA_LOCATION;
/**
* Table prefix for all the batch meta-data tables.
*/
private String tablePrefix;
/**
* Database schema initialization mode.
*/
private DataSourceInitializationMode initializeSchema = DataSourceInitializationMode.EMBEDDED;
public String getSchema() {
return this.schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getTablePrefix() {
return this.tablePrefix;
}
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
}
public DataSourceInitializationMode getInitializeSchema() {
return this.initializeSchema;
}
public void setInitializeSchema(DataSourceInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
}
}
} }

@ -187,6 +187,21 @@ class BatchAutoConfigurationTests {
}); });
} }
@Test
void testDisableSchemaLoaderWithNewJdbcProperties() {
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.jdbc.initialize-schema:never")
.run((context) -> {
assertThat(context).hasSingleBean(JobLauncher.class);
assertThat(context.getBean(BatchProperties.class).getInitializeSchema())
.isEqualTo(DataSourceInitializationMode.NEVER);
assertThatExceptionOfType(BadSqlGrammarException.class)
.isThrownBy(() -> new JdbcTemplate(context.getBean(DataSource.class))
.queryForList("select * from BATCH_JOB_EXECUTION"));
});
}
@Test @Test
void testUsingJpa() { void testUsingJpa() {
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class, this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class,
@ -224,6 +239,27 @@ class BatchAutoConfigurationTests {
}); });
} }
@Test
void testRenamePrefixWithNewJdbcProperties() {
this.contextRunner
.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class,
HibernateJpaAutoConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.jdbc.schema:classpath:batch/custom-schema-hsql.sql",
"spring.batch.jdbc.tablePrefix:PREFIX_")
.run((context) -> {
assertThat(context).hasSingleBean(JobLauncher.class);
assertThat(context.getBean(BatchProperties.class).getInitializeSchema())
.isEqualTo(DataSourceInitializationMode.EMBEDDED);
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
.queryForList("select * from PREFIX_JOB_EXECUTION")).isEmpty();
JobExplorer jobExplorer = context.getBean(JobExplorer.class);
assertThat(jobExplorer.findRunningJobExecutions("test")).isEmpty();
JobRepository jobRepository = context.getBean(JobRepository.class);
assertThat(jobRepository.getLastJobExecution("test", new JobParameters())).isNull();
});
}
@Test @Test
void testCustomizeJpaTransactionManagerUsingProperties() { void testCustomizeJpaTransactionManagerUsingProperties() {
this.contextRunner this.contextRunner

@ -84,6 +84,21 @@ class BatchAutoConfigurationWithoutJpaTests {
}); });
} }
@Test
void jdbcWithCustomPrefixWithNewJdbcProperties() {
this.contextRunner.withUserConfiguration(DefaultConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.jdbc.schema:classpath:batch/custom-schema-hsql.sql",
"spring.batch.jdbc.tablePrefix:PREFIX_")
.run((context) -> {
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
.queryForList("select * from PREFIX_JOB_EXECUTION")).isEmpty();
assertThat(context.getBean(JobExplorer.class).findRunningJobExecutions("test")).isEmpty();
assertThat(context.getBean(JobRepository.class).getLastJobExecution("test", new JobParameters()))
.isNull();
});
}
@EnableBatchProcessing @EnableBatchProcessing
@TestAutoConfigurationPackage(City.class) @TestAutoConfigurationPackage(City.class)
static class DefaultConfiguration { static class DefaultConfiguration {

@ -228,7 +228,7 @@ class JobLauncherApplicationRunnerTests {
@Bean @Bean
BatchDataSourceInitializer batchDataSourceInitializer(ResourceLoader resourceLoader) { BatchDataSourceInitializer batchDataSourceInitializer(ResourceLoader resourceLoader) {
return new BatchDataSourceInitializer(this.dataSource, resourceLoader, new BatchProperties()); return new BatchDataSourceInitializer(this.dataSource, resourceLoader, new BatchProperties().getJdbc());
} }
} }

Loading…
Cancel
Save