From c7b5b01a41d44d43dca4e4122dd9a176a0b26835 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Sat, 18 Feb 2023 04:46:47 +0100 Subject: [PATCH] Fix inconsistent state validation rules in RepositoryItemReader Before this commit, state validation rules in RepositoryItemReader were not consistent with those applied in its builder. This commit makes validation rules consistent between the two ways of creating a RepositoryItemReader. This commit also adds a getter for the component name in ExecutionContextUserSupport to be able to assert on it where appropriate down the hierarchy. Resolves #4276 --- .../batch/item/ItemStreamSupport.java | 11 ++++++++++- .../batch/item/data/RepositoryItemReader.java | 8 +++++++- .../builder/RepositoryItemReaderBuilder.java | 5 +++-- .../item/util/ExecutionContextUserSupport.java | 5 +++-- .../item/data/RepositoryItemReaderTests.java | 12 ++++++++++++ .../RepositoryItemReaderBuilderTests.java | 18 ++++++++++++++++++ 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java index 87cf48557..b0003d3c0 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2023 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. @@ -22,6 +22,7 @@ import org.springframework.batch.item.util.ExecutionContextUserSupport; * * @author Dave Syer * @author Dean de Bree + * @author Mahmoud Ben Hassine * */ public abstract class ItemStreamSupport implements ItemStream { @@ -63,6 +64,14 @@ public abstract class ItemStreamSupport implements ItemStream { this.setExecutionContextName(name); } + /** + * Get the name of the component + * @return the name of the component + */ + public String getName() { + return executionContextUserSupport.getName(); + } + protected void setExecutionContextName(String name) { executionContextUserSupport.setName(name); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java index a6f9dee1b..b09c48f82 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java @@ -37,6 +37,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.MethodInvoker; +import org.springframework.util.StringUtils; /** *

@@ -72,6 +73,7 @@ import org.springframework.util.MethodInvoker; * * @author Michael Minella * @author Antoine Kapps + * @author Mahmoud Ben Hassine * @since 2.2 */ public class RepositoryItemReader extends AbstractItemCountingItemStreamItemReader implements InitializingBean { @@ -119,7 +121,7 @@ public class RepositoryItemReader extends AbstractItemCountingItemStreamItemR } /** - * @param pageSize The number of items to retrieve per page. + * @param pageSize The number of items to retrieve per page. Must be greater than 0. */ public void setPageSize(int pageSize) { this.pageSize = pageSize; @@ -150,6 +152,10 @@ public class RepositoryItemReader extends AbstractItemCountingItemStreamItemR Assert.state(repository != null, "A PagingAndSortingRepository is required"); Assert.state(pageSize > 0, "Page size must be greater than 0"); Assert.state(sort != null, "A sort is required"); + Assert.state(this.methodName != null && !this.methodName.isEmpty(), "methodName is required."); + if (isSaveState()) { + Assert.state(StringUtils.hasText(getName()), "A name is required when saveState is set to true."); + } } @Nullable diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java index aa9e245fe..09b95953a 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 the original author or authors. + * Copyright 2017-2023 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. @@ -158,7 +158,7 @@ public class RepositoryItemReaderBuilder { /** * Establish the pageSize for the generated RepositoryItemReader. * - * @param pageSize The number of items to retrieve per page. + * @param pageSize The number of items to retrieve per page. Must be greater than 0. * @return The current instance of the builder. * @see RepositoryItemReader#setPageSize(int) */ @@ -236,6 +236,7 @@ public class RepositoryItemReaderBuilder { Assert.notNull(this.sorts, "sorts map is required."); Assert.notNull(this.repository, "repository is required."); + Assert.isTrue(this.pageSize > 0, "Page size must be greater than 0"); Assert.hasText(this.methodName, "methodName is required."); if (this.saveState) { Assert.state(StringUtils.hasText(this.name), "A name is required when saveState is set to true."); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java index 1b3365f4c..7951eb2d0 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007 the original author or authors. + * Copyright 2006-2023 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,6 +23,7 @@ import org.springframework.util.Assert; * {@link ExecutionContext} based on the name. * * @author Robert Kasanicky + * @author Mahmoud Ben Hassine */ public class ExecutionContextUserSupport { @@ -40,7 +41,7 @@ public class ExecutionContextUserSupport { /** * @return name used to uniquely identify this instance's entries in shared context. */ - protected String getName() { + public String getName() { return this.name; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java index eca4a83e3..899e918de 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java @@ -108,10 +108,22 @@ public class RepositoryItemReaderTests { // expected } + try { + reader = new RepositoryItemReader<>(); + reader.setRepository(repository); + reader.setPageSize(1); + reader.setSort(sorts); + reader.afterPropertiesSet(); + fail(); + } catch (IllegalStateException iae) { + // expected + } + reader = new RepositoryItemReader<>(); reader.setRepository(repository); reader.setPageSize(1); reader.setSort(sorts); + reader.setMethodName("findAll"); reader.afterPropertiesSet(); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java index b2806bcc0..ab408f9d1 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java @@ -41,6 +41,7 @@ import static org.mockito.Mockito.when; /** * @author Glenn Renfro * @author Drummond Dawson + * @author Mahmoud Ben Hassine */ public class RepositoryItemReaderBuilderTests { @@ -234,6 +235,23 @@ public class RepositoryItemReaderBuilderTests { } } + @Test + public void testInvalidPageSize() { + try { + new RepositoryItemReaderBuilder<>() + .repository(repository) + .sorts(this.sorts) + .pageSize(-1) + .build(); + + fail("IllegalArgumentException should have been thrown"); + } + catch (IllegalArgumentException iae) { + assertEquals("IllegalArgumentException message did not match the expected result.", + "Page size must be greater than 0", iae.getMessage()); + } + } + @Test public void testArguments() throws Exception { List args = new ArrayList<>(3);