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
This commit is contained in:
Mahmoud Ben Hassine
2023-02-18 04:46:47 +01:00
parent 669768365f
commit c7b5b01a41
6 changed files with 53 additions and 6 deletions

View File

@@ -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);
}

View File

@@ -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;
/**
* <p>
@@ -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<T> extends AbstractItemCountingItemStreamItemReader<T> implements InitializingBean {
@@ -119,7 +121,7 @@ public class RepositoryItemReader<T> 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<T> 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

View File

@@ -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<T> {
/**
* 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<T> {
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.");

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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<String> args = new ArrayList<>(3);