Merge pull request #25316 from chaundhyan

* pr/25316:
  Polish "Group jdbc-related batch properties beneath spring.batch.jdbc"
  Group jdbc-related batch properties beneath spring.batch.jdbc

Closes gh-25316
This commit is contained in:
Stephane Nicoll
2021-02-17 11:30:20 +01:00
7 changed files with 177 additions and 65 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@@ -111,7 +111,7 @@ public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean {
PropertyMapper map = PropertyMapper.get();
JobExplorerFactoryBean factory = new JobExplorerFactoryBean();
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();
return factory.getObject();
}
@@ -128,7 +128,7 @@ public class BasicBatchConfigurer implements BatchConfigurer, InitializingBean {
PropertyMapper map = PropertyMapper.get();
map.from(this.dataSource).to(factory::setDataSource);
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);
factory.afterPropertiesSet();
return factory.getObject();

View File

@@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.batch;
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.batch.BatchProperties.Jdbc;
import org.springframework.boot.jdbc.AbstractDataSourceInitializer;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.core.io.ResourceLoader;
@@ -32,23 +33,23 @@ import org.springframework.util.Assert;
*/
public class BatchDataSourceInitializer extends AbstractDataSourceInitializer {
private final BatchProperties properties;
private final Jdbc jdbcProperties;
public BatchDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader,
BatchProperties properties) {
super(dataSource, resourceLoader);
Assert.notNull(properties, "BatchProperties must not be null");
this.properties = properties;
this.jdbcProperties = properties.getJdbc();
}
@Override
protected DataSourceInitializationMode getMode() {
return this.properties.getInitializeSchema();
return this.jdbcProperties.getInitializeSchema();
}
@Override
protected String getSchemaLocation() {
return this.properties.getSchema();
return this.jdbcProperties.getSchema();
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.boot.autoconfigure.batch;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
/**
@@ -25,59 +26,72 @@ import org.springframework.boot.jdbc.DataSourceInitializationMode;
* @author Stephane Nicoll
* @author Eddú Meléndez
* @author Vedran Pavic
* @author Mukul Kumar Chaundhyan
* @since 1.2.0
*/
@ConfigurationProperties(prefix = "spring.batch")
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 Jdbc jdbc = new Jdbc();
/**
* Return the datasource schema.
* @return the schema
* @deprecated as of 2.5.0 in favor of {@link Jdbc#getSchema()}
*/
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc.schema")
public String getSchema() {
return this.schema;
return this.jdbc.getSchema();
}
@Deprecated
public void setSchema(String schema) {
this.schema = schema;
this.jdbc.setSchema(schema);
}
/**
* Return the table prefix.
* @return the table prefix
* @deprecated as of 2.5.0 in favor of {@link Jdbc#getTablePrefix()}
*/
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc.table-prefix")
public String getTablePrefix() {
return this.tablePrefix;
return this.jdbc.getTablePrefix();
}
@Deprecated
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
this.jdbc.setTablePrefix(tablePrefix);
}
/**
* Return whether the schema should be initialized.
* @return the initialization mode
* @deprecated as of 2.5.0 in favor of {@link Jdbc#getInitializeSchema()}
*/
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.batch.jdbc.initialize-schema")
public DataSourceInitializationMode getInitializeSchema() {
return this.initializeSchema;
return this.jdbc.getInitializeSchema();
}
@Deprecated
public void setInitializeSchema(DataSourceInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
this.jdbc.setInitializeSchema(initializeSchema);
}
public Job getJob() {
return this.job;
}
public Jdbc getJdbc() {
return this.jdbc;
}
public static class Job {
/**
@@ -96,4 +110,50 @@ public class BatchProperties {
}
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;
}
}
}

View File

@@ -376,10 +376,14 @@
"type": "java.lang.Boolean",
"description": "Create the required batch tables on startup if necessary. Enabled automatically\n if no custom table prefix is set or if a custom schema is configured.",
"deprecation": {
"replacement": "spring.batch.initialize-schema",
"replacement": "spring.batch.jdbc.initialize-schema",
"level": "error"
}
},
{
"name": "spring.batch.jdbc.initialize-schema",
"defaultValue": "embedded"
},
{
"name": "spring.batch.job.enabled",
"type": "java.lang.Boolean",

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@@ -49,7 +49,9 @@ import org.springframework.boot.autoconfigure.orm.jpa.test.City;
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@@ -82,7 +84,7 @@ class BatchAutoConfigurationTests {
.run((context) -> {
assertThat(context).hasSingleBean(JobLauncher.class);
assertThat(context).hasSingleBean(JobExplorer.class);
assertThat(context.getBean(BatchProperties.class).getInitializeSchema())
assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema())
.isEqualTo(DataSourceInitializationMode.EMBEDDED);
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
.queryForList("select * from BATCH_JOB_EXECUTION")).isEmpty();
@@ -174,17 +176,30 @@ class BatchAutoConfigurationTests {
@Test
void testDisableSchemaLoader() {
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.jdbc.initialize-schema:never")
.run(assertDatasourceIsNotInitialized());
}
@Test
@Deprecated
void testDisableSchemaLoaderWithDeprecatedProperty() {
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.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"));
});
.run(assertDatasourceIsNotInitialized());
}
private ContextConsumer<AssertableApplicationContext> assertDatasourceIsNotInitialized() {
return (context) -> {
assertThat(context).hasSingleBean(JobLauncher.class);
assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema())
.isEqualTo(DataSourceInitializationMode.NEVER);
assertThatExceptionOfType(BadSqlGrammarException.class)
.isThrownBy(() -> new JdbcTemplate(context.getBean(DataSource.class))
.queryForList("select * from BATCH_JOB_EXECUTION"));
};
}
@Test
@@ -205,23 +220,39 @@ class BatchAutoConfigurationTests {
@Test
void testRenamePrefix() {
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(assertCustomTablePrefix());
}
@Test
@Deprecated
void testRenamePrefixWithDeprecatedProperty() {
this.contextRunner
.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class,
HibernateJpaAutoConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.schema:classpath:batch/custom-schema-hsql.sql",
"spring.batch.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();
});
.run(assertCustomTablePrefix());
}
private ContextConsumer<AssertableApplicationContext> assertCustomTablePrefix() {
return (context) -> {
assertThat(context).hasSingleBean(JobLauncher.class);
assertThat(context.getBean(BatchProperties.class).getJdbc().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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
@@ -31,7 +31,9 @@ import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfigurati
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
@@ -59,7 +61,7 @@ class BatchAutoConfigurationWithoutJpaTests {
assertThat(context).hasSingleBean(PlatformTransactionManager.class);
assertThat(context.getBean(PlatformTransactionManager.class).toString())
.contains("DataSourceTransactionManager");
assertThat(context.getBean(BatchProperties.class).getInitializeSchema())
assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema())
.isEqualTo(DataSourceInitializationMode.EMBEDDED);
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
.queryForList("select * from BATCH_JOB_EXECUTION")).isEmpty();
@@ -71,17 +73,30 @@ class BatchAutoConfigurationWithoutJpaTests {
@Test
void jdbcWithCustomPrefix() {
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(assertCustomPrefix());
}
@Test
@Deprecated
void jdbcWithCustomPrefixWithDeprecatedProperties() {
this.contextRunner.withUserConfiguration(DefaultConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.schema:classpath:batch/custom-schema-hsql.sql",
"spring.batch.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();
});
.run(assertCustomPrefix());
}
private ContextConsumer<AssertableApplicationContext> assertCustomPrefix() {
return (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

View File

@@ -2087,10 +2087,11 @@ You can also enable it for any database type, as shown in the following example:
----
spring:
batch:
initialize-schema: "always"
jdbc:
initialize-schema: "always"
----
You can also switch off the initialization explicitly by setting `spring.batch.initialize-schema` to `never`.
You can also switch off the initialization explicitly by setting `spring.batch.jdbc.initialize-schema` to `never`.