diff --git a/pom.xml b/pom.xml index 365805eb3..c98e5c7a5 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ 2.1.210 3.36.0.3 10.14.2.0 - 2.9.12 + 2.11.17 2.20.0 3.0.2 2.17.2 diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hana.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hana.sql index b9f43b412..7dd2a2fe3 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hana.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hana.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) , constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/sql/hana.properties b/spring-batch-core/src/main/sql/hana.properties deleted file mode 100644 index 313903c84..000000000 --- a/spring-batch-core/src/main/sql/hana.properties +++ /dev/null @@ -1,14 +0,0 @@ -platform=hana -# SQL language oddities -BIGINT = BIGINT -IDENTITY = -GENERATED = GENERATED BY DEFAULT AS IDENTITY -IFEXISTSBEFORE = -DOUBLE = DOUBLE -BLOB = BLOB -CLOB = CLOB -TIMESTAMP = TIMESTAMP -VARCHAR = VARCHAR -CHAR = VARCHAR -# for generating drop statements... -SEQUENCE = SEQUENCE diff --git a/spring-batch-core/src/main/sql/hana.vpp b/spring-batch-core/src/main/sql/hana.vpp deleted file mode 100644 index b57090345..000000000 --- a/spring-batch-core/src/main/sql/hana.vpp +++ /dev/null @@ -1,3 +0,0 @@ -#macro (sequence $name $value)CREATE SEQUENCE ${name} START WITH ${value} MINVALUE 0 NO CYCLE; -#end -#macro (notnull $name $type)ALTER (${name} ${type} NOT NULL)#end diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HANAContainer.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HANAContainer.java deleted file mode 100644 index 06fa8871a..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HANAContainer.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 java.time.Duration; -import java.time.temporal.ChronoUnit; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.testcontainers.containers.JdbcDatabaseContainer; -import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; -import org.testcontainers.utility.DockerImageName; -import org.testcontainers.utility.LicenseAcceptance; - -import com.github.dockerjava.api.model.Ulimit; - -/** - * @author Jonathan Bregler - */ -public class HANAContainer> extends JdbcDatabaseContainer { - - private static final Integer PORT = 39041; - - private static final String SYSTEM_USER = "SYSTEM"; - private static final String SYSTEM_USER_PASSWORD = "HXEHana1"; - - public HANAContainer(DockerImageName image) { - - super( image ); - - addExposedPorts( 39013, 39017, 39041, 39042, 39043, 39044, 39045, 1128, 1129, 59013, 59014 ); - - // create ulimits - Ulimit[] ulimits = new Ulimit[]{ new Ulimit( "nofile", 1048576L, 1048576L ) }; - - // create sysctls Map. - Map sysctls = new HashMap(); - - sysctls.put( "kernel.shmmax", "1073741824" ); - sysctls.put( "net.ipv4.ip_local_port_range", "40000 60999" ); - - // Apply mounts, ulimits and sysctls. - this.withCreateContainerCmdModifier( it -> it.getHostConfig().withUlimits( ulimits ).withSysctls( sysctls ) ); - - // Arguments for Image. - this.withCommand( "--master-password " + SYSTEM_USER_PASSWORD + " --agree-to-sap-license" ); - - // Determine if container is ready. - this.waitStrategy = new LogMessageWaitStrategy().withRegEx( ".*Startup finished!*\\s" ).withTimes( 1 ) - .withStartupTimeout( Duration.of( 600, ChronoUnit.SECONDS ) ); - } - - @Override - protected void configure() { - /* - * Enforce that the license is accepted - do not remove. License available at: - * https://www.sap.com/docs/download/cmp/2016/06/sap-hana-express-dev-agmt-and- exhibit.pdf - */ - - // If license was not accepted programmatically, check if it was accepted via - // resource file - if ( !getEnvMap().containsKey( "AGREE_TO_SAP_LICENSE" ) ) { - LicenseAcceptance.assertLicenseAccepted( this.getDockerImageName() ); - acceptLicense(); - } - } - - /** - * Accepts the license for the SAP HANA Express container by setting the AGREE_TO_SAP_LICENSE=Y Calling this method - * will automatically accept the license at: - * https://www.sap.com/docs/download/cmp/2016/06/sap-hana-express-dev-agmt-and-exhibit.pdf - * - * @return The container itself with an environment variable accepting the SAP HANA Express license - */ - public SELF acceptLicense() { - addEnv( "AGREE_TO_SAP_LICENSE", "Y" ); - return self(); - } - - @Override - protected Set getLivenessCheckPorts() { - return new HashSet<>( Arrays.asList( new Integer[]{ getMappedPort( PORT ) } ) ); - } - - @Override - protected void waitUntilContainerStarted() { - getWaitStrategy().waitUntilReady( this ); - } - - @Override - public String getDriverClassName() { - return "com.sap.db.jdbc.Driver"; - } - - @Override - public String getUsername() { - return SYSTEM_USER; - } - - @Override - public String getPassword() { - return SYSTEM_USER_PASSWORD; - } - - @Override - public String getTestQueryString() { - return "SELECT 1 FROM SYS.DUMMY"; - } - - @Override - public String getJdbcUrl() { - return "jdbc:sap://" + getContainerIpAddress() + ":" + getMappedPort( PORT ) + "/"; - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HANAJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HANAJobRepositoryIntegrationTests.java index 276aaf39d..038ffa168 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HANAJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HANAJobRepositoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2022 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. @@ -15,11 +15,21 @@ */ package org.springframework.batch.core.test.repository; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import javax.sql.DataSource; +import com.github.dockerjava.api.model.Ulimit; 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.springframework.batch.core.ExitStatus; @@ -38,19 +48,30 @@ 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.junit.jupiter.EnabledIf; import org.springframework.test.context.junit4.SpringRunner; + +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; import org.testcontainers.utility.DockerImageName; import com.sap.db.jdbcext.HanaDataSource; +import org.testcontainers.utility.LicenseAcceptance; /** + * The official Docker image for SAP HANA is not publicly available. SAP HANA support is tested manually. + * See https://hub.docker.com/_/sap-hana-express-edition/plans/f2dc436a-d851-4c22-a2ba-9de07db7a9ac + * FTR, from the previous link: "This installation does not support Docker for Windows or Docker for Mac." + * * @author Jonathan Bregler + * @author Mahmoud Ben Hassine */ @RunWith(SpringRunner.class) @ContextConfiguration +@Ignore("Official Docker image for SAP HANA not publicly available and works only on Linux") public class HANAJobRepositoryIntegrationTests { - private static final DockerImageName HANA_IMAGE = DockerImageName.parse( "store/saplabs/hanaexpress:2.00.054.00.20210603.1" ); + private static final DockerImageName HANA_IMAGE = DockerImageName.parse( "store/saplabs/hanaexpress:2.00.057.00.20211207.1" ); @ClassRule public static HANAContainer hana = new HANAContainer<>( HANA_IMAGE ).acceptLicense(); @@ -103,4 +124,103 @@ public class HANAJobRepositoryIntegrationTests { } } + + /** + * @author Jonathan Bregler + */ + public static class HANAContainer> extends JdbcDatabaseContainer { + + private static final Integer PORT = 39041; + + private static final String SYSTEM_USER = "SYSTEM"; + private static final String SYSTEM_USER_PASSWORD = "HXEHana1"; + + public HANAContainer(DockerImageName image) { + + super( image ); + + addExposedPorts( 39013, 39017, 39041, 39042, 39043, 39044, 39045, 1128, 1129, 59013, 59014 ); + + // create ulimits + Ulimit[] ulimits = new Ulimit[]{ new Ulimit( "nofile", 1048576L, 1048576L ) }; + + // create sysctls Map. + Map sysctls = new HashMap(); + + sysctls.put( "kernel.shmmax", "1073741824" ); + sysctls.put( "net.ipv4.ip_local_port_range", "40000 60999" ); + + // Apply mounts, ulimits and sysctls. + this.withCreateContainerCmdModifier( it -> it.getHostConfig().withUlimits( ulimits ).withSysctls( sysctls ) ); + + // Arguments for Image. + this.withCommand( "--master-password " + SYSTEM_USER_PASSWORD + " --agree-to-sap-license" ); + + // Determine if container is ready. + this.waitStrategy = new LogMessageWaitStrategy().withRegEx( ".*Startup finished!*\\s" ).withTimes( 1 ) + .withStartupTimeout( Duration.of( 600, ChronoUnit.SECONDS ) ); + } + + @Override + protected void configure() { + /* + * Enforce that the license is accepted - do not remove. License available at: + * https://www.sap.com/docs/download/cmp/2016/06/sap-hana-express-dev-agmt-and-exhibit.pdf + */ + + // If license was not accepted programmatically, check if it was accepted via + // resource file + if ( !getEnvMap().containsKey( "AGREE_TO_SAP_LICENSE" ) ) { + LicenseAcceptance.assertLicenseAccepted( this.getDockerImageName() ); + acceptLicense(); + } + } + + /** + * Accepts the license for the SAP HANA Express container by setting the AGREE_TO_SAP_LICENSE=Y Calling this method + * will automatically accept the license at: + * https://www.sap.com/docs/download/cmp/2016/06/sap-hana-express-dev-agmt-and-exhibit.pdf + * + * @return The container itself with an environment variable accepting the SAP HANA Express license + */ + public SELF acceptLicense() { + addEnv( "AGREE_TO_SAP_LICENSE", "Y" ); + return self(); + } + + @Override + public Set getLivenessCheckPortNumbers() { + return new HashSet<>( Arrays.asList( new Integer[]{ getMappedPort( PORT ) } ) ); + } + + @Override + protected void waitUntilContainerStarted() { + getWaitStrategy().waitUntilReady( this ); + } + + @Override + public String getDriverClassName() { + return "com.sap.db.jdbc.Driver"; + } + + @Override + public String getUsername() { + return SYSTEM_USER; + } + + @Override + public String getPassword() { + return SYSTEM_USER_PASSWORD; + } + + @Override + public String getTestQueryString() { + return "SELECT 1 FROM SYS.DUMMY"; + } + + @Override + public String getJdbcUrl() { + return "jdbc:sap://" + getContainerIpAddress() + ":" + getMappedPort( PORT ) + "/"; + } + } } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JdbcPagingItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JdbcPagingItemReaderBuilder.java index f16f2be8c..2dec50fb1 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JdbcPagingItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JdbcPagingItemReaderBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2020 the original author or authors. + * Copyright 2017-2022 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. diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java index 9e5bdb18a..a4e2e9459 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2021 the original author or authors. + * Copyright 2006-2022 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. diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/HanaPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/HanaPagingQueryProvider.java index eabae383c..98d7b5201 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/HanaPagingQueryProvider.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/HanaPagingQueryProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 the original author or authors. + * Copyright 2022 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. @@ -23,7 +23,7 @@ import org.springframework.util.StringUtils; * SAP HANA implementation of a {@link PagingQueryProvider} using database specific features. * * @author Jonathan Bregler - * @since 4.0 + * @since 5.0 */ public class HanaPagingQueryProvider extends AbstractSqlPagingQueryProvider { @@ -35,7 +35,7 @@ public class HanaPagingQueryProvider extends AbstractSqlPagingQueryProvider { @Override public String generateRemainingPagesQuery(int pageSize) { if(StringUtils.hasText(getGroupClause())) { - return SqlPagingQueryUtils.generateLimitGroupedSqlQuery(this, true, buildLimitClause(pageSize)); + return SqlPagingQueryUtils.generateLimitGroupedSqlQuery(this, buildLimitClause(pageSize)); } else { return SqlPagingQueryUtils.generateLimitSqlQuery(this, true, buildLimitClause(pageSize)); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java index 6c29b3754..b1100f6f4 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 the original author or authors. + * Copyright 2006-2022 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. diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java index bec64dec7..0033efd73 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2021 the original author or authors. + * Copyright 2006-2022 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. diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java index 96454ab82..96604f412 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2021 the original author or authors. + * Copyright 2006-2022 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. diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HanaPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HanaPagingQueryProviderTests.java index 5f1b836e9..63ab3f6be 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HanaPagingQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HanaPagingQueryProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 the original author or authors. + * Copyright 2022 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. @@ -26,7 +26,7 @@ import static org.junit.Assert.assertEquals; /** * @author Jonathan Bregler - * @since 4.0 + * @since 5.0 */ public class HanaPagingQueryProviderTests extends AbstractSqlPagingQueryProviderTests { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java index c34f069c9..ad563a434 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2018 the original author or authors. + * Copyright 2008-2022 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. diff --git a/spring-batch-samples/src/main/sql/hana.vpp b/spring-batch-samples/src/main/sql/hana.vpp deleted file mode 100644 index cf8238a41..000000000 --- a/spring-batch-samples/src/main/sql/hana.vpp +++ /dev/null @@ -1,2 +0,0 @@ -#macro (sequence $name $value)CREATE SEQUENCE ${name} START WITH ${value} MINVALUE 0; -#end