diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java index 742d076f5..c49f2d38e 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2020 the original author or authors. + * Copyright 2006-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. @@ -250,22 +250,6 @@ public class JobExecution extends Entity { return status == BatchStatus.STOPPING; } - /** - * Signal the {@link JobExecution} to stop. Iterates through the associated - * {@link StepExecution}s, calling {@link StepExecution#setTerminateOnly()}. - * - * @deprecated Use {@link org.springframework.batch.core.launch.JobOperator#stop(long)} - * or {@link org.springframework.batch.core.launch.support.CommandLineJobRunner} - * with the "-stop" option instead. - */ - @Deprecated - public void stop() { - for (StepExecution stepExecution : stepExecutions) { - stepExecution.setTerminateOnly(); - } - status = BatchStatus.STOPPING; - } - /** * Sets the {@link ExecutionContext} for this execution * diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java index 94a797397..bde6eea91 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java @@ -70,27 +70,6 @@ public class JobParameters implements Serializable { return value==null ? null : ((Long)value).longValue(); } - /** - * Typesafe Getter for the Long represented by the provided key. If the - * key does not exist, the default value will be returned. - * - * @param key to return the value for - * @param defaultValue to return if the value doesn't exist - * @return the parameter represented by the provided key, defaultValue - * otherwise. - * @deprecated Use {@link JobParameters#getLong(java.lang.String, java.lang.Long)} - * instead. This method will be removed in a future release. - */ - @Deprecated - public Long getLong(String key, long defaultValue){ - if(parameters.containsKey(key)){ - return getLong(key); - } - else{ - return defaultValue; - } - } - /** * Typesafe Getter for the Long represented by the provided key. If the * key does not exist, the default value will be returned. @@ -156,27 +135,6 @@ public class JobParameters implements Serializable { return value==null ? null : value.doubleValue(); } - /** - * Typesafe Getter for the Double represented by the provided key. If the - * key does not exist, the default value will be returned. - * - * @param key to return the value for - * @param defaultValue to return if the value doesn't exist - * @return the parameter represented by the provided key, defaultValue - * otherwise. - * @deprecated Use {@link JobParameters#getDouble(java.lang.String, java.lang.Double)} - * instead. This method will be removed in a future release. - */ - @Deprecated - public Double getDouble(String key, double defaultValue){ - if(parameters.containsKey(key)){ - return getDouble(key); - } - else{ - return defaultValue; - } - } - /** * Typesafe Getter for the Double represented by the provided key. If the * key does not exist, the default value will be returned. diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextFactory.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextFactory.java deleted file mode 100644 index 1c60796db..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2006-2007 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.configuration.support; - -import org.springframework.context.ApplicationContext; -import org.springframework.core.io.Resource; - -/** - * {@link ApplicationContextFactory} implementation that takes a parent context - * and a path to the context to create. When createApplicationContext method is - * called, the child {@link ApplicationContext} will be returned. The child - * context is not re-created every time it is requested, it is lazily - * initialized and cached. Clients should ensure that it is closed when it is no - * longer needed. If a path is not set, the parent will always be returned. - * - * @deprecated use {@link GenericApplicationContextFactory} instead - */ -@Deprecated -public class ClassPathXmlApplicationContextFactory extends GenericApplicationContextFactory { - - /** - * Create an application context factory for the resource specified. - * - * @param resource a resource (XML configuration file) - */ - public ClassPathXmlApplicationContextFactory(Resource resource) { - super(resource); - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/ClassPathXmlJobRegistry.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/ClassPathXmlJobRegistry.java deleted file mode 100644 index 6e6befb60..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/ClassPathXmlJobRegistry.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2008-2010 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.configuration.support; - -/** - * Placeholder for deprecation warning. - * - * @author Dave Syer - * - * @deprecated in version 2.1, please us {@link AutomaticJobRegistrar} instead - */ -@Deprecated -public abstract class ClassPathXmlJobRegistry { - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/ScheduledJobParametersFactory.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/ScheduledJobParametersFactory.java deleted file mode 100644 index 2e1d2bb93..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/ScheduledJobParametersFactory.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2006-2020 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.launch.support; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import org.springframework.batch.core.JobParameter; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.converter.JobParametersConverter; -import org.springframework.lang.Nullable; - -/** - * @author Lucas Ward - * @author Mahmoud Ben Hassine - * - * @deprecated as of v4.3 in favor of - * {@link org.springframework.batch.core.converter.DefaultJobParametersConverter} - * and scheduled for removal in v5.0. - */ -@Deprecated -public class ScheduledJobParametersFactory implements JobParametersConverter { - - public static final String SCHEDULE_DATE_KEY = "schedule.date"; - - private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); - - /* - * (non-Javadoc) - * - * @see org.springframework.batch.core.runtime.JobParametersFactory#getJobParameters(java.util.Properties) - */ - @Override - public JobParameters getJobParameters(@Nullable Properties props) { - - if (props == null || props.isEmpty()) { - return new JobParameters(); - } - - JobParametersBuilder propertiesBuilder = new JobParametersBuilder(); - - for (Entry entry : props.entrySet()) { - if (entry.getKey().equals(SCHEDULE_DATE_KEY)) { - Date scheduleDate; - try { - scheduleDate = dateFormat.parse(entry.getValue().toString()); - } catch (ParseException ex) { - throw new IllegalArgumentException("Date format is invalid: [" + entry.getValue() + "]"); - } - propertiesBuilder.addDate(entry.getKey().toString(), scheduleDate); - } else { - propertiesBuilder.addString(entry.getKey().toString(), entry.getValue().toString()); - } - } - - return propertiesBuilder.toJobParameters(); - } - - /** - * Convert schedule date to Date, and assume all other parameters can be represented by their default string value. - * - * @see org.springframework.batch.core.converter.JobParametersConverter#getProperties(org.springframework.batch.core.JobParameters) - */ - @Override - public Properties getProperties(@Nullable JobParameters params) { - - if (params == null || params.isEmpty()) { - return new Properties(); - } - - Map parameters = params.getParameters(); - Properties result = new Properties(); - for (Entry entry : parameters.entrySet()) { - String key = entry.getKey(); - JobParameter jobParameter = entry.getValue(); - if (key.equals(SCHEDULE_DATE_KEY)) { - result.setProperty(key, dateFormat.format(jobParameter.getValue())); - } else { - result.setProperty(key, "" + jobParameter.getValue()); - } - } - return result; - } - - /** - * Public setter for injecting a date format. - * - * @param dateFormat a {@link DateFormat}, defaults to "yyyy/MM/dd" - */ - public void setDateFormat(DateFormat dateFormat) { - this.dateFormat = dateFormat; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java index 522cfb2fb..3bc5a53fa 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 the original author or authors. + * Copyright 2006-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. @@ -84,26 +84,6 @@ public class SimpleStepExecutionSplitter implements StepExecutionSplitter, Initi this.stepName = stepName; } - /** - * Construct a {@link SimpleStepExecutionSplitter} from its mandatory - * properties. - * - * @param jobRepository the {@link JobRepository} - * @param step the target step (a local version of it), used to extract the - * name and allowStartIfComplete flags - * @param partitioner a {@link Partitioner} to use for generating input - * parameters - * - * @deprecated use {@link #SimpleStepExecutionSplitter(JobRepository, boolean, String, Partitioner)} instead - */ - @Deprecated - public SimpleStepExecutionSplitter(JobRepository jobRepository, Step step, Partitioner partitioner) { - this.jobRepository = jobRepository; - this.allowStartIfComplete = step.isAllowStartIfComplete(); - this.partitioner = partitioner; - this.stepName = step.getName(); - } - /** * Check mandatory properties (step name, job repository and partitioner). * @@ -247,22 +227,6 @@ public class SimpleStepExecutionSplitter implements StepExecutionSplitter, Initi * @throws JobExecutionException if unable to check if the step execution is startable */ protected boolean isStartable(StepExecution stepExecution, ExecutionContext context) throws JobExecutionException { - return getStartable(stepExecution, context); - } - - /** - * Check if a step execution is startable. - * @param stepExecution the step execution to check - * @param context the execution context of the step - * @return true if the step execution is startable, false otherwise - * @throws JobExecutionException if unable to check if the step execution is startable - * @deprecated This method is deprecated in favor of - * {@link SimpleStepExecutionSplitter#isStartable} and will be removed in a - * future version. - */ - @Deprecated - protected boolean getStartable(StepExecution stepExecution, ExecutionContext context) throws JobExecutionException { - JobInstance jobInstance = stepExecution.getJobExecution().getJobInstance(); String stepName = stepExecution.getStepName(); StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobInstance, stepName); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/XStreamExecutionContextStringSerializer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/XStreamExecutionContextStringSerializer.java deleted file mode 100644 index f911d86e5..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/XStreamExecutionContextStringSerializer.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2006-2018 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.repository.dao; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.util.Map; - -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; -import com.thoughtworks.xstream.io.HierarchicalStreamDriver; -import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver; - -import org.springframework.batch.core.repository.ExecutionContextSerializer; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.serializer.Deserializer; -import org.springframework.core.serializer.Serializer; -import org.springframework.util.Assert; - -/** - * Implementation that uses XStream and Jettison to provide serialization. - * - * @author Thomas Risberg - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 2.0 - * @see ExecutionContextSerializer - * @deprecated Due to the incompatibilities between current Jettison versions and XStream - * versions, this serializer is deprecated in favor of - * {@link Jackson2ExecutionContextStringSerializer} - */ -@Deprecated -public class XStreamExecutionContextStringSerializer implements ExecutionContextSerializer, InitializingBean { - - private ReflectionProvider reflectionProvider = null; - - private HierarchicalStreamDriver hierarchicalStreamDriver; - - private XStream xstream; - - public void setReflectionProvider(ReflectionProvider reflectionProvider) { - this.reflectionProvider = reflectionProvider; - } - - public void setHierarchicalStreamDriver(HierarchicalStreamDriver hierarchicalStreamDriver) { - this.hierarchicalStreamDriver = hierarchicalStreamDriver; - } - - @Override - public void afterPropertiesSet() throws Exception { - init(); - } - - public synchronized void init() throws Exception { - if (hierarchicalStreamDriver == null) { - this.hierarchicalStreamDriver = new JettisonMappedXmlDriver(); - } - if (reflectionProvider == null) { - xstream = new XStream(hierarchicalStreamDriver); - } - else { - xstream = new XStream(reflectionProvider, hierarchicalStreamDriver); - } - } - - /** - * Serializes the passed execution context to the supplied OutputStream. - * - * @param context {@link Map} containing the context information. - * @param out {@link OutputStream} where the serialized context information - * will be written. - * - * @see Serializer#serialize(Object, OutputStream) - */ - @Override - public void serialize(Map context, OutputStream out) throws IOException { - Assert.notNull(context, "context is required"); - Assert.notNull(out, "An OutputStream is required"); - - out.write(xstream.toXML(context).getBytes()); - } - - /** - * Deserializes the supplied input stream into a new execution context. - * - * @param in {@link InputStream} containing the information to be deserialized. - - * @return a reconstructed execution context - * @see Deserializer#deserialize(InputStream) - */ - @SuppressWarnings("unchecked") - @Override - public Map deserialize(InputStream in) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(in)); - - StringBuilder sb = new StringBuilder(); - - String line; - while ((line = br.readLine()) != null) { - sb.append(line); - } - - return (Map) xstream.fromXML(sb.toString()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java index 4e62eab1f..d58f21210 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java @@ -72,19 +72,6 @@ public class JobExecutionTests { assertFalse(execution.isRunning()); } - /** - * Test method for - * {@link org.springframework.batch.core.JobExecution#getEndTime()}. - */ - @Test - public void testIsRunningWithStoppedExecution() { - execution.setStartTime(new Date()); - assertTrue(execution.isRunning()); - execution.stop(); - assertTrue(execution.isRunning()); - assertTrue(execution.isStopping()); - } - /** * Test method for * {@link org.springframework.batch.core.JobExecution#getStartTime()}. @@ -206,14 +193,6 @@ public class JobExecutionTests { assertEquals(2, execution.getStepExecutions().size()); } - @Test - public void testStop() throws Exception { - StepExecution stepExecution = execution.createStepExecution("step"); - assertFalse(stepExecution.isTerminateOnly()); - execution.stop(); - assertTrue(stepExecution.isTerminateOnly()); - } - @Test public void testToString() throws Exception { assertTrue("JobExecution string does not contain id", execution.toString().indexOf("id=") >= 0); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java index b4961f81a..6e1224bc5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java @@ -102,7 +102,6 @@ public class SimpleJobTests { @Before public void setUp() throws Exception { - EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder() .addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql") .addScript("/org/springframework/batch/core/schema-hsqldb.sql") @@ -394,17 +393,6 @@ public class SimpleJobTests { "no steps configured") >= 0); } - @Test - public void testNotExecutedIfAlreadyStopped() throws Exception { - jobExecution.stop(); - job.execute(jobExecution); - - assertEquals(0, list.size()); - checkRepository(BatchStatus.STOPPED, ExitStatus.NOOP); - ExitStatus exitStatus = jobExecution.getExitStatus(); - assertEquals(ExitStatus.NOOP.getExitCode(), exitStatus.getExitCode()); - } - @Test public void testRestart() throws Exception { step1.setAllowStartIfComplete(true); @@ -493,31 +481,6 @@ public class SimpleJobTests { assertFalse(step2.passedInJobContext.isEmpty()); } - @Test - public void testInterruptJob() throws Exception { - - step1 = new StubStep("interruptStep", jobRepository) { - - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException, - UnexpectedJobExecutionException { - stepExecution.getJobExecution().stop(); - super.execute(stepExecution); - } - - }; - - job.setSteps(Arrays.asList(new Step[] { step1, step2 })); - job.execute(jobExecution); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - assertEquals(1, jobExecution.getAllFailureExceptions().size()); - Throwable expected = jobExecution.getAllFailureExceptions().get(0); - assertTrue("Wrong exception " + expected, expected instanceof JobInterruptedException); - assertEquals("JobExecution interrupted.", expected.getMessage()); - - assertNull("Second step was not supposed to be executed", step2.passedInStepContext); - } - @Test public void testGetStepExists() { step1 = new StubStep("step1", jobRepository); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/ScheduledJobParametersFactoryTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/ScheduledJobParametersFactoryTests.java deleted file mode 100644 index 111bb47da..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/ScheduledJobParametersFactoryTests.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2006-2013 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.launch.support; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Properties; - -import junit.framework.TestCase; - -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.util.StringUtils; - -/** - * @author Lucas Ward - * - */ -public class ScheduledJobParametersFactoryTests extends TestCase { - - ScheduledJobParametersFactory factory; - - DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); - - @Override - protected void setUp() throws Exception { - super.setUp(); - - factory = new ScheduledJobParametersFactory(); - } - - public void testGetParameters() throws Exception { - - String jobKey = "job.key=myKey"; - String scheduleDate = "schedule.date=2008/01/23"; - String vendorId = "vendor.id=33243243"; - - String[] args = new String[] { jobKey, scheduleDate, vendorId }; - - JobParameters props = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "=")); - assertNotNull(props); - assertEquals("myKey", props.getString("job.key")); - assertEquals("33243243", props.getString("vendor.id")); - Date date = dateFormat.parse("01/23/2008"); - assertEquals(date, props.getDate("schedule.date")); - } - - public void testGetProperties() throws Exception { - - JobParameters parameters = new JobParametersBuilder().addDate("schedule.date", dateFormat.parse("01/23/2008")) - .addString("job.key", "myKey").addString("vendor.id", "33243243").toJobParameters(); - - Properties props = factory.getProperties(parameters); - assertNotNull(props); - assertEquals("myKey", props.getProperty("job.key")); - assertEquals("33243243", props.getProperty("vendor.id")); - assertEquals("2008/01/23", props.getProperty("schedule.date")); - } - - public void testEmptyArgs() { - - JobParameters props = factory.getJobParameters(new Properties()); - assertTrue(props.getParameters().isEmpty()); - } - - public void testNullArgs() { - assertEquals(new JobParameters(), factory.getJobParameters(null)); - assertEquals(new Properties(), factory.getProperties(null)); - } - - public void testGetParametersWithDateFormat() throws Exception { - - String[] args = new String[] { "schedule.date=2008/23/01" }; - - factory.setDateFormat(new SimpleDateFormat("yyyy/dd/MM")); - JobParameters props = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "=")); - assertNotNull(props); - Date date = dateFormat.parse("01/23/2008"); - assertEquals(date, props.getDate("schedule.date")); - } - - public void testGetParametersWithBogusDate() throws Exception { - - String[] args = new String[] { "schedule.date=20080123" }; - - try { - factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "=")); - } catch (IllegalArgumentException e) { - String message = e.getMessage(); - assertTrue("Message should contain wrong date: " + message, contains(message, "20080123")); - } - } - - private boolean contains(String str, String searchStr) { - return str.indexOf(searchStr) != -1; - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/XStreamExecutionContextStringSerializerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/XStreamExecutionContextStringSerializerTests.java deleted file mode 100644 index e5cd4a856..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/XStreamExecutionContextStringSerializerTests.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2008-2016 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.repository.dao; - -import org.junit.Before; -import org.springframework.batch.core.repository.ExecutionContextSerializer; - -/** - * @author Thomas Risberg - * @author Michael Minella - */ -public class XStreamExecutionContextStringSerializerTests extends AbstractExecutionContextSerializerTests { - - ExecutionContextSerializer serializer; - - @Before - public void onSetUp() throws Exception { - @SuppressWarnings("deprecation") - XStreamExecutionContextStringSerializer serializerDeserializer = new XStreamExecutionContextStringSerializer(); - (serializerDeserializer).afterPropertiesSet(); - - serializer = serializerDeserializer; - } - - @Override - protected ExecutionContextSerializer getSerializer() { - return this.serializer; - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/resource/ListPreparedStatementSetterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/resource/ListPreparedStatementSetterTests.java deleted file mode 100644 index 913a441cf..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/resource/ListPreparedStatementSetterTests.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2006-2013 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.resource; - -import static org.junit.Assert.assertEquals; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import javax.sql.DataSource; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.job.AbstractJob; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.database.support.ListPreparedStatementSetter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowCallbackHandler; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author Lucas Ward - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = { - "/org/springframework/batch/core/resource/ListPreparedStatementSetterTests-context.xml", -"/org/springframework/batch/core/repository/dao/data-source-context.xml" }) -public class ListPreparedStatementSetterTests { - - ListPreparedStatementSetter pss; - - StepExecution stepExecution; - - private JdbcTemplate jdbcTemplate; - - @Autowired - public void setDataSource(DataSource dataSource) { - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - @Autowired - private AbstractJob job; - - @Autowired - private JobLauncher jobLauncher; - - @Autowired - private FooStoringItemWriter fooStoringItemWriter; - - @Before - public void onSetUpInTransaction() throws Exception { - - List parameters = new ArrayList<>(); - parameters.add(1L); - parameters.add(4L); - pss = new ListPreparedStatementSetter(parameters); - } - - @Transactional - @Test - public void testSetValues() { - - final List results = new ArrayList<>(); - jdbcTemplate.query("SELECT NAME from T_FOOS where ID > ? and ID < ?", pss, - new RowCallbackHandler() { - @Override - public void processRow(ResultSet rs) throws SQLException { - results.add(rs.getString(1)); - } - }); - - assertEquals(2, results.size()); - assertEquals("bar2", results.get(0)); - assertEquals("bar3", results.get(1)); - } - - @Transactional - @Test(expected = IllegalArgumentException.class) - public void testAfterPropertiesSet() throws Exception { - pss = new ListPreparedStatementSetter(null); - pss.afterPropertiesSet(); - } - - @Test - public void testXmlConfiguration() throws Exception { - this.jdbcTemplate.update("create table FOO (ID integer, NAME varchar(40), VALUE integer)"); - try { - this.jdbcTemplate.update("insert into FOO values (?,?,?)", 0, "zero", 0); - this.jdbcTemplate.update("insert into FOO values (?,?,?)", 1, "one", 1); - this.jdbcTemplate.update("insert into FOO values (?,?,?)", 2, "two", 2); - this.jdbcTemplate.update("insert into FOO values (?,?,?)", 3, "three", 3); - - JobParametersBuilder builder = new JobParametersBuilder().addLong("min.id", 1L).addLong("max.id", 2L); - JobExecution jobExecution = this.jobLauncher.run(this.job, builder.toJobParameters()); - assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); - - List foos = fooStoringItemWriter.getFoos(); - assertEquals(2, foos.size()); - System.err.println(foos.get(0)); - System.err.println(foos.get(1)); - assertEquals(new Foo(1, "one", 1), foos.get(0)); - assertEquals(new Foo(2, "two", 2), foos.get(1)); - } - finally { - this.jdbcTemplate.update("drop table FOO"); - } - } - - public static class FooStoringItemWriter implements ItemWriter { - private List foos = new ArrayList<>(); - - @Override - public void write(List items) throws Exception { - foos.addAll(items); - } - - public List getFoos() { - return foos; - } - } -} diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/sql-dao-test.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/sql-dao-test.xml index b95d87b83..93b2ba182 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/sql-dao-test.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/sql-dao-test.xml @@ -35,5 +35,5 @@ - + diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractNeo4jItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractNeo4jItemReader.java deleted file mode 100644 index d244afc73..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractNeo4jItemReader.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2012-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.item.data; - -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.ItemReader; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - *

- * Restartable {@link ItemReader} that reads objects from the graph database Neo4j - * via a paging technique. - *

- * - *

- * It executes cypher queries built from the statement fragments provided to - * retrieve the requested data. The query is executed using paged requests of - * a size specified in {@link #setPageSize(int)}. Additional pages are requested - * as needed when the {@link #read()} method is called. On restart, the reader - * will begin again at the same number item it left off at. - *

- * - *

- * Performance is dependent on your Neo4J configuration (embedded or remote) as - * well as page size. Setting a fairly large page size and using a commit - * interval that matches the page size should provide better performance. - *

- * - *

- * This implementation is thread-safe between calls to - * {@link #open(org.springframework.batch.item.ExecutionContext)}, however you - * should set saveState=false if used in a multi-threaded - * environment (no restart available). - *

- * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.07 - * @deprecated Extend {@link Neo4jItemReader} instead. - */ -@Deprecated -public abstract class AbstractNeo4jItemReader extends - AbstractPaginatedDataItemReader implements InitializingBean { - - protected Log logger = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - private String startStatement; - private String returnStatement; - private String matchStatement; - private String whereStatement; - private String orderByStatement; - - private Class targetType; - - private Map parameterValues; - - /** - * Optional parameters to be used in the cypher query. - * - * @param parameterValues the parameter values to be used in the cypher query - */ - public void setParameterValues(Map parameterValues) { - this.parameterValues = parameterValues; - } - - protected final Map getParameterValues() { - return this.parameterValues; - } - - /** - * The start segment of the cypher query. START is prepended - * to the statement provided and should not be - * included. - * - * @param startStatement the start fragment of the cypher query. - */ - public void setStartStatement(String startStatement) { - this.startStatement = startStatement; - } - - /** - * The return statement of the cypher query. RETURN is prepended - * to the statement provided and should not be - * included - * - * @param returnStatement the return fragment of the cypher query. - */ - public void setReturnStatement(String returnStatement) { - this.returnStatement = returnStatement; - } - - /** - * An optional match fragment of the cypher query. MATCH is - * prepended to the statement provided and should not - * be included. - * - * @param matchStatement the match fragment of the cypher query - */ - public void setMatchStatement(String matchStatement) { - this.matchStatement = matchStatement; - } - - /** - * An optional where fragment of the cypher query. WHERE is - * prepended to the statement provided and should not - * be included. - * - * @param whereStatement where fragment of the cypher query - */ - public void setWhereStatement(String whereStatement) { - this.whereStatement = whereStatement; - } - - /** - * A list of properties to order the results by. This is - * required so that subsequent page requests pull back the - * segment of results correctly. ORDER BY is prepended to - * the statement provided and should not be included. - * - * @param orderByStatement order by fragment of the cypher query. - */ - public void setOrderByStatement(String orderByStatement) { - this.orderByStatement = orderByStatement; - } - - protected SessionFactory getSessionFactory() { - return sessionFactory; - } - - /** - * Establish the session factory for the reader. - * @param sessionFactory the factory to use for the reader. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * The object type to be returned from each call to {@link #read()} - * - * @param targetType the type of object to return. - */ - public void setTargetType(Class targetType) { - this.targetType = targetType; - } - - protected final Class getTargetType() { - return this.targetType; - } - - protected String generateLimitCypherQuery() { - StringBuilder query = new StringBuilder(128); - - query.append("START ").append(startStatement); - query.append(matchStatement != null ? " MATCH " + matchStatement : ""); - query.append(whereStatement != null ? " WHERE " + whereStatement : ""); - query.append(" RETURN ").append(returnStatement); - query.append(" ORDER BY ").append(orderByStatement); - query.append(" SKIP " + (pageSize * page)); - query.append(" LIMIT " + pageSize); - - String resultingQuery = query.toString(); - - if (logger.isDebugEnabled()) { - logger.debug(resultingQuery); - } - - return resultingQuery; - } - - /** - * Checks mandatory properties - * - * @see InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.state(sessionFactory != null,"A SessionFactory is required"); - Assert.state(targetType != null, "The type to be returned is required"); - Assert.state(StringUtils.hasText(startStatement), "A START statement is required"); - Assert.state(StringUtils.hasText(returnStatement), "A RETURN statement is required"); - Assert.state(StringUtils.hasText(orderByStatement), "A ORDER BY statement is required"); - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java index 06e2224a1..f9416b435 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 the original author or authors. + * Copyright 2012-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. @@ -18,17 +18,191 @@ package org.springframework.batch.item.data; import java.util.ArrayList; import java.util.Iterator; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.neo4j.ogm.session.Session; +import org.neo4j.ogm.session.SessionFactory; + +import org.springframework.batch.item.ItemReader; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** *

- * Extensions of the {@link AbstractNeo4jItemReader}. + * Restartable {@link ItemReader} that reads objects from the graph database Neo4j + * via a paging technique. + *

+ * + *

+ * It executes cypher queries built from the statement fragments provided to + * retrieve the requested data. The query is executed using paged requests of + * a size specified in {@link #setPageSize(int)}. Additional pages are requested + * as needed when the {@link #read()} method is called. On restart, the reader + * will begin again at the same number item it left off at. + *

+ * + *

+ * Performance is dependent on your Neo4J configuration (embedded or remote) as + * well as page size. Setting a fairly large page size and using a commit + * interval that matches the page size should provide better performance. + *

+ * + *

+ * This implementation is thread-safe between calls to + * {@link #open(org.springframework.batch.item.ExecutionContext)}, however you + * should set saveState=false if used in a multi-threaded + * environment (no restart available). *

* * @author Michael Minella + * @author Mahmoud Ben Hassine */ -public class Neo4jItemReader extends AbstractNeo4jItemReader { +public class Neo4jItemReader extends AbstractPaginatedDataItemReader implements InitializingBean { + + protected Log logger = LogFactory.getLog(getClass()); + + private SessionFactory sessionFactory; + + private String startStatement; + private String returnStatement; + private String matchStatement; + private String whereStatement; + private String orderByStatement; + + private Class targetType; + + private Map parameterValues; + + /** + * Optional parameters to be used in the cypher query. + * + * @param parameterValues the parameter values to be used in the cypher query + */ + public void setParameterValues(Map parameterValues) { + this.parameterValues = parameterValues; + } + + protected final Map getParameterValues() { + return this.parameterValues; + } + + /** + * The start segment of the cypher query. START is prepended + * to the statement provided and should not be + * included. + * + * @param startStatement the start fragment of the cypher query. + */ + public void setStartStatement(String startStatement) { + this.startStatement = startStatement; + } + + /** + * The return statement of the cypher query. RETURN is prepended + * to the statement provided and should not be + * included + * + * @param returnStatement the return fragment of the cypher query. + */ + public void setReturnStatement(String returnStatement) { + this.returnStatement = returnStatement; + } + + /** + * An optional match fragment of the cypher query. MATCH is + * prepended to the statement provided and should not + * be included. + * + * @param matchStatement the match fragment of the cypher query + */ + public void setMatchStatement(String matchStatement) { + this.matchStatement = matchStatement; + } + + /** + * An optional where fragment of the cypher query. WHERE is + * prepended to the statement provided and should not + * be included. + * + * @param whereStatement where fragment of the cypher query + */ + public void setWhereStatement(String whereStatement) { + this.whereStatement = whereStatement; + } + + /** + * A list of properties to order the results by. This is + * required so that subsequent page requests pull back the + * segment of results correctly. ORDER BY is prepended to + * the statement provided and should not be included. + * + * @param orderByStatement order by fragment of the cypher query. + */ + public void setOrderByStatement(String orderByStatement) { + this.orderByStatement = orderByStatement; + } + + protected SessionFactory getSessionFactory() { + return sessionFactory; + } + + /** + * Establish the session factory for the reader. + * @param sessionFactory the factory to use for the reader. + */ + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + /** + * The object type to be returned from each call to {@link #read()} + * + * @param targetType the type of object to return. + */ + public void setTargetType(Class targetType) { + this.targetType = targetType; + } + + protected final Class getTargetType() { + return this.targetType; + } + + protected String generateLimitCypherQuery() { + StringBuilder query = new StringBuilder(128); + + query.append("START ").append(startStatement); + query.append(matchStatement != null ? " MATCH " + matchStatement : ""); + query.append(whereStatement != null ? " WHERE " + whereStatement : ""); + query.append(" RETURN ").append(returnStatement); + query.append(" ORDER BY ").append(orderByStatement); + query.append(" SKIP " + (pageSize * page)); + query.append(" LIMIT " + pageSize); + + String resultingQuery = query.toString(); + + if (logger.isDebugEnabled()) { + logger.debug(resultingQuery); + } + + return resultingQuery; + } + + /** + * Checks mandatory properties + * + * @see InitializingBean#afterPropertiesSet() + */ + @Override + public void afterPropertiesSet() throws Exception { + Assert.state(sessionFactory != null,"A SessionFactory is required"); + Assert.state(targetType != null, "The type to be returned is required"); + Assert.state(StringUtils.hasText(startStatement), "A START statement is required"); + Assert.state(StringUtils.hasText(returnStatement), "A RETURN statement is required"); + Assert.state(StringUtils.hasText(orderByStatement), "A ORDER BY statement is required"); + } @SuppressWarnings("unchecked") @Override diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java index aefc8f6a9..67f834439 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2020 the original author or authors. + * Copyright 2006-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. @@ -413,16 +413,6 @@ implements InitializingBean { } } - /** - * Clean up resources. - * @throws Exception If unable to clean up resources - * @deprecated This method is deprecated in favor of - * {@link AbstractCursorItemReader#cleanupOnClose(java.sql.Connection)} and - * will be removed in a future release - */ - @Deprecated - protected abstract void cleanupOnClose() throws Exception; - /** * Clean up resources. * @param connection to the database diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateItemWriter.java index 5857f5e97..bd4bb7d39 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2017 the original author or authors. + * Copyright 2006-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. @@ -43,6 +43,7 @@ import org.springframework.util.Assert; * @author Dave Syer * @author Thomas Risberg * @author Michael Minella + * @author Mahmoud Ben Hassine * */ public class HibernateItemWriter implements ItemWriter, InitializingBean { @@ -129,40 +130,4 @@ public class HibernateItemWriter implements ItemWriter, InitializingBean { } } - /** - * Do perform the actual write operation using {@link HibernateOperations}. - * This can be overridden in a subclass if necessary. - * - * @param hibernateTemplate - * the HibernateTemplate to use for the operation - * @param items - * the list of items to use for the write - * @deprecated As of 2.2 in favor of using Hibernate's session management APIs directly - */ - @Deprecated - protected void doWrite(HibernateOperations hibernateTemplate, - List items) { - - if (logger.isDebugEnabled()) { - logger.debug("Writing to Hibernate with " + items.size() - + " items."); - } - - if (!items.isEmpty()) { - long saveOrUpdateCount = 0; - for (T item : items) { - if (!hibernateTemplate.contains(item)) { - hibernateTemplate.saveOrUpdate(item); - saveOrUpdateCount++; - } - } - if (logger.isDebugEnabled()) { - logger.debug(saveOrUpdateCount + " entities saved/updated."); - logger.debug((items.size() - saveOrUpdateCount) - + " entities found in session."); - } - } - - } - } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java index 3e2c8ade8..2caef4de1 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2020 the original author or authors. + * Copyright 2006-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. @@ -142,18 +142,6 @@ public class JdbcCursorItemReader extends AbstractCursorItemReader { return rowMapper.mapRow(rs, currentRow); } - /** - * Close the cursor and database connection. - * @deprecated This method is deprecated in favor of - * {@link JdbcCursorItemReader#cleanupOnClose(java.sql.Connection)} and will - * be removed in a future release - */ - @Override - @Deprecated - protected void cleanupOnClose() throws Exception { - JdbcUtils.closeStatement(this.preparedStatement); - } - /** * Close the cursor and database connection. * @param connection to the database diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java index 08079dabc..f20bbb556 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2020 the original author or authors. + * Copyright 2006-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. @@ -238,18 +238,6 @@ public class StoredProcedureItemReader extends AbstractCursorItemReader { return rowMapper.mapRow(rs, currentRow); } - /** - * Close the cursor and database connection. - * @deprecated This method is deprecated in favor of - * {@link StoredProcedureItemReader#cleanupOnClose(java.sql.Connection)} and - * will be removed in a future release - */ - @Override - @Deprecated - protected void cleanupOnClose() throws Exception { - JdbcUtils.closeStatement(this.callableStatement); - } - /** * Close the cursor and database connection. * @param connection to the database diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/HibernatePagingItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/HibernatePagingItemReaderBuilder.java index b440c7007..90c32de81 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/HibernatePagingItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/HibernatePagingItemReaderBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 the original author or authors. + * Copyright 2017-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. @@ -217,22 +217,6 @@ public class HibernatePagingItemReaderBuilder { return this; } - /** - * Indicator for whether to use a {@link org.hibernate.StatelessSession} - * (true) or a {@link org.hibernate.Session} (false). - * - * @param useStatelessSession Defaults to false - * @return this instance for method chaining - * @see HibernatePagingItemReader#setUseStatelessSession(boolean) - * @deprecated This method is deprecated in favor of - * {@link HibernatePagingItemReaderBuilder#useStatelessSession} and will be - * removed in a future version. - */ - @Deprecated - public HibernatePagingItemReaderBuilder useSatelessSession(boolean useStatelessSession) { - return useStatelessSession(useStatelessSession); - } - /** * Indicator for whether to use a {@link org.hibernate.StatelessSession} * (true) or a {@link org.hibernate.Session} (false). diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/ListPreparedStatementSetter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/ListPreparedStatementSetter.java deleted file mode 100644 index b5c60c9f2..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/ListPreparedStatementSetter.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2006-2019 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.item.database.support; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.List; - -import org.springframework.batch.item.database.JdbcCursorItemReader; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jdbc.core.PreparedStatementSetter; -import org.springframework.jdbc.core.SqlTypeValue; -import org.springframework.jdbc.core.StatementCreatorUtils; -import org.springframework.util.Assert; - -/** - * Implementation of the {@link PreparedStatementSetter} interface that accepts - * a list of values to be set on a PreparedStatement. This is usually used in - * conjunction with the {@link JdbcCursorItemReader} to allow for the replacement - * of bind variables when generating the cursor. The order of the list will be - * used to determine the ordering of setting variables. For example, the first - * item in the list will be the first bind variable set. (i.e. it will - * correspond to the first '?' in the SQL statement) - * - * @deprecated use {@link org.springframework.jdbc.core.ArgumentPreparedStatementSetter} - * instead. - * - * @author Lucas Ward - * @author Mahmoud Ben Hassine - * - */ -@Deprecated -public class ListPreparedStatementSetter implements -PreparedStatementSetter, InitializingBean { - - private List parameters; - - public ListPreparedStatementSetter() {} - - public ListPreparedStatementSetter(List parameters) { - this.parameters = parameters; - } - - @Override - public void setValues(PreparedStatement ps) throws SQLException { - for (int i = 0; i < parameters.size(); i++) { - StatementCreatorUtils.setParameterValue(ps, i + 1, SqlTypeValue.TYPE_UNKNOWN, parameters.get(i)); - } - } - - /** - * The parameter values that will be set on the PreparedStatement. - * It is assumed that their order in the List is the order of the parameters - * in the PreparedStatement. - * - * @param parameters list containing the parameter values to be used. - * @deprecated In favor of the constructor - */ - @Deprecated - public void setParameters(List parameters) { - this.parameters = parameters; - } - - @Override - public void afterPropertiesSet() throws Exception { - Assert.notNull(parameters, "Parameters must be provided"); - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java index 6b53b5b7b..f8870fe85 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2020 the original author or authors. + * Copyright 2006-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. @@ -142,7 +142,7 @@ public class MultiResourceItemReader extends AbstractItemStreamItemReader private T readFromDelegate() throws Exception { T item = delegate.read(); if(item instanceof ResourceAware){ - ((ResourceAware) item).setResource(getCurrentResource()); + ((ResourceAware) item).setResource(resources[currentResource]); } return item; } @@ -247,20 +247,4 @@ public class MultiResourceItemReader extends AbstractItemStreamItemReader this.resources = Arrays.asList(resources).toArray(new Resource[resources.length]); } - /** - * Getter for the current resource. - * @return the current resource or {@code null} if all resources have been - * processed or the first resource has not been assigned yet. - * - * @deprecated In favor of using {@link ResourceAware} instead. - */ - @Nullable - @Deprecated - public Resource getCurrentResource() { - if (currentResource >= resources.length || currentResource < 0) { - return null; - } - return resources[currentResource]; - } - } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/Alignment.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/Alignment.java deleted file mode 100644 index 55a7c3455..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/Alignment.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2006-2020 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.item.file.transform; - -import org.springframework.util.Assert; - -/** - * @author Dave Syer - * @author Mahmoud Ben Hassine - * - * @deprecated Use {@link FormatterLineAggregator#setFormat(java.lang.String)} - * for alignment (See examples in {@code FormatterLineAggregatorTests}) - */ -@Deprecated -public enum Alignment { - CENTER("CENTER", "center"), - RIGHT("RIGHT", "right"), - LEFT("LEFT", "left"); - - private String code; - private String label; - - private Alignment(String code, String label) { - Assert.notNull(code, "'code' must not be null"); - - this.code = code; - this.label = label; - } - - public Comparable getCode() { - return code; - } - - public String getStringCode() { - return (String) getCode(); - } - - public String getLabel() { - if (this.label != null) { - return label; - } - - return getCode().toString(); - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/FileUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/FileUtils.java index 7d78a2444..f52ccece6 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/FileUtils.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/FileUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007 the original author or authors. + * Copyright 2006-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. @@ -26,6 +26,7 @@ import org.springframework.util.Assert; * Utility methods for files used in batch processing. * * @author Peter Zozom + * @author Mahmoud Ben Hassine */ public final class FileUtils { @@ -89,28 +90,6 @@ public final class FileUtils { } } - /** - * Set up output file for batch processing. This method implements common logic for handling output files when - * starting or restarting file I/O. When starting output file processing, creates/overwrites new file. When - * restarting output file processing, checks whether file is writable. - * - * @param file file to be set up - * @param restarted true signals that we are restarting output file processing - * @param overwriteOutputFile If set to true, output file will be overwritten (this flag is ignored when processing - * is restart) - * - * @throws IllegalArgumentException when file is null - * @throws ItemStreamException when starting output file processing, file exists and flag "overwriteOutputFile" is - * set to false - * @throws ItemStreamException when unable to create file or file is not writable - * - * @deprecated use the version with explicit append parameter instead. Here append=false is assumed. - */ - @Deprecated - public static void setUpOutputFile(File file, boolean restarted, boolean overwriteOutputFile) { - setUpOutputFile(file, restarted, false, overwriteOutputFile); - } - /** * Create a new file if it doesn't already exist. * diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java deleted file mode 100644 index 5c5dfa82b..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2006-2020 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.item.xml; - -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLEventWriter; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.stax.StAXResult; -import javax.xml.transform.stax.StAXSource; - - -/** - * StAX utility methods. - *
- * This class is thread-safe. - * - * @author Josh Long - * @author Mahmoud Ben Hassine - * - * @deprecated in favor of {@link org.springframework.util.xml.StaxUtils} - * - */ -@Deprecated -public abstract class StaxUtils { - - public static Source getSource(XMLEventReader r) throws XMLStreamException { - return new StAXSource(r); - } - - public static Result getResult(XMLEventWriter w) { - return new StAXResult(w); - } - - public static XMLInputFactory createXmlInputFactory() { - XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); - xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); - xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); - return xmlInputFactory; - } -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java index b9b97a88c..17d3be676 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-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. @@ -35,6 +35,7 @@ import static org.mockito.Mockito.when; * @author Thomas Risberg * @author Michael Minella * @author Will Schipp + * @author Mahmoud Ben Hassine */ public class HibernateItemWriterTests { @@ -83,7 +84,6 @@ public class HibernateItemWriterTests { writer.afterPropertiesSet(); } - @SuppressWarnings("deprecation") @Test public void testWriteAndFlushSunnyDayHibernate3() throws Exception { this.writer.setSessionFactory(this.factory); @@ -98,7 +98,6 @@ public class HibernateItemWriterTests { } - @SuppressWarnings("deprecation") @Test public void testWriteAndFlushWithFailureHibernate3() throws Exception { this.writer.setSessionFactory(this.factory); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java index b191ed1e9..3ac9f54d7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2019 the original author or authors. + * Copyright 2008-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. @@ -102,33 +102,6 @@ public class MultiResourceItemReaderIntegrationTests { tested.close(); } - @Test - public void testGetCurrentResource() throws Exception { - - tested.open(ctx); - - assertEquals("1", tested.read()); - assertSame(r1, tested.getCurrentResource()); - assertEquals("2", tested.read()); - assertSame(r1, tested.getCurrentResource()); - assertEquals("3", tested.read()); - assertSame(r1, tested.getCurrentResource()); - assertEquals("4", tested.read()); - assertSame(r2, tested.getCurrentResource()); - assertEquals("5", tested.read()); - assertSame(r2, tested.getCurrentResource()); - assertEquals("6", tested.read()); - assertSame(r4, tested.getCurrentResource()); - assertEquals("7", tested.read()); - assertSame(r5, tested.getCurrentResource()); - assertEquals("8", tested.read()); - assertSame(r5, tested.getCurrentResource()); - assertEquals(null, tested.read()); - assertSame(null, tested.getCurrentResource()); - - tested.close(); - } - @Test public void testRestartWhenStateNotSaved() throws Exception { @@ -433,13 +406,6 @@ public class MultiResourceItemReaderIntegrationTests { } - @Test - public void testGetCurrentResourceBeforeRead() throws Exception { - tested.open(ctx); - assertNull("There is no 'current' resource before read is called", tested.getCurrentResource()); - - } - /** * No resources to read should result in error in strict mode. */ diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingMasterStepBuilder.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingMasterStepBuilder.java deleted file mode 100644 index 8d88f0ea3..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingMasterStepBuilder.java +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Copyright 2018-2019 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.integration.chunk; - -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.ItemReadListener; -import org.springframework.batch.core.ItemWriteListener; -import org.springframework.batch.core.SkipListener; -import org.springframework.batch.core.StepExecutionListener; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.step.builder.FaultTolerantStepBuilder; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.core.step.item.KeyGenerator; -import org.springframework.batch.core.step.skip.SkipPolicy; -import org.springframework.batch.core.step.tasklet.TaskletStep; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemStream; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.repeat.CompletionPolicy; -import org.springframework.batch.repeat.RepeatOperations; -import org.springframework.batch.repeat.exception.ExceptionHandler; -import org.springframework.integration.core.MessagingTemplate; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.PollableChannel; -import org.springframework.retry.RetryPolicy; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.retry.policy.RetryContextCache; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.interceptor.TransactionAttribute; -import org.springframework.util.Assert; - -/** - * Builder for a master step in a remote chunking setup. This builder creates and - * sets a {@link ChunkMessageChannelItemWriter} on the master step. - * - *

If no {@code messagingTemplate} is provided through - * {@link RemoteChunkingMasterStepBuilder#messagingTemplate(MessagingTemplate)}, - * this builder will create one and set its default channel to the {@code outputChannel} - * provided through {@link RemoteChunkingMasterStepBuilder#outputChannel(MessageChannel)}.

- * - *

If a {@code messagingTemplate} is provided, it is assumed that it is fully configured - * and that its default channel is set to an output channel on which requests to workers - * will be sent.

- * - * @param type of input items - * @param type of output items - * - * @deprecated Use {@link RemoteChunkingManagerStepBuilder} instead. - * - * @since 4.1 - * @author Mahmoud Ben Hassine - */ -@Deprecated -public class RemoteChunkingMasterStepBuilder extends FaultTolerantStepBuilder { - - private MessagingTemplate messagingTemplate; - private PollableChannel inputChannel; - private MessageChannel outputChannel; - - private final int DEFAULT_MAX_WAIT_TIMEOUTS = 40; - private static final long DEFAULT_THROTTLE_LIMIT = 6; - private int maxWaitTimeouts = DEFAULT_MAX_WAIT_TIMEOUTS; - private long throttleLimit = DEFAULT_THROTTLE_LIMIT; - - /** - * Create a new {@link RemoteChunkingMasterStepBuilder}. - * - * @param stepName name of the master step - */ - public RemoteChunkingMasterStepBuilder(String stepName) { - super(new StepBuilder(stepName)); - } - - /** - * Set the input channel on which replies from workers will be received. - * The provided input channel will be set as a reply channel on the - * {@link ChunkMessageChannelItemWriter} created by this builder. - * - * @param inputChannel the input channel - * @return this builder instance for fluent chaining - * - * @see ChunkMessageChannelItemWriter#setReplyChannel - */ - public RemoteChunkingMasterStepBuilder inputChannel(PollableChannel inputChannel) { - Assert.notNull(inputChannel, "inputChannel must not be null"); - this.inputChannel = inputChannel; - return this; - } - - /** - * Set the output channel on which requests to workers will be sent. By using - * this setter, a default messaging template will be created and the output - * channel will be set as its default channel. - *

Use either this setter or {@link RemoteChunkingMasterStepBuilder#messagingTemplate(MessagingTemplate)} - * to provide a fully configured messaging template.

- * - * @param outputChannel the output channel. - * @return this builder instance for fluent chaining - * - * @see RemoteChunkingMasterStepBuilder#messagingTemplate(MessagingTemplate) - */ - public RemoteChunkingMasterStepBuilder outputChannel(MessageChannel outputChannel) { - Assert.notNull(outputChannel, "outputChannel must not be null"); - this.outputChannel = outputChannel; - return this; - } - - /** - * Set the {@link MessagingTemplate} to use to send data to workers. - * The default channel of the messaging template must be set. - *

Use either this setter to provide a fully configured messaging template or - * provide an output channel through {@link RemoteChunkingMasterStepBuilder#outputChannel(MessageChannel)} - * and a default messaging template will be created.

- * - * @param messagingTemplate the messaging template to use - * @return this builder instance for fluent chaining - * @see RemoteChunkingMasterStepBuilder#outputChannel(MessageChannel) - */ - public RemoteChunkingMasterStepBuilder messagingTemplate(MessagingTemplate messagingTemplate) { - Assert.notNull(messagingTemplate, "messagingTemplate must not be null"); - this.messagingTemplate = messagingTemplate; - return this; - } - - /** - * The maximum number of times to wait at the end of a step for a non-null result from the remote workers. This is a - * multiplier on the receive timeout set separately on the gateway. The ideal value is a compromise between allowing - * slow workers time to finish, and responsiveness if there is a dead worker. Defaults to 40. - * - * @param maxWaitTimeouts the maximum number of wait timeouts - * @return this builder instance for fluent chaining - * @see ChunkMessageChannelItemWriter#setMaxWaitTimeouts(int) - */ - public RemoteChunkingMasterStepBuilder maxWaitTimeouts(int maxWaitTimeouts) { - Assert.isTrue(maxWaitTimeouts > 0, "maxWaitTimeouts must be greater than zero"); - this.maxWaitTimeouts = maxWaitTimeouts; - return this; - } - - /** - * Public setter for the throttle limit. This limits the number of pending requests for chunk processing to avoid - * overwhelming the receivers. - * - * @param throttleLimit the throttle limit to set - * @return this builder instance for fluent chaining - * @see ChunkMessageChannelItemWriter#setThrottleLimit(long) - */ - public RemoteChunkingMasterStepBuilder throttleLimit(long throttleLimit) { - Assert.isTrue(throttleLimit > 0, "throttleLimit must be greater than zero"); - this.throttleLimit = throttleLimit; - return this; - } - - /** - * Build a master {@link TaskletStep}. - * - * @return the configured master step - * @see RemoteChunkHandlerFactoryBean - */ - public TaskletStep build() { - Assert.notNull(this.inputChannel, "An InputChannel must be provided"); - Assert.state(this.outputChannel == null || this.messagingTemplate == null, - "You must specify either an outputChannel or a messagingTemplate but not both."); - - // configure messaging template - if (this.messagingTemplate == null) { - this.messagingTemplate = new MessagingTemplate(); - this.messagingTemplate.setDefaultChannel(this.outputChannel); - if (this.logger.isDebugEnabled()) { - this.logger.debug("No messagingTemplate was provided, using a default one"); - } - } - - // configure item writer - ChunkMessageChannelItemWriter chunkMessageChannelItemWriter = new ChunkMessageChannelItemWriter<>(); - chunkMessageChannelItemWriter.setMessagingOperations(this.messagingTemplate); - chunkMessageChannelItemWriter.setMaxWaitTimeouts(this.maxWaitTimeouts); - chunkMessageChannelItemWriter.setThrottleLimit(this.throttleLimit); - chunkMessageChannelItemWriter.setReplyChannel(this.inputChannel); - super.writer(chunkMessageChannelItemWriter); - - return super.build(); - } - - /* - * The following methods override those from parent builders and return - * the current builder type. - * FIXME: Change parent builders to be generic and return current builder - * type in each method. - */ - - @Override - public RemoteChunkingMasterStepBuilder reader(ItemReader reader) { - super.reader(reader); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder repository(JobRepository jobRepository) { - super.repository(jobRepository); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder transactionManager(PlatformTransactionManager transactionManager) { - super.transactionManager(transactionManager); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder listener(Object listener) { - super.listener(listener); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder listener(SkipListener listener) { - super.listener(listener); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder listener(ChunkListener listener) { - super.listener(listener); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder transactionAttribute(TransactionAttribute transactionAttribute) { - super.transactionAttribute(transactionAttribute); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder listener(org.springframework.retry.RetryListener listener) { - super.listener(listener); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder keyGenerator(KeyGenerator keyGenerator) { - super.keyGenerator(keyGenerator); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder retryLimit(int retryLimit) { - super.retryLimit(retryLimit); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder retryPolicy(RetryPolicy retryPolicy) { - super.retryPolicy(retryPolicy); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder backOffPolicy(BackOffPolicy backOffPolicy) { - super.backOffPolicy(backOffPolicy); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder retryContextCache(RetryContextCache retryContextCache) { - super.retryContextCache(retryContextCache); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder skipLimit(int skipLimit) { - super.skipLimit(skipLimit); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder noSkip(Class type) { - super.noSkip(type); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder skip(Class type) { - super.skip(type); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder skipPolicy(SkipPolicy skipPolicy) { - super.skipPolicy(skipPolicy); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder noRollback(Class type) { - super.noRollback(type); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder noRetry(Class type) { - super.noRetry(type); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder retry(Class type) { - super.retry(type); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder stream(ItemStream stream) { - super.stream(stream); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder chunk(int chunkSize) { - super.chunk(chunkSize); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder chunk(CompletionPolicy completionPolicy) { - super.chunk(completionPolicy); - return this; - } - - /** - * This method will throw a {@link UnsupportedOperationException} since - * the item writer of the master step in a remote chunking setup will be - * automatically set to an instance of {@link ChunkMessageChannelItemWriter}. - * - * When building a master step for remote chunking, no item writer must be - * provided. - * - * @throws UnsupportedOperationException if an item writer is provided - * @see ChunkMessageChannelItemWriter - * @see RemoteChunkHandlerFactoryBean#setChunkWriter(ItemWriter) - */ - @Override - public RemoteChunkingMasterStepBuilder writer(ItemWriter writer) throws UnsupportedOperationException { - throw new UnsupportedOperationException("When configuring a master step " + - "for remote chunking, the item writer will be automatically set " + - "to an instance of ChunkMessageChannelItemWriter. The item writer " + - "must not be provided in this case."); - } - - @Override - public RemoteChunkingMasterStepBuilder readerIsTransactionalQueue() { - super.readerIsTransactionalQueue(); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder listener(ItemReadListener listener) { - super.listener(listener); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder listener(ItemWriteListener listener) { - super.listener(listener); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder chunkOperations(RepeatOperations repeatTemplate) { - super.chunkOperations(repeatTemplate); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder exceptionHandler(ExceptionHandler exceptionHandler) { - super.exceptionHandler(exceptionHandler); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder stepOperations(RepeatOperations repeatTemplate) { - super.stepOperations(repeatTemplate); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder startLimit(int startLimit) { - super.startLimit(startLimit); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder listener(StepExecutionListener listener) { - super.listener(listener); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder allowStartIfComplete(boolean allowStartIfComplete) { - super.allowStartIfComplete(allowStartIfComplete); - return this; - } - - @Override - public RemoteChunkingMasterStepBuilder processor(ItemProcessor itemProcessor) { - super.processor(itemProcessor); - return this; - } -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingMasterStepBuilderFactory.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingMasterStepBuilderFactory.java deleted file mode 100644 index 44405a216..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingMasterStepBuilderFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2018-2019 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.integration.chunk; - -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.transaction.PlatformTransactionManager; - -/** - * Convenient factory for a {@link RemoteChunkingMasterStepBuilder} which sets - * the {@link JobRepository} and {@link PlatformTransactionManager} automatically. - * - * @deprecated Use {@link RemoteChunkingManagerStepBuilderFactory} instead. - * - * @since 4.1 - * @author Mahmoud Ben Hassine - */ -@Deprecated -public class RemoteChunkingMasterStepBuilderFactory { - - private JobRepository jobRepository; - - private PlatformTransactionManager transactionManager; - - /** - * Create a new {@link RemoteChunkingMasterStepBuilderFactory}. - * - * @param jobRepository the job repository to use - * @param transactionManager the transaction manager to use - */ - public RemoteChunkingMasterStepBuilderFactory( - JobRepository jobRepository, - PlatformTransactionManager transactionManager) { - - this.jobRepository = jobRepository; - this.transactionManager = transactionManager; - } - - /** - * Creates a {@link RemoteChunkingMasterStepBuilder} and initializes its job - * repository and transaction manager. - * - * @param name the name of the step - * @param type of input items - * @param type of output items - * @return a {@link RemoteChunkingMasterStepBuilder} - */ - public RemoteChunkingMasterStepBuilder get(String name) { - return new RemoteChunkingMasterStepBuilder(name) - .repository(this.jobRepository) - .transactionManager(this.transactionManager); - } - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java index b4efa1db4..3a973f571 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-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. @@ -17,10 +17,8 @@ package org.springframework.batch.integration.config.annotation; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.integration.chunk.RemoteChunkingMasterStepBuilderFactory; import org.springframework.batch.integration.chunk.RemoteChunkingManagerStepBuilderFactory; import org.springframework.batch.integration.chunk.RemoteChunkingWorkerBuilder; -import org.springframework.batch.integration.partition.RemotePartitioningMasterStepBuilderFactory; import org.springframework.batch.integration.partition.RemotePartitioningManagerStepBuilderFactory; import org.springframework.batch.integration.partition.RemotePartitioningWorkerStepBuilderFactory; import org.springframework.beans.factory.InitializingBean; @@ -44,14 +42,10 @@ public class BatchIntegrationConfiguration implements InitializingBean { private PlatformTransactionManager transactionManager; - private RemoteChunkingMasterStepBuilderFactory remoteChunkingMasterStepBuilderFactory; - private RemoteChunkingManagerStepBuilderFactory remoteChunkingManagerStepBuilderFactory; private RemoteChunkingWorkerBuilder remoteChunkingWorkerBuilder; - private RemotePartitioningMasterStepBuilderFactory remotePartitioningMasterStepBuilderFactory; - private RemotePartitioningManagerStepBuilderFactory remotePartitioningManagerStepBuilderFactory; private RemotePartitioningWorkerStepBuilderFactory remotePartitioningWorkerStepBuilderFactory; @@ -67,12 +61,6 @@ public class BatchIntegrationConfiguration implements InitializingBean { this.transactionManager = transactionManager; } - @Deprecated - @Bean - public RemoteChunkingMasterStepBuilderFactory remoteChunkingMasterStepBuilderFactory() { - return this.remoteChunkingMasterStepBuilderFactory; - } - @Bean public RemoteChunkingManagerStepBuilderFactory remoteChunkingManagerStepBuilderFactory() { return this.remoteChunkingManagerStepBuilderFactory; @@ -83,12 +71,6 @@ public class BatchIntegrationConfiguration implements InitializingBean { return remoteChunkingWorkerBuilder; } - @Deprecated - @Bean - public RemotePartitioningMasterStepBuilderFactory remotePartitioningMasterStepBuilderFactory() { - return remotePartitioningMasterStepBuilderFactory; - } - @Bean public RemotePartitioningManagerStepBuilderFactory remotePartitioningManagerStepBuilderFactory() { return this.remotePartitioningManagerStepBuilderFactory; @@ -101,13 +83,9 @@ public class BatchIntegrationConfiguration implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { - this.remoteChunkingMasterStepBuilderFactory = new RemoteChunkingMasterStepBuilderFactory(this.jobRepository, - this.transactionManager); this.remoteChunkingManagerStepBuilderFactory = new RemoteChunkingManagerStepBuilderFactory(this.jobRepository, this.transactionManager); this.remoteChunkingWorkerBuilder = new RemoteChunkingWorkerBuilder<>(); - this.remotePartitioningMasterStepBuilderFactory = new RemotePartitioningMasterStepBuilderFactory(this.jobRepository, - this.jobExplorer, this.transactionManager); this.remotePartitioningManagerStepBuilderFactory = new RemotePartitioningManagerStepBuilderFactory(this.jobRepository, this.jobExplorer, this.transactionManager); this.remotePartitioningWorkerStepBuilderFactory = new RemotePartitioningWorkerStepBuilderFactory(this.jobRepository, diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java index e870b693c..2d6bba008 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-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. @@ -35,9 +35,5 @@ public class BatchIntegrationNamespaceHandler extends AbstractIntegrationNamespa this.registerBeanDefinitionParser("remote-chunking-manager", remoteChunkingManagerParser); RemoteChunkingWorkerParser remoteChunkingWorkerParser = new RemoteChunkingWorkerParser(); this.registerBeanDefinitionParser("remote-chunking-worker", remoteChunkingWorkerParser); - - // TODO remove the following when related deprecated APIs are removed - this.registerBeanDefinitionParser("remote-chunking-master", remoteChunkingManagerParser); - this.registerBeanDefinitionParser("remote-chunking-slave", remoteChunkingWorkerParser); } } diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilder.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilder.java deleted file mode 100644 index ae3397b5d..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilder.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2018-2019 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.integration.partition; - -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecutionListener; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.partition.PartitionHandler; -import org.springframework.batch.core.partition.StepExecutionSplitter; -import org.springframework.batch.core.partition.support.Partitioner; -import org.springframework.batch.core.partition.support.StepExecutionAggregator; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.step.builder.PartitionStepBuilder; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.integration.channel.QueueChannel; -import org.springframework.integration.core.MessagingTemplate; -import org.springframework.integration.dsl.IntegrationFlows; -import org.springframework.integration.dsl.StandardIntegrationFlow; -import org.springframework.integration.dsl.context.IntegrationFlowContext; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.PollableChannel; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.util.Assert; - -/** - * Builder for a master step in a remote partitioning setup. This builder creates and - * sets a {@link MessageChannelPartitionHandler} on the master step. - * - *

If no {@code messagingTemplate} is provided through - * {@link RemotePartitioningMasterStepBuilder#messagingTemplate(MessagingTemplate)}, - * this builder will create one and set its default channel to the {@code outputChannel} - * provided through {@link RemotePartitioningMasterStepBuilder#outputChannel(MessageChannel)}.

- * - *

If a {@code messagingTemplate} is provided, it is assumed that it is fully configured - * and that its default channel is set to an output channel on which requests to workers - * will be sent.

- * - * @deprecated Use {@link RemotePartitioningManagerStepBuilder} instead. - * - * @since 4.1 - * @author Mahmoud Ben Hassine - */ -@Deprecated -public class RemotePartitioningMasterStepBuilder extends PartitionStepBuilder { - - private static final long DEFAULT_POLL_INTERVAL = 10000L; - private static final long DEFAULT_TIMEOUT = -1L; - - private MessagingTemplate messagingTemplate; - private MessageChannel inputChannel; - private MessageChannel outputChannel; - private JobExplorer jobExplorer; - private BeanFactory beanFactory; - private long pollInterval = DEFAULT_POLL_INTERVAL; - private long timeout = DEFAULT_TIMEOUT; - - /** - * Create a new {@link RemotePartitioningMasterStepBuilder}. - * @param stepName name of the master step - */ - public RemotePartitioningMasterStepBuilder(String stepName) { - super(new StepBuilder(stepName)); - } - - /** - * Set the input channel on which replies from workers will be received. - * @param inputChannel the input channel - * @return this builder instance for fluent chaining - */ - public RemotePartitioningMasterStepBuilder inputChannel(MessageChannel inputChannel) { - Assert.notNull(inputChannel, "inputChannel must not be null"); - this.inputChannel = inputChannel; - return this; - } - - /** - * Set the output channel on which requests to workers will be sent. By using - * this setter, a default messaging template will be created and the output - * channel will be set as its default channel. - *

Use either this setter or {@link RemotePartitioningMasterStepBuilder#messagingTemplate(MessagingTemplate)} - * to provide a fully configured messaging template.

- * - * @param outputChannel the output channel. - * @return this builder instance for fluent chaining - * @see RemotePartitioningMasterStepBuilder#messagingTemplate(MessagingTemplate) - */ - public RemotePartitioningMasterStepBuilder outputChannel(MessageChannel outputChannel) { - Assert.notNull(outputChannel, "outputChannel must not be null"); - this.outputChannel = outputChannel; - return this; - } - - /** - * Set the {@link MessagingTemplate} to use to send data to workers. - * The default channel of the messaging template must be set. - *

Use either this setter to provide a fully configured messaging template or - * provide an output channel through {@link RemotePartitioningMasterStepBuilder#outputChannel(MessageChannel)} - * and a default messaging template will be created.

- * - * @param messagingTemplate the messaging template to use - * @return this builder instance for fluent chaining - * @see RemotePartitioningMasterStepBuilder#outputChannel(MessageChannel) - */ - public RemotePartitioningMasterStepBuilder messagingTemplate(MessagingTemplate messagingTemplate) { - Assert.notNull(messagingTemplate, "messagingTemplate must not be null"); - this.messagingTemplate = messagingTemplate; - return this; - } - - /** - * Set the job explorer. - * @param jobExplorer the job explorer to use. - * @return this builder instance for fluent chaining - */ - public RemotePartitioningMasterStepBuilder jobExplorer(JobExplorer jobExplorer) { - Assert.notNull(jobExplorer, "jobExplorer must not be null"); - this.jobExplorer = jobExplorer; - return this; - } - - /** - * How often to poll the job repository for the status of the workers. Defaults to 10 seconds. - * @param pollInterval the poll interval value in milliseconds - * @return this builder instance for fluent chaining - */ - public RemotePartitioningMasterStepBuilder pollInterval(long pollInterval) { - Assert.isTrue(pollInterval > 0, "The poll interval must be greater than zero"); - this.pollInterval = pollInterval; - return this; - } - - /** - * When using job repository polling, the time limit to wait. Defaults to -1 (no timeout). - * @param timeout the timeout value in milliseconds - * @return this builder instance for fluent chaining - */ - public RemotePartitioningMasterStepBuilder timeout(long timeout) { - this.timeout = timeout; - return this; - } - - /** - * Set the bean factory. - * @param beanFactory the bean factory to use - * @return this builder instance for fluent chaining - */ - public RemotePartitioningMasterStepBuilder beanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - return this; - } - - public Step build() { - Assert.state(this.outputChannel == null || this.messagingTemplate == null, - "You must specify either an outputChannel or a messagingTemplate but not both."); - - // configure messaging template - if (this.messagingTemplate == null) { - this.messagingTemplate = new MessagingTemplate(); - this.messagingTemplate.setDefaultChannel(this.outputChannel); - if (this.logger.isDebugEnabled()) { - this.logger.debug("No messagingTemplate was provided, using a default one"); - } - } - - // Configure the partition handler - final MessageChannelPartitionHandler partitionHandler = new MessageChannelPartitionHandler(); - partitionHandler.setStepName(getStepName()); - partitionHandler.setGridSize(getGridSize()); - partitionHandler.setMessagingOperations(this.messagingTemplate); - - if (isPolling()) { - partitionHandler.setJobExplorer(this.jobExplorer); - partitionHandler.setPollInterval(this.pollInterval); - partitionHandler.setTimeout(this.timeout); - } - else { - PollableChannel replies = new QueueChannel(); - partitionHandler.setReplyChannel(replies); - StandardIntegrationFlow standardIntegrationFlow = IntegrationFlows - .from(this.inputChannel) - .aggregate(aggregatorSpec -> aggregatorSpec.processor(partitionHandler)) - .channel(replies) - .get(); - IntegrationFlowContext integrationFlowContext = this.beanFactory.getBean(IntegrationFlowContext.class); - integrationFlowContext.registration(standardIntegrationFlow) - .autoStartup(false) - .register(); - } - - try { - partitionHandler.afterPropertiesSet(); - super.partitionHandler(partitionHandler); - } - catch (Exception e) { - throw new BeanCreationException("Unable to create a master step for remote partitioning", e); - } - - return super.build(); - } - - private boolean isPolling() { - return this.inputChannel == null; - } - - @Override - public RemotePartitioningMasterStepBuilder repository(JobRepository jobRepository) { - super.repository(jobRepository); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder transactionManager(PlatformTransactionManager transactionManager) { - super.transactionManager(transactionManager); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder partitioner(String slaveStepName, Partitioner partitioner) { - super.partitioner(slaveStepName, partitioner); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder gridSize(int gridSize) { - super.gridSize(gridSize); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder step(Step step) { - super.step(step); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder splitter(StepExecutionSplitter splitter) { - super.splitter(splitter); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder aggregator(StepExecutionAggregator aggregator) { - super.aggregator(aggregator); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder startLimit(int startLimit) { - super.startLimit(startLimit); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder listener(Object listener) { - super.listener(listener); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder listener(StepExecutionListener listener) { - super.listener(listener); - return this; - } - - @Override - public RemotePartitioningMasterStepBuilder allowStartIfComplete(boolean allowStartIfComplete) { - super.allowStartIfComplete(allowStartIfComplete); - return this; - } - - /** - * This method will throw a {@link UnsupportedOperationException} since - * the partition handler of the master step will be automatically set to an - * instance of {@link MessageChannelPartitionHandler}. - * - * When building a master step for remote partitioning using this builder, - * no partition handler must be provided. - * - * @param partitionHandler a partition handler - * @return this builder instance for fluent chaining - * @throws UnsupportedOperationException if a partition handler is provided - */ - @Override - public RemotePartitioningMasterStepBuilder partitionHandler(PartitionHandler partitionHandler) throws UnsupportedOperationException { - throw new UnsupportedOperationException("When configuring a master step " + - "for remote partitioning using the RemotePartitioningMasterStepBuilder, " + - "the partition handler will be automatically set to an instance " + - "of MessageChannelPartitionHandler. The partition handler must " + - "not be provided in this case."); - } - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilderFactory.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilderFactory.java deleted file mode 100644 index 7d8249c82..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilderFactory.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2018-2019 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.integration.partition; - -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.transaction.PlatformTransactionManager; - -/** - * Convenient factory for a {@link RemotePartitioningMasterStepBuilder} which sets - * the {@link JobRepository}, {@link JobExplorer}, {@link BeanFactory} and - * {@link PlatformTransactionManager} automatically. - * - * @deprecated Use {@link RemotePartitioningManagerStepBuilderFactory} instead - * - * @since 4.1 - * @author Mahmoud Ben Hassine - */ -@Deprecated -public class RemotePartitioningMasterStepBuilderFactory implements BeanFactoryAware { - - private BeanFactory beanFactory; - final private JobExplorer jobExplorer; - final private JobRepository jobRepository; - final private PlatformTransactionManager transactionManager; - - - /** - * Create a new {@link RemotePartitioningMasterStepBuilderFactory}. - * @param jobRepository the job repository to use - * @param jobExplorer the job explorer to use - * @param transactionManager the transaction manager to use - */ - public RemotePartitioningMasterStepBuilderFactory(JobRepository jobRepository, - JobExplorer jobExplorer, PlatformTransactionManager transactionManager) { - - this.jobRepository = jobRepository; - this.jobExplorer = jobExplorer; - this.transactionManager = transactionManager; - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - - /** - * Creates a {@link RemotePartitioningMasterStepBuilder} and initializes its job - * repository, job explorer, bean factory and transaction manager. - * @param name the name of the step - * @return a {@link RemotePartitioningMasterStepBuilder} - */ - public RemotePartitioningMasterStepBuilder get(String name) { - return new RemotePartitioningMasterStepBuilder(name) - .repository(this.jobRepository) - .jobExplorer(this.jobExplorer) - .beanFactory(this.beanFactory) - .transactionManager(this.transactionManager); - } - -} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/RemoteChunkingParserTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/RemoteChunkingParserTests.java index 8f59844dc..0643b0728 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/RemoteChunkingParserTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/RemoteChunkingParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-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. @@ -54,227 +54,6 @@ import static org.junit.Assert.fail; @SuppressWarnings("unchecked") public class RemoteChunkingParserTests { - /* TODO delete the following deprecated tests when related APIs are removed - * /!\ Deliberately not using parametrized tests as it will be easier to delete - * the following tests afterwards - */ - @SuppressWarnings("rawtypes") - @Test - public void testRemoteChunkingSlaveParserWithProcessorDefined() { - ApplicationContext applicationContext = - new ClassPathXmlApplicationContext("/org/springframework/batch/integration/config/xml/RemoteChunkingSlaveParserTests.xml"); - - ChunkHandler chunkHandler = applicationContext.getBean(ChunkProcessorChunkHandler.class); - ChunkProcessor chunkProcessor = (SimpleChunkProcessor) TestUtils.getPropertyValue(chunkHandler, "chunkProcessor"); - assertNotNull("ChunkProcessor must not be null", chunkProcessor); - - ItemWriter itemWriter = (ItemWriter) TestUtils.getPropertyValue(chunkProcessor, "itemWriter"); - assertNotNull("ChunkProcessor ItemWriter must not be null", itemWriter); - assertTrue("Got wrong instance of ItemWriter", itemWriter instanceof Writer); - - ItemProcessor itemProcessor = (ItemProcessor) TestUtils.getPropertyValue(chunkProcessor, "itemProcessor"); - assertNotNull("ChunkProcessor ItemWriter must not be null", itemProcessor); - assertTrue("Got wrong instance of ItemProcessor", itemProcessor instanceof Processor); - - FactoryBean serviceActivatorFactoryBean = applicationContext.getBean(ServiceActivatorFactoryBean.class); - assertNotNull("ServiceActivatorFactoryBean must not be null", serviceActivatorFactoryBean); - assertNotNull("Output channel name must not be null", TestUtils.getPropertyValue(serviceActivatorFactoryBean, "outputChannelName")); - - MessageChannel inputChannel = applicationContext.getBean("requests", MessageChannel.class); - assertNotNull("Input channel must not be null", inputChannel); - - String targetMethodName = (String) TestUtils.getPropertyValue(serviceActivatorFactoryBean, "targetMethodName"); - assertNotNull("Target method name must not be null", targetMethodName); - assertTrue("Target method name must be handleChunk, got: " + targetMethodName, "handleChunk".equals(targetMethodName)); - - ChunkHandler targetObject = (ChunkHandler) TestUtils.getPropertyValue(serviceActivatorFactoryBean, "targetObject"); - assertNotNull("Target object must not be null", targetObject); - } - - @SuppressWarnings("rawtypes") - @Test - public void testRemoteChunkingSlaveParserWithProcessorNotDefined() { - ApplicationContext applicationContext = - new ClassPathXmlApplicationContext("/org/springframework/batch/integration/config/xml/RemoteChunkingSlaveParserNoProcessorTests.xml"); - - ChunkHandler chunkHandler = applicationContext.getBean(ChunkProcessorChunkHandler.class); - ChunkProcessor chunkProcessor = (SimpleChunkProcessor) TestUtils.getPropertyValue(chunkHandler, "chunkProcessor"); - assertNotNull("ChunkProcessor must not be null", chunkProcessor); - - ItemProcessor itemProcessor = (ItemProcessor) TestUtils.getPropertyValue(chunkProcessor, "itemProcessor"); - assertNotNull("ChunkProcessor ItemWriter must not be null", itemProcessor); - assertTrue("Got wrong instance of ItemProcessor", itemProcessor instanceof PassThroughItemProcessor); - } - - @SuppressWarnings("rawtypes") - @Test - public void testRemoteChunkingMasterParser() { - ApplicationContext applicationContext = - new ClassPathXmlApplicationContext("/org/springframework/batch/integration/config/xml/RemoteChunkingMasterParserTests.xml"); - - ItemWriter itemWriter = applicationContext.getBean("itemWriter", ChunkMessageChannelItemWriter.class); - assertNotNull("Messaging template must not be null", TestUtils.getPropertyValue(itemWriter, "messagingGateway")); - assertNotNull("Reply channel must not be null", TestUtils.getPropertyValue(itemWriter, "replyChannel")); - - FactoryBean remoteChunkingHandlerFactoryBean = applicationContext.getBean(RemoteChunkHandlerFactoryBean.class); - assertNotNull("Chunk writer must not be null", TestUtils.getPropertyValue(remoteChunkingHandlerFactoryBean, "chunkWriter")); - assertNotNull("Step must not be null", TestUtils.getPropertyValue(remoteChunkingHandlerFactoryBean, "step")); - } - - @Test - public void testRemoteChunkingMasterIdAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingMasterParserMissingIdAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The id attribute must be specified" + " but got: " + iae.getMessage(), - "The id attribute must be specified".equals(iae.getMessage())); - } - } - - @Test - public void testRemoteChunkingMasterMessageTemplateAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingMasterParserMissingMessageTemplateAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The message-template attribute must be specified" + " but got: " + iae.getMessage(), - "The message-template attribute must be specified".equals(iae.getMessage())); - } - } - - @Test - public void testRemoteChunkingMasterStepAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingMasterParserMissingStepAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The step attribute must be specified" + " but got: " + iae.getMessage(), - "The step attribute must be specified".equals(iae.getMessage())); - } - } - - @Test - public void testRemoteChunkingMasterReplyChannelAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingMasterParserMissingReplyChannelAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The reply-channel attribute must be specified" + " but got: " + iae.getMessage(), - "The reply-channel attribute must be specified".equals(iae.getMessage())); - } - } - - @Test - public void testRemoteChunkingSlaveIdAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingSlaveParserMissingIdAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The id attribute must be specified" + " but got: " + iae.getMessage(), - "The id attribute must be specified".equals(iae.getMessage())); - } - } - - @Test - public void testRemoteChunkingSlaveInputChannelAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingSlaveParserMissingInputChannelAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The input-channel attribute must be specified" + " but got: " + iae.getMessage(), - "The input-channel attribute must be specified".equals(iae.getMessage())); - } - } - - @Test - public void testRemoteChunkingSlaveItemWriterAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingSlaveParserMissingItemWriterAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The item-writer attribute must be specified" + " but got: " + iae.getMessage(), - "The item-writer attribute must be specified".equals(iae.getMessage())); - } - } - - @Test - public void testRemoteChunkingSlaveOutputChannelAttrAssert() throws Exception { - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.setValidating(false); - applicationContext.setConfigLocation("/org/springframework/batch/integration/config/xml/RemoteChunkingSlaveParserMissingOutputChannelAttrTests.xml"); - - try { - applicationContext.refresh(); - fail(); - } catch (BeanDefinitionStoreException e) { - assertTrue("Nested exception must be of type IllegalArgumentException", e.getCause() instanceof IllegalArgumentException); - - IllegalArgumentException iae = (IllegalArgumentException) e.getCause(); - - assertTrue("Expected: " + "The output-channel attribute must be specified" + " but got: " + iae.getMessage(), - "The output-channel attribute must be specified".equals(iae.getMessage())); - } - } - - /* TODO end of deprecated tests to remove */ - @SuppressWarnings("rawtypes") @Test public void testRemoteChunkingWorkerParserWithProcessorDefined() { diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilderTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilderTests.java index cedd3e1fb..3e6d2281a 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilderTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningMasterStepBuilderTests.java @@ -55,7 +55,7 @@ public class RemotePartitioningMasterStepBuilderTests { @Test public void inputChannelMustNotBeNull() { // given - final RemotePartitioningMasterStepBuilder builder = new RemotePartitioningMasterStepBuilder("step"); + final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step"); // when final Exception expectedException = Assert.assertThrows(IllegalArgumentException.class, @@ -68,7 +68,7 @@ public class RemotePartitioningMasterStepBuilderTests { @Test public void outputChannelMustNotBeNull() { // given - final RemotePartitioningMasterStepBuilder builder = new RemotePartitioningMasterStepBuilder("step"); + final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step"); // when final Exception expectedException = Assert.assertThrows(IllegalArgumentException.class, @@ -81,7 +81,7 @@ public class RemotePartitioningMasterStepBuilderTests { @Test public void messagingTemplateMustNotBeNull() { // given - final RemotePartitioningMasterStepBuilder builder = new RemotePartitioningMasterStepBuilder("step"); + final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step"); // when final Exception expectedException = Assert.assertThrows(IllegalArgumentException.class, @@ -94,7 +94,7 @@ public class RemotePartitioningMasterStepBuilderTests { @Test public void jobExplorerMustNotBeNull() { // given - final RemotePartitioningMasterStepBuilder builder = new RemotePartitioningMasterStepBuilder("step"); + final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step"); // when final Exception expectedException = Assert.assertThrows(IllegalArgumentException.class, @@ -107,7 +107,7 @@ public class RemotePartitioningMasterStepBuilderTests { @Test public void pollIntervalMustBeGreaterThanZero() { // given - final RemotePartitioningMasterStepBuilder builder = new RemotePartitioningMasterStepBuilder("step"); + final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step"); // when final Exception expectedException = Assert.assertThrows(IllegalArgumentException.class, @@ -120,7 +120,7 @@ public class RemotePartitioningMasterStepBuilderTests { @Test public void eitherOutputChannelOrMessagingTemplateMustBeProvided() { // given - RemotePartitioningMasterStepBuilder builder = new RemotePartitioningMasterStepBuilder("step") + RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step") .outputChannel(new DirectChannel()) .messagingTemplate(new MessagingTemplate()); @@ -136,15 +136,15 @@ public class RemotePartitioningMasterStepBuilderTests { public void testUnsupportedOperationExceptionWhenSpecifyingPartitionHandler() { // given PartitionHandler partitionHandler = Mockito.mock(PartitionHandler.class); - final RemotePartitioningMasterStepBuilder builder = new RemotePartitioningMasterStepBuilder("step"); + final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step"); // when final Exception expectedException = Assert.assertThrows(UnsupportedOperationException.class, () -> builder.partitionHandler(partitionHandler)); // then - assertThat(expectedException).hasMessage("When configuring a master step " + - "for remote partitioning using the RemotePartitioningMasterStepBuilder, " + + assertThat(expectedException).hasMessage("When configuring a manager step " + + "for remote partitioning using the RemotePartitioningManagerStepBuilder, " + "the partition handler will be automatically set to an instance " + "of MessageChannelPartitionHandler. The partition handler must " + "not be provided in this case."); @@ -162,7 +162,7 @@ public class RemotePartitioningMasterStepBuilderTests { StepExecutionAggregator stepExecutionAggregator = (result, executions) -> { }; // when - Step step = new RemotePartitioningMasterStepBuilder("masterStep") + Step step = new RemotePartitioningManagerStepBuilder("masterStep") .repository(jobRepository) .outputChannel(outputChannel) .partitioner("workerStep", partitioner) @@ -205,7 +205,7 @@ public class RemotePartitioningMasterStepBuilderTests { StepExecutionAggregator stepExecutionAggregator = (result, executions) -> { }; // when - Step step = new RemotePartitioningMasterStepBuilder("masterStep") + Step step = new RemotePartitioningManagerStepBuilder("masterStep") .repository(jobRepository) .outputChannel(outputChannel) .partitioner("workerStep", partitioner) diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/AbstractJobTests.java b/spring-batch-test/src/main/java/org/springframework/batch/test/AbstractJobTests.java deleted file mode 100644 index c18af29c4..000000000 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/AbstractJobTests.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2006-2007 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.test; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameter; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.job.AbstractJob; -import org.springframework.batch.core.job.SimpleJob; -import org.springframework.batch.core.job.flow.FlowJob; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -/** - *

- * Base class for testing batch jobs. It provides methods for launching an - * entire {@link AbstractJob}, allowing for end to end testing of individual - * steps, without having to run every step in the job. Any test classes - * inheriting from this class should make sure they are part of an - * {@link ApplicationContext}, which is generally expected to be done as part of - * the Spring test framework. Furthermore, the {@link ApplicationContext} in - * which it is a part of is expected to have one {@link JobLauncher}, - * {@link JobRepository}, and a single {@link AbstractJob} implementation. - * - *

- * This class also provides the ability to run {@link Step}s from a - * {@link FlowJob} or {@link SimpleJob} individually. By launching {@link Step}s - * within a {@link Job} on their own, end to end testing of individual steps can - * be performed without having to run every step in the job. - * - *

- * It should be noted that using any of the methods that don't contain - * {@link JobParameters} in their signature, will result in one being created - * with the current system time as a parameter. This will ensure restartability - * when no parameters are provided. - * - * @author Lucas Ward - * @author Dan Garrette - * @since 2.0 - * - * @deprecated (from 2.1) use {@link JobLauncherTestUtils} instead - */ -@Deprecated -public abstract class AbstractJobTests implements ApplicationContextAware { - - /** Logger */ - protected final Log logger = LogFactory.getLog(getClass()); - - @Autowired - private JobLauncher launcher; - - @Autowired - private AbstractJob job; - - @Autowired - private JobRepository jobRepository; - - private StepRunner stepRunner; - - private ApplicationContext applicationContext; - - /** - * {@inheritDoc} - */ - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - /** - * @return the applicationContext - */ - protected ApplicationContext getApplicationContext() { - return applicationContext; - } - - /** - * @return the job repository which is autowired by type - */ - public JobRepository getJobRepository() { - return jobRepository; - } - - /** - * @return the job which is autowired by type - */ - public AbstractJob getJob() { - return job; - } - - /** - * @return the launcher - */ - protected JobLauncher getJobLauncher() { - return launcher; - } - - /** - * Launch the entire job, including all steps. - * - * @return JobExecution, so that the test can validate the exit status - * - * @throws Exception is thrown if error occurs. - */ - protected JobExecution launchJob() throws Exception { - return this.launchJob(this.getUniqueJobParameters()); - } - - /** - * Launch the entire job, including all steps - * - * @param jobParameters parameters for the job - * @return JobExecution, so that the test can validate the exit status - * - * @throws Exception is thrown if error occurs. - */ - protected JobExecution launchJob(JobParameters jobParameters) throws Exception { - return getJobLauncher().run(this.job, jobParameters); - } - - /** - * @return a new JobParameters object containing only a parameter for the - * current timestamp, to ensure that the job instance will be unique. - */ - protected JobParameters getUniqueJobParameters() { - Map parameters = new HashMap<>(); - parameters.put("timestamp", new JobParameter(new Date().getTime())); - return new JobParameters(parameters); - } - - /** - * Convenient method for subclasses to grab a {@link StepRunner} for running - * steps by name. - * - * @return a {@link StepRunner} - */ - protected StepRunner getStepRunner() { - if (this.stepRunner == null) { - this.stepRunner = new StepRunner(getJobLauncher(), getJobRepository()); - } - return this.stepRunner; - } - - /** - * Launch just the specified step in the job. A unique set of JobParameters - * will automatically be generated. An IllegalStateException is thrown if - * there is no Step with the given name. - * - * @param stepName The name of the step to launch - * @return JobExecution - */ - public JobExecution launchStep(String stepName) { - return this.launchStep(stepName, this.getUniqueJobParameters(), null); - } - - /** - * Launch just the specified step in the job. A unique set of JobParameters - * will automatically be generated. An IllegalStateException is thrown if - * there is no Step with the given name. - * - * @param stepName The name of the step to launch - * @param jobExecutionContext An ExecutionContext whose values will be - * loaded into the Job ExecutionContext prior to launching the step. - * @return JobExecution - */ - public JobExecution launchStep(String stepName, ExecutionContext jobExecutionContext) { - return this.launchStep(stepName, this.getUniqueJobParameters(), jobExecutionContext); - } - - /** - * Launch just the specified step in the job. An IllegalStateException is - * thrown if there is no Step with the given name. - * - * @param stepName The name of the step to launch - * @param jobParameters The JobParameters to use during the launch - * @return JobExecution - */ - public JobExecution launchStep(String stepName, JobParameters jobParameters) { - return this.launchStep(stepName, jobParameters, null); - } - - /** - * Launch just the specified step in the job. An IllegalStateException is - * thrown if there is no Step with the given name. - * - * @param stepName The name of the step to launch - * @param jobParameters The JobParameters to use during the launch - * @param jobExecutionContext An ExecutionContext whose values will be - * loaded into the Job ExecutionContext prior to launching the step. - * @return JobExecution - */ - public JobExecution launchStep(String stepName, JobParameters jobParameters, ExecutionContext jobExecutionContext) { - Step step = this.job.getStep(stepName); - if (step == null) { - step = this.job.getStep(this.job.getName() + "." + stepName); - } - if (step == null) { - throw new IllegalStateException("No Step found with name: [" + stepName + "]"); - } - return getStepRunner().launchStep(step, jobParameters, jobExecutionContext); - } -} diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractSampleJobTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractSampleJobTests.java index 23cf140b1..3baa37e0c 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractSampleJobTests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractSampleJobTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2014 the original author or authors. + * Copyright 2009-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. @@ -27,12 +27,11 @@ import org.springframework.batch.test.sample.SampleTasklet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.test.annotation.Repeat; +import org.springframework.test.annotation.Repeat; import org.springframework.test.context.ContextConfiguration; /** - * This is an abstract test class to be used by test classes to test the - * {@link AbstractJobTests} class. + * This is an abstract test class. * * @author Dan Garrette * @since 2.0 @@ -90,13 +89,13 @@ public abstract class AbstractSampleJobTests { } @Test - @Repeat(10) - public void testStep3Execution() throws Exception { - // logging only, may complete in < 1ms (repeat so that it's likely to for at least one of those times) - assertEquals(BatchStatus.COMPLETED, jobLauncherTestUtils.launchStep("step3").getStatus()); - } - - @Test + @Repeat(10) + public void testStep3Execution() throws Exception { + // logging only, may complete in < 1ms (repeat so that it's likely to for at least one of those times) + assertEquals(BatchStatus.COMPLETED, jobLauncherTestUtils.launchStep("step3").getStatus()); + } + + @Test public void testStepLaunchJobContextEntry() { ExecutionContext jobContext = new ExecutionContext(); jobContext.put("key1", "value1");