diff --git a/pom.xml b/pom.xml index 1613c9093..0b20365fc 100644 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,11 @@ 6.2.5 1.9.6 8.0.23 + 42.2.22 + 11.5.6.0 + 21.1.0.0 + 9.2.1.jre8 + 1.3.1 1.15.3 1.0 1 diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index 9301c44fe..8c93fc5c4 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -112,6 +112,66 @@ ${testcontainers.version} test + + org.postgresql + postgresql + ${postgresql.version} + test + + + org.testcontainers + postgresql + ${testcontainers.version} + test + + + com.ibm.db2 + jcc + ${db2.version} + test + + + org.testcontainers + db2 + ${testcontainers.version} + test + + + org.testcontainers + oracle-xe + ${testcontainers.version} + test + + + com.oracle.database.jdbc + ojdbc8 + ${oracle.version} + test + + + org.testcontainers + mssqlserver + ${testcontainers.version} + test + + + com.microsoft.sqlserver + mssql-jdbc + ${sqlserver.version} + test + + + net.sourceforge.jtds + jtds + ${jtds.version} + test + + + org.xerial + sqlite-jdbc + ${sqlite.version} + test + com.h2database h2 diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/Db2JobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/Db2JobRepositoryIntegrationTests.java new file mode 100644 index 000000000..9a1fd5f72 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/Db2JobRepositoryIntegrationTests.java @@ -0,0 +1,114 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import com.ibm.db2.jcc.DB2SimpleDataSource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.testcontainers.containers.Db2Container; +import org.testcontainers.utility.DockerImageName; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class Db2JobRepositoryIntegrationTests { + + // TODO find the best way to externalize and manage image versions + private static final DockerImageName DB2_IMAGE = DockerImageName.parse("ibmcom/db2:11.5.5.1"); + + @ClassRule + public static Db2Container db2 = new Db2Container(DB2_IMAGE).acceptLicense(); + + @Autowired + private DataSource dataSource; + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Before + public void setUp() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScript(new ClassPathResource("/org/springframework/batch/core/schema-db2.sql")); + databasePopulator.execute(this.dataSource); + } + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() throws Exception { + DB2SimpleDataSource dataSource =new DB2SimpleDataSource(); + dataSource.setDatabaseName(db2.getDatabaseName()); + dataSource.setUser(db2.getUsername()); + dataSource.setPassword(db2.getPassword()); + dataSource.setDriverType(4); + dataSource.setServerName(db2.getContainerIpAddress()); + dataSource.setPortNumber(db2.getMappedPort(Db2Container.DB2_PORT)); + dataSource.setSslConnection(false); + return dataSource; + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/DerbyJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/DerbyJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..feede6f27 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/DerbyJobRepositoryIntegrationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class DerbyJobRepositoryIntegrationTests { + + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.DERBY) + .addScript("/org/springframework/batch/core/schema-derby.sql") + .generateUniqueName(true) + .build(); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2JobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2JobRepositoryIntegrationTests.java new file mode 100644 index 000000000..cfac294fb --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2JobRepositoryIntegrationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class H2JobRepositoryIntegrationTests { + + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("/org/springframework/batch/core/schema-h2.sql") + .generateUniqueName(true) + .build(); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HSQLDBJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HSQLDBJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..2c3e376b0 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HSQLDBJobRepositoryIntegrationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class HSQLDBJobRepositoryIntegrationTests { + + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.HSQL) + .addScript("/org/springframework/batch/core/schema-hsqldb.sql") + .generateUniqueName(true) + .build(); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..c1b687b43 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJobRepositoryIntegrationTests.java @@ -0,0 +1,111 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import com.mysql.cj.jdbc.MysqlDataSource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.utility.DockerImageName; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class MySQLJobRepositoryIntegrationTests { + + // TODO find the best way to externalize and manage image versions + private static final DockerImageName MYSQL_IMAGE = DockerImageName.parse("mysql:8.0.25"); + + @ClassRule + public static MySQLContainer mysql = new MySQLContainer<>(MYSQL_IMAGE); + + @Autowired + private DataSource dataSource; + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Before + public void setUp() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScript(new ClassPathResource("/org/springframework/batch/core/schema-mysql.sql")); + databasePopulator.execute(this.dataSource); + } + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() throws Exception { + MysqlDataSource datasource = new MysqlDataSource(); + datasource.setURL(mysql.getJdbcUrl()); + datasource.setUser(mysql.getUsername()); + datasource.setPassword(mysql.getPassword()); + datasource.setUseSSL(false); + return datasource; + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/OracleJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/OracleJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..09e3cfc94 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/OracleJobRepositoryIntegrationTests.java @@ -0,0 +1,118 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import oracle.jdbc.pool.OracleDataSource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.testcontainers.containers.OracleContainer; +import org.testcontainers.utility.DockerImageName; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Official Docker images for Oracle are not publicly available. Oracle support is tested semi-manually for the moment: + * 1. Build a docker image for oracle/database:11.2.0.2-xe: https://github.com/oracle/docker-images/tree/main/OracleDatabase/SingleInstance#running-oracle-database-11gr2-express-edition-in-a-container + * 2. Run the test `testJobExecution` + * + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +@Ignore("Official Docker images for Oracle are not publicly available") +public class OracleJobRepositoryIntegrationTests { + + // TODO find the best way to externalize and manage image versions + private static final DockerImageName ORACLE_IMAGE = DockerImageName.parse("oracle/database:11.2.0.2-xe"); + + @ClassRule + public static OracleContainer oracle = new OracleContainer(ORACLE_IMAGE); + + @Autowired + private DataSource dataSource; + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Before + public void setUp() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScript(new ClassPathResource("/org/springframework/batch/core/schema-oracle10g.sql")); + databasePopulator.execute(this.dataSource); + } + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() throws Exception { + OracleDataSource oracleDataSource = new OracleDataSource(); + oracleDataSource.setUser(oracle.getUsername()); + oracleDataSource.setPassword(oracle.getPassword()); + oracleDataSource.setDatabaseName(oracle.getDatabaseName()); + oracleDataSource.setServerName(oracle.getContainerIpAddress()); + oracleDataSource.setPortNumber(oracle.getOraclePort()); + return oracleDataSource; + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/PostgreSQLJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/PostgreSQLJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..e2c5f0ff8 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/PostgreSQLJobRepositoryIntegrationTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.postgresql.ds.PGSimpleDataSource; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.utility.DockerImageName; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class PostgreSQLJobRepositoryIntegrationTests { + + // TODO find the best way to externalize and manage image versions + private static final DockerImageName POSTGRESQL_IMAGE = DockerImageName.parse("postgres:13.3"); + + @ClassRule + public static PostgreSQLContainer postgres = new PostgreSQLContainer<>(POSTGRESQL_IMAGE); + + @Autowired + private DataSource dataSource; + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Before + public void setUp() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScript(new ClassPathResource("/org/springframework/batch/core/schema-postgresql.sql")); + databasePopulator.execute(this.dataSource); + } + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() throws Exception { + PGSimpleDataSource datasource = new PGSimpleDataSource(); + datasource.setURL(postgres.getJdbcUrl()); + datasource.setUser(postgres.getUsername()); + datasource.setPassword(postgres.getPassword()); + return datasource; + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLServerJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLServerJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..37800699d --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLServerJobRepositoryIntegrationTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import com.microsoft.sqlserver.jdbc.SQLServerDataSource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.testcontainers.containers.MSSQLServerContainer; +import org.testcontainers.utility.DockerImageName; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class SQLServerJobRepositoryIntegrationTests { + + // TODO find the best way to externalize and manage image versions + private static final DockerImageName SQLSERVER_IMAGE = DockerImageName.parse("mcr.microsoft.com/mssql/server:2019-CU11-ubuntu-20.04"); + + @ClassRule + public static MSSQLServerContainer sqlserver = new MSSQLServerContainer<>(SQLSERVER_IMAGE).acceptLicense(); + + @Autowired + private DataSource dataSource; + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Before + public void setUp() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScript(new ClassPathResource("/org/springframework/batch/core/schema-sqlserver.sql")); + databasePopulator.execute(this.dataSource); + } + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() throws Exception { + SQLServerDataSource dataSource = new SQLServerDataSource(); + dataSource.setUser(sqlserver.getUsername()); + dataSource.setPassword(sqlserver.getPassword()); + dataSource.setURL(sqlserver.getJdbcUrl()); + return dataSource; + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLiteJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLiteJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..775f53461 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLiteJobRepositoryIntegrationTests.java @@ -0,0 +1,92 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.sqlite.SQLiteDataSource; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class SQLiteJobRepositoryIntegrationTests { + + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + @Bean + public DataSource dataSource() { + SQLiteDataSource dataSource = new SQLiteDataSource(); + dataSource.setUrl("jdbc:sqlite:target/spring-batch.sqlite"); + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScript(new ClassPathResource("/org/springframework/batch/core/schema-sqlite.sql")); + databasePopulator.execute(dataSource); + return dataSource; + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SybaseJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SybaseJobRepositoryIntegrationTests.java new file mode 100644 index 000000000..1839e6bfc --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SybaseJobRepositoryIntegrationTests.java @@ -0,0 +1,113 @@ +/* + * Copyright 2020-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. + * 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.batch.core.test.repository; + +import javax.sql.DataSource; + +import net.sourceforge.jtds.jdbcx.JtdsDataSource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * The Sybase official jdbc driver is not freely available. This test uses the non-official jTDS driver. + * There is no official public Docker image for Sybase neither. This test uses the non-official Docker image by Jetbrains. + * Sybase in not supported in testcontainers. Sysbase support is tested manually for the moment: + * 1. Run `docker run -d -t -p 5000:5000 -eSYBASE_USER=sa -eSYBASE_PASSWORD=sa -eSYBASE_DB=test datagrip/sybase:16.0` + * 2. Update the datasource configuration with the IP of the container + * 3. Run the test `testJobExecution` + * + * @author Mahmoud Ben Hassine + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +@Ignore("No support for Sybase in testcontainers") +public class SybaseJobRepositoryIntegrationTests { + + @Autowired + private DataSource dataSource; + @Autowired + private JobLauncher jobLauncher; + @Autowired + private Job job; + + @Before + public void setUp() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScript(new ClassPathResource("/org/springframework/batch/core/schema-sybase.sql")); + databasePopulator.execute(this.dataSource); + } + + @Test + public void testJobExecution() throws Exception { + // given + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters); + + // then + Assert.assertNotNull(jobExecution); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Configuration + @EnableBatchProcessing + static class TestConfiguration { + + // FIXME Configuration parameters are hard-coded for the moment, to update once testcontainers support is available + @Bean + public DataSource dataSource() throws Exception { + JtdsDataSource dataSource = new JtdsDataSource(); + dataSource.setUser("sa"); + dataSource.setPassword("sa"); + dataSource.setServerName("172.17.0.2"); + dataSource.setPortNumber(5000); + dataSource.setDatabaseName("test"); + return dataSource; + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + return jobs.get("job") + .start(steps.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .build()) + .build(); + } + + } +}