From 40867f30868a07c263d5c8118c7525f2e39f2f4a Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Wed, 6 Nov 2024 15:31:17 +0100 Subject: [PATCH 1/2] #10115 - fixed GmlLoader configuration (migration to spring boot 5) --- .../loader/GmlLoaderConfiguration.java | 44 ++++++++++++------- .../loader/GmlLoaderConfigurationTest.java | 19 ++++++++ 2 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfigurationTest.java diff --git a/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfiguration.java b/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfiguration.java index 7be5a00b60..b6e6f1f818 100644 --- a/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfiguration.java +++ b/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfiguration.java @@ -32,21 +32,25 @@ import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecutionListener; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.JobScope; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.step.builder.SimpleStepBuilder; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.file.MultiResourceItemReader; import org.springframework.batch.item.support.AbstractItemStreamItemReader; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.PathResource; import org.springframework.core.io.Resource; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.transaction.PlatformTransactionManager; import java.io.IOException; import java.nio.file.Files; @@ -59,6 +63,8 @@ import static org.slf4j.LoggerFactory.getLogger; +import javax.sql.DataSource; + /** * Configuration of the GMLLoader. * @@ -71,12 +77,6 @@ public class GmlLoaderConfiguration { private static final Logger LOG = getLogger(GmlLoaderConfiguration.class); - @Autowired - private JobBuilderFactory jobBuilderFactory; - - @Autowired - private StepBuilderFactory stepBuilderFactory; - @JobScope @Bean public Summary summary(@Value("#{jobParameters[reportWriteStatistics] ?: false}") boolean reportWriteStatistics) { @@ -192,13 +192,14 @@ public StepExecutionListener referenceCheckListener(SQLFeatureStore sqlFeatureSt @JobScope @Bean - public Step step(StepExecutionListener referenceCheckListener, AbstractItemStreamItemReader gmlReader, + public Step step(JobRepository jobRepository, PlatformTransactionManager transactionManager, + StepExecutionListener referenceCheckListener, AbstractItemStreamItemReader gmlReader, FeatureReferencesParser featureReferencesParser, ItemWriter featureStoreWriter, @Value("#{jobParameters['chunkSize']}") Integer chunkSize, @Value("#{jobParameters['skipReferenceCheck'] ?: false}") boolean skipReferenceCheck) { int chunk = chunkSize != null && chunkSize.intValue() > 10 ? chunkSize.intValue() : 10; - SimpleStepBuilder builder = stepBuilderFactory.get("gmlLoaderStep") - .chunk(chunk); + SimpleStepBuilder builder = new StepBuilder("gmlLoaderStep", jobRepository) + .chunk(chunk, transactionManager); builder.reader(gmlReader); if (skipReferenceCheck) { LOG.warn("The feature reference check will be skipped."); @@ -210,14 +211,27 @@ public Step step(StepExecutionListener referenceCheckListener, AbstractItemStrea } @Bean - public Job job(Step step, ReportWriter reportWriter) { - return jobBuilderFactory.get("gmlLoaderJob") - .incrementer(new RunIdIncrementer()) + public Job job(JobRepository jobRepository, Step step, ReportWriter reportWriter) { + return new JobBuilder("gmlLoaderJob", jobRepository).incrementer(new RunIdIncrementer()) .start(step) .listener(reportWriter) .build(); } + @Bean + public DataSource dataSource() { + EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder(); + return embeddedDatabaseBuilder.addScript("classpath:org/springframework/batch/core/schema-drop-h2.sql") + .addScript("classpath:org/springframework/batch/core/schema-h2.sql") + .setType(EmbeddedDatabaseType.H2) + .build(); + } + + @Bean + public ResourcelessTransactionManager transactionManager() { + return new ResourcelessTransactionManager(); + } + private List parseDisabledResources(String disabledResources) { List patterns = new ArrayList<>(); if (disabledResources != null) { diff --git a/deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfigurationTest.java b/deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfigurationTest.java new file mode 100644 index 0000000000..c24106342b --- /dev/null +++ b/deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/GmlLoaderConfigurationTest.java @@ -0,0 +1,19 @@ +package org.deegree.tools.featurestoresql.loader; + +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +/** + * @author Lyn Goltz + */ +public class GmlLoaderConfigurationTest { + + @Test + public void testLoadApplicationContextAndInitializeBeans() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + context.register(GmlLoaderConfiguration.class); + context.refresh(); + context.close(); + } + +} From 5c32ee48127178714702179591b6196b929047f5 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 7 Nov 2024 06:43:03 +0100 Subject: [PATCH 2/2] #1760 - fixed date formatting --- deegree-tools/deegree-tools-gml/pom.xml | 5 +++ .../featurestoresql/loader/ReportWriter.java | 8 ++-- .../loader/ReportWriterTest.java | 40 +++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/ReportWriterTest.java diff --git a/deegree-tools/deegree-tools-gml/pom.xml b/deegree-tools/deegree-tools-gml/pom.xml index bc8595a4d7..9291451f51 100755 --- a/deegree-tools/deegree-tools-gml/pom.xml +++ b/deegree-tools/deegree-tools-gml/pom.xml @@ -224,6 +224,11 @@ ${spring-batch.version} test + + org.mockito + mockito-core + test + diff --git a/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/ReportWriter.java b/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/ReportWriter.java index f25cb2aca6..78f8b2e942 100644 --- a/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/ReportWriter.java +++ b/deegree-tools/deegree-tools-gml/src/main/java/org/deegree/tools/featurestoresql/loader/ReportWriter.java @@ -32,7 +32,9 @@ import java.io.PrintWriter; import java.nio.file.Path; import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.Collection; @@ -51,7 +53,7 @@ public class ReportWriter extends JobExecutionListenerSupport { private static final Logger LOG = getLogger(ReportWriter.class); - private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); + private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss"); private final Summary summary; @@ -134,13 +136,13 @@ private String getTimeNeeded(StepExecution stepExecution) { private String getStartTime(StepExecution stepExecution) { if (stepExecution != null && stepExecution.getStartTime() != null) - return DATE_FORMAT.format(stepExecution.getStartTime()); + return stepExecution.getStartTime().format(DATE_FORMAT); return "UNKNOWN"; } private String getEndTime(StepExecution stepExecution) { if (stepExecution != null && stepExecution.getEndTime() != null) - return DATE_FORMAT.format(stepExecution.getEndTime()); + return stepExecution.getEndTime().format(DATE_FORMAT); return "UNKNOWN"; } diff --git a/deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/ReportWriterTest.java b/deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/ReportWriterTest.java new file mode 100644 index 0000000000..5823ae953b --- /dev/null +++ b/deegree-tools/deegree-tools-gml/src/test/java/org/deegree/tools/featurestoresql/loader/ReportWriterTest.java @@ -0,0 +1,40 @@ +package org.deegree.tools.featurestoresql.loader; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.Collections; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.StepExecution; + +/** + * @author Lyn Goltz + */ +public class ReportWriterTest { + + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + + @Test + public void test() throws IOException { + Summary summary = new Summary(); + ReportWriter reportWriter = new ReportWriter(summary, tmpFolder.newFile().toPath()); + + JobExecution jobExecution = mock(JobExecution.class); + StepExecution stepExecution = mock(StepExecution.class); + when(jobExecution.getStepExecutions()).thenReturn(Collections.singletonList(stepExecution)); + when(stepExecution.getStartTime()).thenReturn(LocalDateTime.now().minusDays(1)); + when(stepExecution.getEndTime()).thenReturn(LocalDateTime.now().minusDays(1)); + when(stepExecution.getExitStatus()).thenReturn(ExitStatus.COMPLETED); + + reportWriter.afterJob(jobExecution); + } + +}