diff --git a/.gitignore b/.gitignore index c64a0d4ec..e34622327 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,4 @@ build out /.gradletasknamecache -/spring-batch-jsr352-tck/jsr352-tck-1.0/results/ **/*.flattened-pom.xml diff --git a/pom.xml b/pom.xml index 9f1b4cbaa..4d09f99d2 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,6 @@ spring-batch-test spring-batch-integration spring-batch-samples - spring-batch-jsr352-tck spring-batch-docs @@ -72,7 +71,6 @@ 2.0.0 2.0.1 3.0.0 - 2.0.0 3.0.0 3.0.0 3.2.21 @@ -111,7 +109,6 @@ 9.2.1.jre8 1.3.1 1.16.2 - 1.0 1.5.0 diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index 28e240455..137ee944f 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -50,11 +50,6 @@ jackson-databind ${jackson.version} - - jakarta.batch - jakarta.batch-api - ${jakarta.batch-api.version} - io.micrometer micrometer-core @@ -256,12 +251,6 @@ ${jaxb-core.version} test - - com.ibm.jbatch - com.ibm.jbatch-tck-spi - ${com.ibm.jbatch-tck-spi.version} - test - jakarta.inject jakarta.inject-api diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java b/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java index 05a4757a7..4bedd5af4 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java @@ -108,29 +108,6 @@ public enum BatchStatus { return this.compareTo(other) <= 0; } - /** - * Converts the current status to the JSR-352 equivalent - * - * @return JSR-352 equivalent to the current status - */ - public jakarta.batch.runtime.BatchStatus getBatchStatus() { - if(this == ABANDONED) { - return jakarta.batch.runtime.BatchStatus.ABANDONED; - } else if(this == COMPLETED) { - return jakarta.batch.runtime.BatchStatus.COMPLETED; - } else if(this == STARTED) { - return jakarta.batch.runtime.BatchStatus.STARTED; - } else if(this == STARTING) { - return jakarta.batch.runtime.BatchStatus.STARTING; - } else if(this == STOPPED) { - return jakarta.batch.runtime.BatchStatus.STOPPED; - } else if(this == STOPPING) { - return jakarta.batch.runtime.BatchStatus.STOPPING; - } else { - return jakarta.batch.runtime.BatchStatus.FAILED; - } - } - /** * Find a BatchStatus that matches the beginning of the given value. If no * match is found, return COMPLETED as the default because has is low 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 c49f2d38e..7a378018e 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 @@ -65,8 +65,6 @@ public class JobExecution extends Entity { private transient volatile List failureExceptions = new CopyOnWriteArrayList<>(); - private final String jobConfigurationName; - public JobExecution(JobExecution original) { this.jobParameters = original.getJobParameters(); this.jobInstance = original.getJobInstance(); @@ -79,7 +77,6 @@ public class JobExecution extends Entity { this.exitStatus = original.getExitStatus(); this.executionContext = original.getExecutionContext(); this.failureExceptions = original.getFailureExceptions(); - this.jobConfigurationName = original.getJobConfigurationName(); this.setId(original.getId()); this.setVersion(original.getVersion()); } @@ -91,22 +88,11 @@ public class JobExecution extends Entity { * @param job the job of which this execution is a part * @param id {@link Long} that represents the id for the JobExecution. * @param jobParameters {@link JobParameters} instance for this JobExecution. - * @param jobConfigurationName {@link String} instance that represents the - * job configuration name (used with JSR-352). */ - public JobExecution(JobInstance job, Long id, @Nullable JobParameters jobParameters, String jobConfigurationName) { + public JobExecution(JobInstance job, Long id, @Nullable JobParameters jobParameters) { super(id); this.jobInstance = job; this.jobParameters = jobParameters == null ? new JobParameters() : jobParameters; - this.jobConfigurationName = jobConfigurationName; - } - - public JobExecution(JobInstance job, JobParameters jobParameters, String jobConfigurationName) { - this(job, null, jobParameters, jobConfigurationName); - } - - public JobExecution(Long id, JobParameters jobParameters, String jobConfigurationName) { - this(null, id, jobParameters, jobConfigurationName); } /** @@ -116,15 +102,15 @@ public class JobExecution extends Entity { * @param jobParameters {@link JobParameters} instance for this JobExecution. */ public JobExecution(JobInstance job, JobParameters jobParameters) { - this(job, null, jobParameters, null); + this(job, null, jobParameters); } public JobExecution(Long id, JobParameters jobParameters) { - this(null, id, jobParameters, null); + this(null, id, jobParameters); } public JobExecution(Long id) { - this(null, id, null, null); + this(null, id, null); } public JobParameters getJobParameters() { @@ -283,10 +269,6 @@ public class JobExecution extends Entity { this.createTime = createTime; } - public String getJobConfigurationName() { - return this.jobConfigurationName; - } - /** * Package private method for re-constituting the step executions from * existing instances. diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobInstance.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobInstance.java index 5c9aeb46c..7ca252362 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobInstance.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobInstance.java @@ -30,7 +30,6 @@ import org.springframework.util.Assert; * @see Job * @see JobParameters * @see JobExecution - * @see jakarta.batch.runtime.JobInstance * * @author Lucas Ward * @author Dave Syer @@ -40,7 +39,7 @@ import org.springframework.util.Assert; * */ @SuppressWarnings("serial") -public class JobInstance extends Entity implements jakarta.batch.runtime.JobInstance{ +public class JobInstance extends Entity { private final String jobName; @@ -53,7 +52,6 @@ public class JobInstance extends Entity implements jakarta.batch.runtime.JobInst /** * @return the job name. (Equivalent to getJob().getName()) */ - @Override public String getJobName() { return jobName; } @@ -63,7 +61,6 @@ public class JobInstance extends Entity implements jakarta.batch.runtime.JobInst return super.toString() + ", Job=[" + jobName + "]"; } - @Override public long getInstanceId() { return super.getId(); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java index d418546c4..66f80e540 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java @@ -25,13 +25,6 @@ import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; -import jakarta.batch.api.chunk.listener.RetryProcessListener; -import jakarta.batch.api.chunk.listener.RetryReadListener; -import jakarta.batch.api.chunk.listener.RetryWriteListener; -import jakarta.batch.api.chunk.listener.SkipProcessListener; -import jakarta.batch.api.chunk.listener.SkipReadListener; -import jakarta.batch.api.chunk.listener.SkipWriteListener; -import jakarta.batch.api.partition.PartitionCollector; import org.springframework.batch.core.ChunkListener; import org.springframework.batch.core.ItemProcessListener; @@ -43,16 +36,6 @@ import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecutionListener; import org.springframework.batch.core.StepListener; import org.springframework.batch.core.job.flow.Flow; -import org.springframework.batch.core.jsr.ChunkListenerAdapter; -import org.springframework.batch.core.jsr.ItemProcessListenerAdapter; -import org.springframework.batch.core.jsr.ItemReadListenerAdapter; -import org.springframework.batch.core.jsr.ItemWriteListenerAdapter; -import org.springframework.batch.core.jsr.RetryProcessListenerAdapter; -import org.springframework.batch.core.jsr.RetryReadListenerAdapter; -import org.springframework.batch.core.jsr.RetryWriteListenerAdapter; -import org.springframework.batch.core.jsr.SkipListenerAdapter; -import org.springframework.batch.core.jsr.StepListenerAdapter; -import org.springframework.batch.core.jsr.partition.PartitionCollectorAdapter; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.partition.PartitionHandler; import org.springframework.batch.core.partition.support.Partitioner; @@ -105,6 +88,7 @@ import org.springframework.util.Assert; * @author Josh Long * @author Michael Minella * @author Chris Schaefer + * @author Mahmoud Ben Hassine * @see SimpleStepFactoryBean * @see FaultTolerantStepFactoryBean * @see TaskletStep @@ -159,10 +143,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN private int gridSize = DEFAULT_GRID_SIZE; - private Queue partitionQueue; - - private ReentrantLock partitionLock; - // // Tasklet Elements // @@ -232,8 +212,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN private Set> skipListeners = new LinkedHashSet<>(); - private Set jsrRetryListeners = new LinkedHashSet<>(); - // // Additional // @@ -241,22 +219,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN private StepExecutionAggregator stepExecutionAggregator; - /** - * @param queue The {@link Queue} that is used for communication between {@link jakarta.batch.api.partition.PartitionCollector} and {@link jakarta.batch.api.partition.PartitionAnalyzer} - */ - public void setPartitionQueue(Queue queue) { - this.partitionQueue = queue; - } - - /** - * Used to coordinate access to the partition queue between the {@link jakarta.batch.api.partition.PartitionCollector} and {@link jakarta.batch.api.partition.AbstractPartitionAnalyzer} - * - * @param lock a lock that will be locked around accessing the partition queue - */ - public void setPartitionLock(ReentrantLock lock) { - this.partitionLock = lock; - } - /** * Create a {@link Step} from the configuration provided. * @@ -312,8 +274,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN for (Object listener : stepExecutionListeners) { if(listener instanceof StepExecutionListener) { builder.listener((StepExecutionListener) listener); - } else if(listener instanceof jakarta.batch.api.listener.StepListener) { - builder.listener(new StepListenerAdapter((jakarta.batch.api.listener.StepListener) listener)); } } } @@ -369,10 +329,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN builder.listener(listener); } - for (org.springframework.batch.core.jsr.RetryListener listener : jsrRetryListeners) { - builder.listener(listener); - } - registerItemListeners(builder); if (skipPolicy != null) { @@ -485,10 +441,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN enhanceCommonStep(builder); for (ChunkListener listener : chunkListeners) { - if(listener instanceof PartitionCollectorAdapter) { - ((PartitionCollectorAdapter) listener).setPartitionLock(partitionLock); - } - builder.listener(listener); } @@ -817,71 +769,26 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN SkipListener skipListener = (SkipListener) listener; skipListeners.add(skipListener); } - if(listener instanceof SkipReadListener) { - SkipListener skipListener = new SkipListenerAdapter<>((SkipReadListener) listener, null, null); - skipListeners.add(skipListener); - } - if(listener instanceof SkipProcessListener) { - SkipListener skipListener = new SkipListenerAdapter<>(null, (SkipProcessListener) listener, null); - skipListeners.add(skipListener); - } - if(listener instanceof SkipWriteListener) { - SkipListener skipListener = new SkipListenerAdapter<>(null, null, (SkipWriteListener) listener); - skipListeners.add(skipListener); - } if (listener instanceof StepExecutionListener) { StepExecutionListener stepExecutionListener = (StepExecutionListener) listener; stepExecutionListeners.add(stepExecutionListener); } - if(listener instanceof jakarta.batch.api.listener.StepListener) { - StepExecutionListener stepExecutionListener = new StepListenerAdapter((jakarta.batch.api.listener.StepListener) listener); - stepExecutionListeners.add(stepExecutionListener); - } if (listener instanceof ChunkListener) { ChunkListener chunkListener = (ChunkListener) listener; chunkListeners.add(chunkListener); } - if(listener instanceof jakarta.batch.api.chunk.listener.ChunkListener) { - ChunkListener chunkListener = new ChunkListenerAdapter((jakarta.batch.api.chunk.listener.ChunkListener) listener); - chunkListeners.add(chunkListener); - } if (listener instanceof ItemReadListener) { ItemReadListener readListener = (ItemReadListener) listener; readListeners.add(readListener); } - if(listener instanceof jakarta.batch.api.chunk.listener.ItemReadListener) { - ItemReadListener itemListener = new ItemReadListenerAdapter<>((jakarta.batch.api.chunk.listener.ItemReadListener) listener); - readListeners.add(itemListener); - } if (listener instanceof ItemWriteListener) { ItemWriteListener writeListener = (ItemWriteListener) listener; writeListeners.add(writeListener); } - if(listener instanceof jakarta.batch.api.chunk.listener.ItemWriteListener) { - ItemWriteListener itemListener = new ItemWriteListenerAdapter<>((jakarta.batch.api.chunk.listener.ItemWriteListener) listener); - writeListeners.add(itemListener); - } if (listener instanceof ItemProcessListener) { ItemProcessListener processListener = (ItemProcessListener) listener; processListeners.add(processListener); } - if(listener instanceof jakarta.batch.api.chunk.listener.ItemProcessListener) { - ItemProcessListener itemListener = new ItemProcessListenerAdapter<>((jakarta.batch.api.chunk.listener.ItemProcessListener) listener); - processListeners.add(itemListener); - } - if(listener instanceof RetryReadListener) { - jsrRetryListeners.add(new RetryReadListenerAdapter((RetryReadListener) listener)); - } - if(listener instanceof RetryProcessListener) { - jsrRetryListeners.add(new RetryProcessListenerAdapter((RetryProcessListener) listener)); - } - if(listener instanceof RetryWriteListener) { - jsrRetryListeners.add(new RetryWriteListenerAdapter((RetryWriteListener) listener)); - } - if(listener instanceof PartitionCollector) { - PartitionCollectorAdapter adapter = new PartitionCollectorAdapter(partitionQueue, (PartitionCollector) listener); - chunkListeners.add(adapter); - } } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ChunkListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ChunkListenerAdapter.java deleted file mode 100644 index 5554c524f..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ChunkListenerAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.batch.core.step.tasklet.UncheckedTransactionException; -import org.springframework.util.Assert; - -/** - * Wrapper class to adapt the {@link jakarta.batch.api.chunk.listener.ChunkListener} to - * a {@link ChunkListener}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class ChunkListenerAdapter implements ChunkListener { - - private final jakarta.batch.api.chunk.listener.ChunkListener delegate; - - /** - * @param delegate to be called within the step chunk lifecycle - */ - public ChunkListenerAdapter(jakarta.batch.api.chunk.listener.ChunkListener delegate) { - Assert.notNull(delegate, "A ChunkListener is required"); - this.delegate = delegate; - } - - @Override - public void beforeChunk(ChunkContext context) { - try { - delegate.beforeChunk(); - } catch (Exception e) { - throw new UncheckedTransactionException(e); - } - } - - @Override - public void afterChunk(ChunkContext context) { - try { - delegate.afterChunk(); - } catch (Exception e) { - throw new UncheckedTransactionException(e); - } - } - - @Override - public void afterChunkError(ChunkContext context) { - if(context != null) { - try { - delegate.onError((Exception) context.getAttribute(ChunkListener.ROLLBACK_EXCEPTION_KEY)); - } catch (Exception e) { - throw new UncheckedTransactionException(e); - } - } else { - throw new BatchRuntimeException("Unable to retrieve causing exception due to null ChunkContext"); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemProcessListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemProcessListenerAdapter.java deleted file mode 100644 index f221cc0e9..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemProcessListenerAdapter.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.ItemProcessListener; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Wrapper class for {@link jakarta.batch.api.chunk.listener.ItemProcessListener} - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * - * @param input type - * @param output type - * @since 3.0 - */ -public class ItemProcessListenerAdapter implements ItemProcessListener { - - private jakarta.batch.api.chunk.listener.ItemProcessListener delegate; - - /** - * @param delegate to be called within the batch lifecycle - */ - public ItemProcessListenerAdapter(jakarta.batch.api.chunk.listener.ItemProcessListener delegate) { - Assert.notNull(delegate, "An ItemProcessListener is required"); - this.delegate = delegate; - } - - @Override - public void beforeProcess(T item) { - try { - delegate.beforeProcess(item); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Override - public void afterProcess(T item, @Nullable S result) { - try { - delegate.afterProcess(item, result); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Override - public void onProcessError(T item, Exception e) { - try { - delegate.onProcessError(item, e); - } catch (Exception e1) { - throw new BatchRuntimeException(e1); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemReadListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemReadListenerAdapter.java deleted file mode 100644 index a37155bed..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemReadListenerAdapter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - * 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.jsr; - -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.ItemReadListener; -import org.springframework.batch.item.ItemReader; -import org.springframework.util.Assert; - -/** - * Wrapper class to adapt the {@link jakarta.batch.api.chunk.listener.ItemReadListener} to - * a {@link ItemReadListener}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * - * @param type to be returned via a read on the associated {@link ItemReader} - * @since 3.0 - */ -public class ItemReadListenerAdapter implements ItemReadListener { - - private jakarta.batch.api.chunk.listener.ItemReadListener delegate; - - public ItemReadListenerAdapter(jakarta.batch.api.chunk.listener.ItemReadListener delegate) { - Assert.notNull(delegate, "An ItemReadListener is required"); - this.delegate = delegate; - } - - @Override - public void beforeRead() { - try { - delegate.beforeRead(); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Override - public void afterRead(T item) { - try { - delegate.afterRead(item); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Override - public void onReadError(Exception ex) { - try { - delegate.onReadError(ex); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemWriteListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemWriteListenerAdapter.java deleted file mode 100644 index 37a6108d7..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/ItemWriteListenerAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.util.List; - -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.ItemWriteListener; -import org.springframework.batch.item.ItemWriter; -import org.springframework.util.Assert; - -/** - * Wrapper class to adapt the {@link jakarta.batch.api.chunk.listener.ItemWriteListener} to - * a {@link ItemWriteListener}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * - * @param type to be written by the associated {@link ItemWriter} - * @since 3.0 - */ -public class ItemWriteListenerAdapter implements ItemWriteListener { - - private jakarta.batch.api.chunk.listener.ItemWriteListener delegate; - - public ItemWriteListenerAdapter(jakarta.batch.api.chunk.listener.ItemWriteListener delegate) { - Assert.notNull(delegate, "An ItemWriteListener is required"); - this.delegate = delegate; - } - - @SuppressWarnings("unchecked") - @Override - public void beforeWrite(List items) { - try { - delegate.beforeWrite((List) items); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @SuppressWarnings("unchecked") - @Override - public void afterWrite(List items) { - try { - delegate.afterWrite((List) items); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @SuppressWarnings("unchecked") - @Override - public void onWriteError(Exception exception, List items) { - try { - delegate.onWriteError((List) items, exception); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JobListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JobListenerAdapter.java deleted file mode 100644 index a276e8613..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JobListenerAdapter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.api.listener.JobListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobExecutionListener; -import org.springframework.util.Assert; - -/** - * Wrapper class to adapt the {@link JobListener} to - * a {@link JobExecutionListener}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JobListenerAdapter implements JobExecutionListener { - - private JobListener delegate; - - /** - * @param delegate to be delegated to - */ - public JobListenerAdapter(JobListener delegate) { - Assert.notNull(delegate, "Delegate is required"); - this.delegate = delegate; - } - - @Override - public void beforeJob(JobExecution jobExecution) { - try { - delegate.beforeJob(); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Override - public void afterJob(JobExecution jobExecution) { - try { - delegate.afterJob(); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobContext.java deleted file mode 100644 index 880e7211f..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobContext.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.util.Properties; -import java.util.concurrent.atomic.AtomicBoolean; - -import jakarta.batch.runtime.BatchStatus; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Wrapper class to provide the {@link jakarta.batch.runtime.context.JobContext} functionality - * as specified in JSR-352. Wrapper delegates to the underlying {@link JobExecution} to - * obtain the related contextual information. - * - * @author Michael Minella - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrJobContext implements jakarta.batch.runtime.context.JobContext { - private Object transientUserData; - private Properties properties; - private JobExecution jobExecution; - private AtomicBoolean exitStatusSet = new AtomicBoolean(); - - public void setJobExecution(JobExecution jobExecution) { - Assert.notNull(jobExecution, "A JobExecution is required"); - this.jobExecution = jobExecution; - } - - public void setProperties(@Nullable Properties properties) { - this.properties = properties != null ? properties : new Properties(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#getJobName() - */ - @Override - public String getJobName() { - return jobExecution.getJobInstance().getJobName(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#getTransientUserData() - */ - @Override - public Object getTransientUserData() { - return transientUserData; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#setTransientUserData(java.lang.Object) - */ - @Override - public void setTransientUserData(Object data) { - transientUserData = data; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#getInstanceId() - */ - @Override - public long getInstanceId() { - return jobExecution.getJobInstance().getId(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#getExecutionId() - */ - @Override - public long getExecutionId() { - return jobExecution.getId(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#getProperties() - */ - @Override - public Properties getProperties() { - return properties; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#getBatchStatus() - */ - @Override - public BatchStatus getBatchStatus() { - return jobExecution.getStatus().getBatchStatus(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#getExitStatus() - */ - @Override - @Nullable - public String getExitStatus() { - return exitStatusSet.get() ? jobExecution.getExitStatus().getExitCode() : null; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.JobContext#setExitStatus(java.lang.String) - */ - @Override - public void setExitStatus(String status) { - jobExecution.setExitStatus(new ExitStatus(status)); - exitStatusSet.set(true); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobContextFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobContextFactoryBean.java deleted file mode 100644 index 75b4c1111..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobContextFactoryBean.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.util.Properties; - -import jakarta.batch.runtime.StepExecution; -import jakarta.batch.runtime.context.JobContext; - -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.FactoryBeanNotInitializedException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.Assert; - -/** - * Provides a single {@link JobContext} for each thread in a running job. - * Subsequent calls to {@link FactoryBean#getObject()} on the same thread will - * return the same instance. The {@link JobContext} wraps a {@link JobExecution} - * which is obtained in one of two ways: - *
    - *
  • The current step scope (getting it from the current {@link StepExecution}
  • - *
  • The provided {@link JobExecution} via the {@link #setJobExecution(JobExecution)} - *
- * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrJobContextFactoryBean implements FactoryBean { - - private JobExecution jobExecution; - @Autowired - private BatchPropertyContext propertyContext; - - private static final ThreadLocal contextHolder = new ThreadLocal<>(); - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObject() - */ - @Override - public JobContext getObject() throws Exception { - return getCurrent(); - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ - @Override - public Class getObjectType() { - return JobContext.class; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#isSingleton() - */ - @Override - public boolean isSingleton() { - return false; - } - - /** - * Used to provide {@link JobContext} instances to batch artifacts that - * are not within the scope of a given step. - * - * @param jobExecution set the current {@link JobExecution} - */ - public void setJobExecution(JobExecution jobExecution) { - Assert.notNull(jobExecution, "A JobExecution is required"); - this.jobExecution = jobExecution; - } - - /** - * @param propertyContext the {@link BatchPropertyContext} to obtain job properties from - */ - public void setBatchPropertyContext(BatchPropertyContext propertyContext) { - this.propertyContext = propertyContext; - } - - /** - * Used to remove the {@link JobContext} for the current thread. Not used via - * normal processing but useful for testing. - */ - public void close() { - if(contextHolder.get() != null) { - contextHolder.remove(); - } - } - - private JobContext getCurrent() { - if(contextHolder.get() == null) { - JobExecution curJobExecution = null; - - if(StepSynchronizationManager.getContext() != null) { - curJobExecution = StepSynchronizationManager.getContext().getStepExecution().getJobExecution(); - } - - if(curJobExecution != null) { - jobExecution = curJobExecution; - } - - if(jobExecution == null) { - throw new FactoryBeanNotInitializedException("A JobExecution is required"); - } - - JsrJobContext jobContext = new JsrJobContext(); - jobContext.setJobExecution(jobExecution); - - if(propertyContext != null) { - jobContext.setProperties(propertyContext.getJobProperties()); - } else { - jobContext.setProperties(new Properties()); - } - - contextHolder.set(jobContext); - } - - return contextHolder.get(); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobExecution.java deleted file mode 100644 index ab199aba7..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobExecution.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.util.Date; -import java.util.Properties; - -import jakarta.batch.runtime.BatchStatus; - -import org.springframework.batch.core.converter.JobParametersConverter; -import org.springframework.util.Assert; - -/** - * Wrapper class to adapt the {@link jakarta.batch.runtime.JobExecution} to - * a {@link org.springframework.batch.core.JobExecution}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrJobExecution implements jakarta.batch.runtime.JobExecution { - - private org.springframework.batch.core.JobExecution execution; - private JobParametersConverter parametersConverter; - - /** - * @param execution for all information to be delegated from. - * @param parametersConverter instance of {@link JobParametersConverter}. - */ - public JsrJobExecution(org.springframework.batch.core.JobExecution execution, JobParametersConverter parametersConverter) { - Assert.notNull(execution, "A JobExecution is required"); - this.execution = execution; - - this.parametersConverter = parametersConverter; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getExecutionId() - */ - @Override - public long getExecutionId() { - return this.execution.getId(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getJobName() - */ - @Override - public String getJobName() { - return this.execution.getJobInstance().getJobName(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getBatchStatus() - */ - @Override - public BatchStatus getBatchStatus() { - return this.execution.getStatus().getBatchStatus(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getStartTime() - */ - @Override - public Date getStartTime() { - return this.execution.getStartTime(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getEndTime() - */ - @Override - public Date getEndTime() { - return this.execution.getEndTime(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getExitStatus() - */ - @Override - public String getExitStatus() { - return this.execution.getExitStatus().getExitCode(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getCreateTime() - */ - @Override - public Date getCreateTime() { - return this.execution.getCreateTime(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getLastUpdatedTime() - */ - @Override - public Date getLastUpdatedTime() { - return this.execution.getLastUpdated(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JobExecution#getJobParameters() - */ - @Override - public Properties getJobParameters() { - Properties properties = parametersConverter.getProperties(this.execution.getJobParameters()); - properties.remove(JsrJobParametersConverter.JOB_RUN_ID); - return properties; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobListenerMetaData.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobListenerMetaData.java deleted file mode 100644 index 5cb9d5d62..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobListenerMetaData.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.Map; - -import jakarta.batch.api.listener.JobListener; - -import org.springframework.batch.core.listener.ListenerMetaData; - -/** - * Enumeration for {@link JobListener} meta data, which ties together the names - * of methods, their interfaces, annotation, and expected arguments. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public enum JsrJobListenerMetaData implements ListenerMetaData { - BEFORE_JOB("beforeJob", "jsr-before-job"), - AFTER_JOB("afterJob", "jsr-after-job"); - - private final String methodName; - private final String propertyName; - private static final Map propertyMap; - - JsrJobListenerMetaData(String methodName, String propertyName) { - this.methodName = methodName; - this.propertyName = propertyName; - } - - static{ - propertyMap = new HashMap<>(); - for(JsrJobListenerMetaData metaData : values()){ - propertyMap.put(metaData.getPropertyName(), metaData); - } - } - - @Override - public String getMethodName() { - return methodName; - } - - @Override - public Class getAnnotation() { - return null; - } - - @Override - public Class getListenerInterface() { - return JobListener.class; - } - - @Override - public String getPropertyName() { - return propertyName; - } - - @Override - public Class[] getParamTypes() { - return new Class[0]; - } - - /** - * Return the relevant meta data for the provided property name. - * - * @param propertyName the name of the property to return. - * @return meta data with supplied property name, null if none exists. - */ - public static JsrJobListenerMetaData fromPropertyName(String propertyName){ - return propertyMap.get(propertyName); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobParametersConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobParametersConverter.java deleted file mode 100644 index 642b42fc4..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrJobParametersConverter.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2013-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.jsr; - -import java.util.Map; -import java.util.Properties; - -import javax.sql.DataSource; - -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.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao; -import org.springframework.batch.item.database.support.DataFieldMaxValueIncrementerFactory; -import org.springframework.batch.item.database.support.DefaultDataFieldMaxValueIncrementerFactory; -import org.springframework.batch.support.DatabaseType; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Provides default conversion methodology for JSR-352's implementation. - * - * Since Spring Batch uses job parameters as a way of identifying a job - * instance, this converter will add an additional identifying parameter if - * it does not exist already in the list. The id for the identifying parameter - * will come from the JOB_SEQ sequence as used to generate the unique ids - * for BATCH_JOB_INSTANCE records. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrJobParametersConverter implements JobParametersConverter, InitializingBean { - - public static final String JOB_RUN_ID = "jsr_batch_run_id"; - public DataFieldMaxValueIncrementer incrementer; - public String tablePrefix = AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX; - public DataSource dataSource; - - /** - * Main constructor. - * - * @param dataSource used to gain access to the database to get unique ids. - */ - public JsrJobParametersConverter(DataSource dataSource) { - Assert.notNull(dataSource, "A DataSource is required"); - this.dataSource = dataSource; - } - - /** - * The table prefix used in the current {@link JobRepository} - * - * @param tablePrefix the table prefix used for the job repository tables - */ - public void setTablePrefix(String tablePrefix) { - this.tablePrefix = tablePrefix; - } - - @Override - public void afterPropertiesSet() throws Exception { - DataFieldMaxValueIncrementerFactory factory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource); - - this.incrementer = factory.getIncrementer(DatabaseType.fromMetaData(dataSource).name(), tablePrefix + "JOB_SEQ"); - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.converter.JobParametersConverter#getJobParameters(java.util.Properties) - */ - @Override - public JobParameters getJobParameters(@Nullable Properties properties) { - JobParametersBuilder builder = new JobParametersBuilder(); - boolean runIdFound = false; - - if(properties != null) { - for (Map.Entry curParameter : properties.entrySet()) { - if(curParameter.getValue() != null) { - if(curParameter.getKey().equals(JOB_RUN_ID)) { - runIdFound = true; - builder.addLong(curParameter.getKey().toString(), Long.valueOf((String) curParameter.getValue()), true); - } else { - builder.addString(curParameter.getKey().toString(), curParameter.getValue().toString(), false); - } - } - } - } - - if(!runIdFound) { - builder.addLong(JOB_RUN_ID, incrementer.nextLongValue()); - } - - return builder.toJobParameters(); - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.converter.JobParametersConverter#getProperties(org.springframework.batch.core.JobParameters) - */ - @Override - public Properties getProperties(@Nullable JobParameters params) { - Properties properties = new Properties(); - boolean runIdFound = false; - - if(params != null) { - for(Map.Entry curParameter: params.getParameters().entrySet()) { - if(curParameter.getKey().equals(JOB_RUN_ID)) { - runIdFound = true; - } - - properties.setProperty(curParameter.getKey(), curParameter.getValue().getValue().toString()); - } - } - - if(!runIdFound) { - properties.setProperty(JOB_RUN_ID, String.valueOf(incrementer.nextLongValue())); - } - - return properties; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepContext.java deleted file mode 100644 index 10aeda150..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepContext.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.io.Serializable; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicBoolean; - -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.Metric; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.item.util.ExecutionContextUserSupport; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Wrapper class to provide the {@link jakarta.batch.runtime.context.StepContext} functionality - * as specified in JSR-352. Wrapper delegates to the underlying {@link StepExecution} to - * obtain the related contextual information. - * - * @author Michael Minella - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrStepContext implements jakarta.batch.runtime.context.StepContext { - private final static String PERSISTENT_USER_DATA_KEY = "batch_jsr_persistentUserData"; - private StepExecution stepExecution; - private Object transientUserData; - private Properties properties = new Properties(); - private AtomicBoolean exitStatusSet = new AtomicBoolean(); - private final ExecutionContextUserSupport executionContextUserSupport = new ExecutionContextUserSupport(ClassUtils.getShortName(JsrStepContext.class)); - - public JsrStepContext(StepExecution stepExecution, Properties properties) { - Assert.notNull(stepExecution, "A StepExecution is required"); - - this.stepExecution = stepExecution; - this.properties = properties; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getStepName() - */ - @Override - public String getStepName() { - return stepExecution.getStepName(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getTransientUserData() - */ - @Override - public Object getTransientUserData() { - return transientUserData; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#setTransientUserData(java.lang.Object) - */ - @Override - public void setTransientUserData(Object data) { - this.transientUserData = data; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getStepExecutionId() - */ - @Override - public long getStepExecutionId() { - return stepExecution.getId(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getProperties() - */ - @Override - public Properties getProperties() { - return properties != null ? properties : new Properties(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getPersistentUserData() - */ - @Override - public Serializable getPersistentUserData() { - return (Serializable) stepExecution.getExecutionContext().get(executionContextUserSupport.getKey(PERSISTENT_USER_DATA_KEY)); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#setPersistentUserData(java.io.Serializable) - */ - @Override - public void setPersistentUserData(Serializable data) { - stepExecution.getExecutionContext().put(executionContextUserSupport.getKey(PERSISTENT_USER_DATA_KEY), data); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getBatchStatus() - */ - @Override - public BatchStatus getBatchStatus() { - return stepExecution.getStatus().getBatchStatus(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getExitStatus() - */ - @Override - public String getExitStatus() { - return exitStatusSet.get() ? stepExecution.getExitStatus().getExitCode() : null; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#setExitStatus(java.lang.String) - */ - @Override - public void setExitStatus(String status) { - stepExecution.setExitStatus(new ExitStatus(status)); - exitStatusSet.set(true); - } - - /** - * To support both JSR-352's requirement to return the most recent exception - * and Spring Batch's support for {@link Throwable}, this implementation will - * return the most recent exception in the underlying {@link StepExecution}'s - * failure exceptions list. If the exception there extends {@link Throwable} - * instead of {@link Exception}, it will be wrapped in an {@link Exception} and - * then returned. - * - * @see jakarta.batch.runtime.context.StepContext#getException() - */ - @Override - public Exception getException() { - List failureExceptions = stepExecution.getFailureExceptions(); - if(failureExceptions == null || failureExceptions.isEmpty()) { - return null; - } else { - Throwable t = failureExceptions.get(failureExceptions.size() - 1); - - if(t instanceof Exception) { - return (Exception) t; - } else { - return new Exception(t); - } - } - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.context.StepContext#getMetrics() - */ - @Override - public Metric[] getMetrics() { - Metric[] metrics = new Metric[8]; - - metrics[0] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.COMMIT_COUNT, stepExecution.getCommitCount()); - metrics[1] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.FILTER_COUNT, stepExecution.getFilterCount()); - metrics[2] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.PROCESS_SKIP_COUNT, stepExecution.getProcessSkipCount()); - metrics[3] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.READ_COUNT, stepExecution.getReadCount()); - metrics[4] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.READ_SKIP_COUNT, stepExecution.getReadSkipCount()); - metrics[5] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.ROLLBACK_COUNT, stepExecution.getRollbackCount()); - metrics[6] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.WRITE_COUNT, stepExecution.getWriteCount()); - metrics[7] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.WRITE_SKIP_COUNT, stepExecution.getWriteSkipCount()); - - return metrics; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepContextFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepContextFactoryBean.java deleted file mode 100644 index 20eac2e83..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepContextFactoryBean.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.util.Properties; - -import jakarta.batch.runtime.context.StepContext; - -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.FactoryBeanNotInitializedException; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.Assert; - -/** - * {@link FactoryBean} implementation used to create {@link jakarta.batch.runtime.context.StepContext} - * instances within the step scope. - * - * @author Michael Minella - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrStepContextFactoryBean implements FactoryBean, InitializingBean { - @Autowired - private BatchPropertyContext batchPropertyContext; - - private static final ThreadLocal contextHolder = new ThreadLocal<>(); - - protected void setBatchPropertyContext(BatchPropertyContext batchPropertyContext) { - this.batchPropertyContext = batchPropertyContext; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObject() - */ - @Override - public StepContext getObject() throws Exception { - return getCurrent(); - } - - private jakarta.batch.runtime.context.StepContext getCurrent() { - org.springframework.batch.core.StepExecution curStepExecution = null; - - if(StepSynchronizationManager.getContext() != null) { - curStepExecution = StepSynchronizationManager.getContext().getStepExecution(); - } - - if(curStepExecution == null) { - throw new FactoryBeanNotInitializedException("A StepExecution is required"); - } - - StepContext context = contextHolder.get(); - - // If the current context applies to the current step, use it - if(context != null && context.getStepExecutionId() == curStepExecution.getId()) { - return context; - } - - Properties stepProperties = batchPropertyContext.getStepProperties(curStepExecution.getStepName()); - - if(stepProperties != null) { - context = new JsrStepContext(curStepExecution, stepProperties); - } else { - context = new JsrStepContext(curStepExecution, new Properties()); - } - - contextHolder.set(context); - - return context; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ - @Override - public Class getObjectType() { - return StepContext.class; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#isSingleton() - */ - @Override - public boolean isSingleton() { - return false; - } - - @Override - public void afterPropertiesSet() throws Exception { - Assert.notNull(batchPropertyContext, "BatchPropertyContext is required"); - } - - public void remove() { - if(contextHolder.get() != null) { - contextHolder.remove(); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepExecution.java deleted file mode 100644 index 2ce6af242..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepExecution.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.io.Serializable; -import java.util.Date; - -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.Metric; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.item.util.ExecutionContextUserSupport; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Implementation of the JsrStepExecution as defined in JSR-352. This implementation - * wraps a {@link org.springframework.batch.core.StepExecution} as it's source of - * data. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrStepExecution implements jakarta.batch.runtime.StepExecution{ - - private final static String PERSISTENT_USER_DATA_KEY = "batch_jsr_persistentUserData"; - private final org.springframework.batch.core.StepExecution stepExecution; - // The API for the persistent user data is handled by the JsrStepContext which is why the name here is based on the JsrStepContext. - private final ExecutionContextUserSupport executionContextUserSupport = new ExecutionContextUserSupport(ClassUtils.getShortName(JsrStepContext.class)); - - /** - * @param stepExecution The {@link org.springframework.batch.core.StepExecution} used - * as the basis for the data. - */ - public JsrStepExecution(org.springframework.batch.core.StepExecution stepExecution) { - Assert.notNull(stepExecution, "A StepExecution is required"); - - this.stepExecution = stepExecution; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getStepExecutionId() - */ - @Override - public long getStepExecutionId() { - return stepExecution.getId(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getStepName() - */ - @Override - public String getStepName() { - return stepExecution.getStepName(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getBatchStatus() - */ - @Override - public BatchStatus getBatchStatus() { - return stepExecution.getStatus().getBatchStatus(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getStartTime() - */ - @Override - public Date getStartTime() { - return stepExecution.getStartTime(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getEndTime() - */ - @Override - public Date getEndTime() { - return stepExecution.getEndTime(); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getExitStatus() - */ - @Override - public String getExitStatus() { - ExitStatus status = stepExecution.getExitStatus(); - - if(status == null) { - return null; - } else { - return status.getExitCode(); - } - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getPersistentUserData() - */ - @Override - public Serializable getPersistentUserData() { - return (Serializable) stepExecution.getExecutionContext().get(executionContextUserSupport.getKey(PERSISTENT_USER_DATA_KEY)); - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.JsrStepExecution#getMetrics() - */ - @Override - public Metric[] getMetrics() { - Metric[] metrics = new Metric[8]; - - metrics[0] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.COMMIT_COUNT, stepExecution.getCommitCount()); - metrics[1] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.FILTER_COUNT, stepExecution.getFilterCount()); - metrics[2] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.PROCESS_SKIP_COUNT, stepExecution.getProcessSkipCount()); - metrics[3] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.READ_COUNT, stepExecution.getReadCount()); - metrics[4] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.READ_SKIP_COUNT, stepExecution.getReadSkipCount()); - metrics[5] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.ROLLBACK_COUNT, stepExecution.getRollbackCount()); - metrics[6] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.WRITE_COUNT, stepExecution.getWriteCount()); - metrics[7] = new SimpleMetric(jakarta.batch.runtime.Metric.MetricType.WRITE_SKIP_COUNT, stepExecution.getWriteSkipCount()); - - return metrics; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepListenerMetaData.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepListenerMetaData.java deleted file mode 100644 index b9578815f..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/JsrStepListenerMetaData.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import jakarta.batch.api.chunk.listener.ChunkListener; -import jakarta.batch.api.chunk.listener.ItemProcessListener; -import jakarta.batch.api.chunk.listener.ItemReadListener; -import jakarta.batch.api.chunk.listener.ItemWriteListener; -import jakarta.batch.api.chunk.listener.RetryProcessListener; -import jakarta.batch.api.chunk.listener.RetryReadListener; -import jakarta.batch.api.chunk.listener.RetryWriteListener; -import jakarta.batch.api.chunk.listener.SkipProcessListener; -import jakarta.batch.api.chunk.listener.SkipReadListener; -import jakarta.batch.api.chunk.listener.SkipWriteListener; -import jakarta.batch.api.listener.StepListener; - -import org.springframework.batch.core.listener.ListenerMetaData; -import org.springframework.batch.core.listener.StepListenerFactoryBean; - -/** - * Enumeration for the JSR specific {@link StepListener} meta data, which - * ties together the names of methods, their interfaces, and expected arguments. - * - * @author Michael Minella - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - * @see StepListenerFactoryBean - */ -public enum JsrStepListenerMetaData implements ListenerMetaData { - BEFORE_STEP("beforeStep", "jsr-before-step", StepListener.class), - AFTER_STEP("afterStep", "jsr-after-step", StepListener.class), - BEFORE_CHUNK("beforeChunk", "jsr-before-chunk", ChunkListener.class), - AFTER_CHUNK("afterChunk", "jsr-after-chunk", ChunkListener.class), - AFTER_CHUNK_ERROR("onError", "jsr-after-chunk-error", ChunkListener.class, Exception.class), - BEFORE_READ("beforeRead", "jsr-before-read", ItemReadListener.class), - AFTER_READ("afterRead", "jsr-after-read", ItemReadListener.class, Object.class), - AFTER_READ_ERROR("onReadError", "jsr-after-read-error", ItemReadListener.class, Exception.class), - BEFORE_PROCESS("beforeProcess", "jsr-before-process", ItemProcessListener.class, Object.class), - AFTER_PROCESS("afterProcess", "jsr-after-process", ItemProcessListener.class, Object.class, Object.class), - AFTER_PROCESS_ERROR("onProcessError", "jsr-after-process-error", ItemProcessListener.class, Object.class, Exception.class), - BEFORE_WRITE("beforeWrite", "jsr-before-write", ItemWriteListener.class, List.class), - AFTER_WRITE("afterWrite", "jsr-after-write", ItemWriteListener.class, List.class), - AFTER_WRITE_ERROR("onWriteError", "jsr-after-write-error", ItemWriteListener.class, List.class, Exception.class), - SKIP_READ("onSkipReadItem", "jsr-skip-read", SkipReadListener.class, Exception.class), - SKIP_PROCESS("onSkipProcessItem", "jsr-skip-process", SkipProcessListener.class, Object.class, Exception.class), - SKIP_WRITE("onSkipWriteItem", "jsr-skip-write", SkipWriteListener.class, List.class, Exception.class), - RETRY_READ("onRetryReadException", "jsr-retry-read", RetryReadListener.class, Exception.class), - RETRY_PROCESS("onRetryProcessException", "jsr-retry-process", RetryProcessListener.class, Object.class, Exception.class), - RETRY_WRITE("onRetryWriteException", "jsr-retry-write", RetryWriteListener.class, List.class, Exception.class); - - private final String methodName; - private final String propertyName; - private final Class listenerInterface; - private static final Map propertyMap; - private final Class[] paramTypes; - - JsrStepListenerMetaData(String methodName, String propertyName, Class listenerInterface, Class... paramTypes) { - this.propertyName = propertyName; - this.methodName = methodName; - this.listenerInterface = listenerInterface; - this.paramTypes = paramTypes; - } - - static{ - propertyMap = new HashMap<>(); - for(JsrStepListenerMetaData metaData : values()){ - propertyMap.put(metaData.getPropertyName(), metaData); - } - } - - @Override - public String getMethodName() { - return methodName; - } - - @Override - public Class getAnnotation() { - return null; - } - - @Override - public Class getListenerInterface() { - return listenerInterface; - } - - @Override - public Class[] getParamTypes() { - return paramTypes; - } - - @Override - public String getPropertyName() { - return propertyName; - } - - /** - * Return the relevant meta data for the provided property name. - * - * @param propertyName the name of the property to return. - * @return meta data with supplied property name, null if none exists. - */ - public static JsrStepListenerMetaData fromPropertyName(String propertyName){ - return propertyMap.get(propertyName); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryListener.java deleted file mode 100644 index 6527cd524..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 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.jsr; - -import org.springframework.batch.core.StepListener; - -/** - *

- * Interface used internally by RetryListener adapters to provide consistent naming. - * Extends {@link StepListener} to allow registration with existing listener methods. - *

- * - * @author Chris Schaefer - * @since 3.0 - */ -public interface RetryListener extends StepListener { -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryProcessListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryProcessListenerAdapter.java deleted file mode 100644 index b41925c00..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryProcessListenerAdapter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.api.chunk.listener.RetryProcessListener; -import jakarta.batch.operations.BatchRuntimeException; - -/** - *

- * Wrapper class to adapt a {@link RetryProcessListener} to a {@link RetryListener}. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class RetryProcessListenerAdapter implements RetryListener, RetryProcessListener { - private RetryProcessListener retryProcessListener; - - public RetryProcessListenerAdapter(RetryProcessListener retryProcessListener) { - this.retryProcessListener = retryProcessListener; - } - - @Override - public void onRetryProcessException(Object item, Exception ex) throws Exception { - try { - retryProcessListener.onRetryProcessException(item, ex); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryReadListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryReadListenerAdapter.java deleted file mode 100644 index 8054855d8..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryReadListenerAdapter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.api.chunk.listener.RetryReadListener; -import jakarta.batch.operations.BatchRuntimeException; - -/** - *

- * Wrapper class to adapt a {@link RetryReadListener} to a {@link RetryListener}. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class RetryReadListenerAdapter implements RetryListener, RetryReadListener { - private RetryReadListener retryReadListener; - - public RetryReadListenerAdapter(RetryReadListener retryReadListener) { - this.retryReadListener = retryReadListener; - } - - @Override - public void onRetryReadException(Exception ex) throws Exception { - try { - retryReadListener.onRetryReadException(ex); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryWriteListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryWriteListenerAdapter.java deleted file mode 100644 index dc434117a..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/RetryWriteListenerAdapter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import java.util.List; -import jakarta.batch.api.chunk.listener.RetryWriteListener; -import jakarta.batch.operations.BatchRuntimeException; - -/** - *

- * Wrapper class to adapt a {@link RetryWriteListener} to a {@link RetryListener}. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class RetryWriteListenerAdapter implements RetryListener, RetryWriteListener { - private RetryWriteListener retryWriteListener; - - public RetryWriteListenerAdapter(RetryWriteListener retryWriteListener) { - this.retryWriteListener = retryWriteListener; - } - - @Override - public void onRetryWriteException(List items, Exception ex) throws Exception { - try { - retryWriteListener.onRetryWriteException(items, ex); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/SimpleMetric.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/SimpleMetric.java deleted file mode 100644 index bbb005e34..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/SimpleMetric.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.runtime.Metric; - -import org.springframework.util.Assert; - -/** - * Simple implementation of the {@link Metric} interface as required by JSR-352. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class SimpleMetric implements Metric { - - private final MetricType type; - private final long value; - - /** - * Basic constructor. The attributes are immutable so this class is - * thread-safe. - * - * @param type as defined by JSR-352 - * @param value the count of the times the related type has occurred. - */ - public SimpleMetric(MetricType type, long value) { - Assert.notNull(type, "A MetricType is required"); - - this.type = type; - this.value = value; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.Metric#getType() - */ - @Override - public MetricType getType() { - return type; - } - - /* (non-Javadoc) - * @see jakarta.batch.runtime.Metric#getValue() - */ - @Override - public long getValue() { - return value; - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/SkipListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/SkipListenerAdapter.java deleted file mode 100644 index c947bd4d4..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/SkipListenerAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.api.chunk.listener.SkipProcessListener; -import jakarta.batch.api.chunk.listener.SkipReadListener; -import jakarta.batch.api.chunk.listener.SkipWriteListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.SkipListener; - -import java.util.List; - -public class SkipListenerAdapter implements SkipListener { - private final SkipReadListener skipReadDelegate; - private final SkipProcessListener skipProcessDelegate; - private final SkipWriteListener skipWriteDelegate; - - public SkipListenerAdapter(SkipReadListener skipReadDelegate, SkipProcessListener skipProcessDelegate, SkipWriteListener skipWriteDelegate) { - this.skipReadDelegate = skipReadDelegate; - this.skipProcessDelegate = skipProcessDelegate; - this.skipWriteDelegate = skipWriteDelegate; - } - - @Override - public void onSkipInRead(Throwable t) { - if(skipReadDelegate != null && t instanceof Exception) { - try { - skipReadDelegate.onSkipReadItem((Exception) t); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - } - - @SuppressWarnings("unchecked") - @Override - public void onSkipInWrite(S item, Throwable t) { - if(skipWriteDelegate != null && t instanceof Exception) { - try { - /* - * assuming this SkipListenerAdapter will only be called from JsrFaultTolerantChunkProcessor, - * which calls onSkipInWrite() with the whole chunk (List) of items instead of single item - */ - skipWriteDelegate.onSkipWriteItem((List) item, (Exception) t); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - } - - @Override - public void onSkipInProcess(T item, Throwable t) { - if(skipProcessDelegate != null && t instanceof Exception) { - try { - skipProcessDelegate.onSkipProcessItem(item, (Exception) t); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/StepListenerAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/StepListenerAdapter.java deleted file mode 100644 index 51131d5a6..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/StepListenerAdapter.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import jakarta.batch.api.listener.StepListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.StepExecutionListener; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Wrapper class to adapt the {@link StepListener} to - * a {@link StepExecutionListener}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class StepListenerAdapter implements StepExecutionListener { - - private final StepListener delegate; - - /** - * @param delegate instance of {@link StepListener}. - */ - public StepListenerAdapter(StepListener delegate) { - Assert.notNull(delegate, "A listener is required"); - this.delegate = delegate; - } - - @Override - public void beforeStep(StepExecution stepExecution) { - try { - delegate.beforeStep(); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Nullable - @Override - public ExitStatus afterStep(StepExecution stepExecution) { - try { - delegate.afterStep(); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - - return stepExecution.getExitStatus(); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BaseContextListFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BaseContextListFactoryBean.java deleted file mode 100644 index 58fd74652..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BaseContextListFactoryBean.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2014 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.jsr.configuration.support; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.FactoryBean; - -/** - * A simple factory bean that consolidates the list of locations to look for the base context for the JSR-352 - * functionality - * - * @author Michael Minella - * @since 3.0.3 - */ -public class BaseContextListFactoryBean implements FactoryBean>{ - - @Override - public List getObject() throws Exception { - String overrideContextLocation = System.getProperty("JSR-352-BASE-CONTEXT"); - - List contextLocations = new ArrayList<>(2); - - contextLocations.add("baseContext.xml"); - - if(overrideContextLocation != null) { - contextLocations.add(overrideContextLocation); - } - - return contextLocations; - } - - @Override - public Class getObjectType() { - return List.class; - } - - @Override - public boolean isSingleton() { - return true; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchArtifactType.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchArtifactType.java deleted file mode 100644 index a60d16481..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchArtifactType.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2014 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.jsr.configuration.support; - -/** - *

- * Enum to identify batch artifact types. - *

- * - * @author Chris Schaefer - * @since 3.0 - */ -public enum BatchArtifactType { - STEP, - STEP_ARTIFACT, - ARTIFACT, - JOB -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContext.java deleted file mode 100644 index e91116ecb..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContext.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.support; - -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import org.springframework.util.Assert; - -/** - *

- * Context object to hold parsed JSR-352 batch properties, mapping properties to beans / - * "batch artifacts". Used internally when parsing property tags from a batch configuration - * file and to obtain corresponding values when injecting into batch artifacts. - *

- * - * @author Chris Schaefer - * @author Michael Minella - * @since 3.0 - */ -public class BatchPropertyContext { - private static final String PARTITION_INDICATOR = ":partition"; - - private Properties jobProperties = new Properties(); - private Map stepProperties = new HashMap<>(); - private Map artifactProperties = new HashMap<>(); - private Map> stepArtifactProperties = new HashMap<>(); - - /** - *

- * Obtains the Job level properties. - *

- * - * @return the Job level properties - */ - public Properties getJobProperties() { - return jobProperties; - } - - /** - *

- * Adds Job level properties to the context. - *

- * - * @param properties the job {@link Properties} to add - */ - public void setJobProperties(Properties properties) { - Assert.notNull(properties, "Job properties cannot be null"); - this.jobProperties.putAll(properties); - } - - /** - *

- * Obtains the Step level properties for the provided Step name. - *

- * - * @param stepName the Step name to obtain properties for - * @return the {@link Properties} for the Step - */ - public Properties getStepProperties(String stepName) { - Assert.hasText(stepName, "Step name must be provided"); - Properties properties = new Properties(); - - if(stepProperties.containsKey(stepName)) { - properties.putAll(stepProperties.get(stepName)); - } - - if(stepName.contains(PARTITION_INDICATOR)) { - String parentStepName = stepName.substring(0, stepName.indexOf(PARTITION_INDICATOR)); - properties.putAll(getStepProperties(parentStepName)); - } - - return properties; - } - - /** - *

- * Adds Step level properties to the context. - *

- * - * @param properties the step {@link Properties} to add - */ - public void setStepProperties(Map properties) { - Assert.notNull(properties, "Step properties cannot be null"); - - for(Map.Entry propertiesEntry : properties.entrySet()) { - String stepName = propertiesEntry.getKey(); - Properties stepProperties = propertiesEntry.getValue(); - - if (!stepProperties.isEmpty()) { - if (this.stepProperties.containsKey(stepName)) { - Properties existingStepProperties = this.stepProperties.get(stepName); - - Enumeration stepPropertyNames = stepProperties.propertyNames(); - - while(stepPropertyNames.hasMoreElements()) { - String propertyEntryName = (String) stepPropertyNames.nextElement(); - existingStepProperties.put(propertyEntryName, stepProperties.getProperty(propertyEntryName)); - } - - this.stepProperties.put(stepName, existingStepProperties); - } else { - this.stepProperties.put(stepName, propertiesEntry.getValue()); - } - } - } - } - - /** - *

- * Convenience method to set step level properties. Simply wraps the provided parameters - * and delegates to {@link #setStepProperties(java.util.Map)}. - *

- * - * @param stepName the step name to set {@link Properties} for - * @param properties the {@link Properties} to set - */ - public void setStepProperties(String stepName, Properties properties) { - Assert.hasText(stepName, "Step name must be provided"); - Assert.notNull(properties, "Step properties must not be null"); - - Map stepProperties = new HashMap<>(); - stepProperties.put(stepName, properties); - - setStepProperties(stepProperties); - } - - /** - *

- * Obtains the batch {@link Properties} for the provided artifact name. - *

- * - * @param artifactName the batch artifact to obtain properties for - * @return the {@link Properties} for the provided batch artifact - */ - public Properties getArtifactProperties(String artifactName) { - Properties properties = new Properties(); - - if (artifactProperties.containsKey(artifactName)) { - properties.putAll(artifactProperties.get(artifactName)); - } - - return properties; - } - - /** - *

- * Adds non-step artifact properties to the context. - *

- * - * @param properties the artifact {@link Properties} to add - */ - public void setArtifactProperties(Map properties) { - Assert.notNull(properties, "Step properties cannot be null"); - - for(Map.Entry propertiesEntry : properties.entrySet()) { - String artifactName = propertiesEntry.getKey(); - Properties artifactProperties = propertiesEntry.getValue(); - - if(!artifactProperties.isEmpty()) { - this.artifactProperties.put(artifactName, artifactProperties); - } - } - } - - /** - *

- * Obtains the batch {@link Properties} for the provided Step and artifact name. - *

- * - * @param stepName the Step name the artifact is associated with - * @param artifactName the artifact name to obtain {@link Properties} for - * @return the {@link Properties} for the provided Step artifact - */ - public Properties getStepArtifactProperties(String stepName, String artifactName) { - Properties properties = new Properties(); - properties.putAll(getStepProperties(stepName)); - - Map artifactProperties = stepArtifactProperties.get(stepName); - - if (artifactProperties != null && artifactProperties.containsKey(artifactName)) { - properties.putAll(artifactProperties.get(artifactName)); - } - - if(stepName.contains(PARTITION_INDICATOR)) { - String parentStepName = stepName.substring(0, stepName.indexOf(PARTITION_INDICATOR)); - properties.putAll(getStepProperties(parentStepName)); - - Map parentArtifactProperties = stepArtifactProperties.get(parentStepName); - - if (parentArtifactProperties != null && parentArtifactProperties.containsKey(artifactName)) { - properties.putAll(parentArtifactProperties.get(artifactName)); - } - } - - return properties; - } - - /** - *

- * Adds Step artifact properties to the context. - *

- * - * @param properties the step artifact {@link Properties} to add - */ - public void setStepArtifactProperties(Map> properties) { - Assert.notNull(properties, "Step artifact properties cannot be null"); - - for(Map.Entry> propertyEntries : properties.entrySet()) { - String stepName = propertyEntries.getKey(); - - for(Map.Entry artifactEntries : propertyEntries.getValue().entrySet()) { - final String artifactName = artifactEntries.getKey(); - final Properties props = artifactEntries.getValue(); - - Map artifactProperties = stepArtifactProperties.get(stepName); - - if (artifactProperties == null) { - artifactProperties = new HashMap<>(); - stepArtifactProperties.put(stepName, artifactProperties); - } - artifactProperties.put(artifactName, props); - } - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/JsrAutowiredAnnotationBeanPostProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/JsrAutowiredAnnotationBeanPostProcessor.java deleted file mode 100644 index ed4c04090..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/JsrAutowiredAnnotationBeanPostProcessor.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.support; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AccessibleObject; - -import jakarta.batch.api.BatchProperty; - -import org.springframework.beans.factory.annotation.InjectionMetadata; - -/** - *

This class overrides methods in the copied {@link SpringAutowiredAnnotationBeanPostProcessor} class - * to check for the {@link BatchProperty} annotation before processing injection annotations. If the annotation - * is found, further injection processing for the field is skipped.

- */ -public class JsrAutowiredAnnotationBeanPostProcessor extends SpringAutowiredAnnotationBeanPostProcessor { - @Override - protected InjectionMetadata findAutowiringMetadata(Class clazz) { - return super.buildAutowiringMetadata(clazz); - } - - @Override - protected Annotation findAutowiredAnnotation(AccessibleObject ao) { - if (ao.getAnnotation(BatchProperty.class) != null) { - return null; - } - - return super.findAutowiredAnnotation(ao); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/JsrExpressionParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/JsrExpressionParser.java deleted file mode 100644 index 2097da005..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/JsrExpressionParser.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 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.jsr.configuration.support; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.springframework.beans.factory.config.BeanExpressionContext; -import org.springframework.beans.factory.config.BeanExpressionResolver; -import org.springframework.util.StringUtils; - -/** - *

- * Support class for parsing JSR-352 expressions. The JSR-352 expression syntax, for - * example conditional/elvis statements need to be transformed a bit to be valid SPeL expressions. - *

- * - * @author Chris Schaefer - * @since 3.0 - */ -public class JsrExpressionParser { - private static final String QUOTE = "'"; - private static final String NULL = "null"; - private static final String ELVIS_RHS = ":"; - private static final String ELVIS_LHS = "\\?"; - private static final String ELVIS_OPERATOR = "?:"; - private static final String EXPRESSION_SUFFIX = "}"; - private static final String EXPRESSION_PREFIX = "#{"; - private static final String DEFAULT_VALUE_SEPARATOR = ";"; - private static final Pattern CONDITIONAL_EXPRESSION = Pattern.compile("(((\\bnull\\b)|(#\\{\\w))[^;]+)"); - - private BeanExpressionContext beanExpressionContext; - private BeanExpressionResolver beanExpressionResolver; - - /** - *

- * Creates a new instance of this expression parser without and expression resolver. Creating - * an instance via this constructor will still parse expressions but no resolution of operators - * will occur as its expected the caller will. - *

- */ - public JsrExpressionParser() { } - - /** - *

- * Creates a new instances of this expression parser with the provided expression resolver and context to evaluate - * against. - *

- * - * @param beanExpressionResolver the expression resolver to use when resolving expressions - * @param beanExpressionContext the expression context to resolve expressions against - */ - public JsrExpressionParser(BeanExpressionResolver beanExpressionResolver, BeanExpressionContext beanExpressionContext) { - this.beanExpressionContext = beanExpressionContext; - this.beanExpressionResolver = beanExpressionResolver; - } - - /** - *

- * Parses the provided expression, applying any transformations needed to evaluate as a SPeL expression. - *

- * - * @param expression the expression to parse and transform - * @return a JSR-352 transformed expression that can be evaluated by a SPeL parser - */ - public String parseExpression(String expression) { - String expressionToParse = expression; - - if (StringUtils.countOccurrencesOf(expressionToParse, ELVIS_OPERATOR) > 0) { - expressionToParse = parseConditionalExpressions(expressionToParse); - } - - return evaluateExpression(expressionToParse); - } - - private String parseConditionalExpressions(String expression) { - String expressionToParse = expression; - - Matcher conditionalExpressionMatcher = CONDITIONAL_EXPRESSION.matcher(expressionToParse); - - while (conditionalExpressionMatcher.find()) { - String conditionalExpression = conditionalExpressionMatcher.group(1); - - String value = conditionalExpression.split(ELVIS_LHS)[0]; - String defaultValue = conditionalExpression.split(ELVIS_RHS)[1]; - - StringBuilder parsedExpression = new StringBuilder(); - - if(beanExpressionResolver != null) { - parsedExpression.append(EXPRESSION_PREFIX) - .append(evaluateExpression(value)) - .append(ELVIS_OPERATOR) - .append(QUOTE) - .append(evaluateExpression(defaultValue)) - .append(QUOTE) - .append(EXPRESSION_SUFFIX); - } else { - if(NULL.equals(value)) { - parsedExpression.append(defaultValue); - } else { - parsedExpression.append(value); - } - } - - expressionToParse = expressionToParse.replace(conditionalExpression, parsedExpression); - } - - return expressionToParse.replace(DEFAULT_VALUE_SEPARATOR, ""); - } - - private String evaluateExpression(String expression) { - if(beanExpressionResolver != null) { - return (String) beanExpressionResolver.evaluate(expression, beanExpressionContext); - } - - return expression; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/SpringAutowiredAnnotationBeanPostProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/SpringAutowiredAnnotationBeanPostProcessor.java deleted file mode 100644 index e3046648a..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/SpringAutowiredAnnotationBeanPostProcessor.java +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.support; - -import java.beans.PropertyDescriptor; -import java.lang.annotation.Annotation; -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.PropertyValues; -import org.springframework.beans.TypeConverter; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.InjectionMetadata; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.DependencyDescriptor; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; -import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.core.BridgeMethodResolver; -import org.springframework.core.MethodParameter; -import org.springframework.core.Ordered; -import org.springframework.core.PriorityOrdered; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -/** - *

This is a copy of AutowiredAnnotationBeanPostProcessor with modifications allow a subclass to - * do additional checks on other field annotations before processing injection annotations.

- * - *

This class is considered a quick work around and needs to be refactored / removed.

- * - *

The in addition to making this class package private, the following methods were modified to be protected:

- *
    - *
  • findAutowiringMetadata(Class<?> clazz)
  • - *
  • buildAutowiringMetadata(Class<?> clazz)
  • - *
  • findAutowiredAnnotation(AccessibleObject ao)
  • - *
- */ -class SpringAutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, - MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { - - protected final Log logger = LogFactory.getLog(getClass()); - - private final Set> autowiredAnnotationTypes = - new LinkedHashSet<>(); - - private String requiredParameterName = "required"; - - private boolean requiredParameterValue = true; - - private int order = Ordered.LOWEST_PRECEDENCE - 2; - - private ConfigurableListableBeanFactory beanFactory; - - private final Map, Constructor[]> candidateConstructorsCache = - new ConcurrentHashMap<>(64); - - private final Map, InjectionMetadata> injectionMetadataCache = - new ConcurrentHashMap<>(64); - - - /** - * Create a new AutowiredAnnotationBeanPostProcessor - * for Spring's standard {@link org.springframework.beans.factory.annotation.Autowired} annotation. - *

Also supports JSR-330's {@link jakarta.inject.Inject} annotation, if available. - */ - @SuppressWarnings("unchecked") - public SpringAutowiredAnnotationBeanPostProcessor() { - this.autowiredAnnotationTypes.add(Autowired.class); - this.autowiredAnnotationTypes.add(Value.class); - ClassLoader cl = SpringAutowiredAnnotationBeanPostProcessor.class.getClassLoader(); - try { - this.autowiredAnnotationTypes.add((Class) cl.loadClass("jakarta.inject.Inject")); - logger.info("JSR-330 'jakarta.inject.Inject' annotation found and supported for autowiring"); - } - catch (ClassNotFoundException ex) { - // JSR-330 API not available - simply skip. - } - } - - - /** - * Set the 'autowired' annotation type, to be used on constructors, fields, - * setter methods and arbitrary config methods. - *

The default autowired annotation type is the Spring-provided - * {@link Autowired} annotation, as well as {@link Value}. - *

This setter property exists so that developers can provide their own - * (non-Spring-specific) annotation type to indicate that a member is - * supposed to be autowired. - * - * @param autowiredAnnotationType type to be used by constructors, fields and methods. - */ - public void setAutowiredAnnotationType(Class autowiredAnnotationType) { - Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null"); - this.autowiredAnnotationTypes.clear(); - this.autowiredAnnotationTypes.add(autowiredAnnotationType); - } - - /** - * Set the 'autowired' annotation types, to be used on constructors, fields, - * setter methods and arbitrary config methods. - *

The default autowired annotation type is the Spring-provided - * {@link Autowired} annotation, as well as {@link Value}. - *

This setter property exists so that developers can provide their own - * (non-Spring-specific) annotation types to indicate that a member is - * supposed to be autowired. - - * @param autowiredAnnotationTypes set of types to be used by constructors, fields and methods. - */ - public void setAutowiredAnnotationTypes(Set> autowiredAnnotationTypes) { - Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty"); - this.autowiredAnnotationTypes.clear(); - this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes); - } - - /** - * Set the name of a parameter of the annotation that specifies - * whether it is required. - * - * @param requiredParameterName the name of the parameter. - * - * @see #setRequiredParameterValue(boolean) - */ - public void setRequiredParameterName(String requiredParameterName) { - this.requiredParameterName = requiredParameterName; - } - - /** - * Set the boolean value that marks a dependency as required - *

For example if using 'required=true' (the default), - * this value should be true; but if using - * 'optional=false', this value should be false. - * - * @param requiredParameterValue true if dependency is required. - * - * @see #setRequiredParameterName(String) - */ - public void setRequiredParameterValue(boolean requiredParameterValue) { - this.requiredParameterValue = requiredParameterValue; - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public int getOrder() { - return this.order; - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { - throw new IllegalArgumentException( - "AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory"); - } - this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; - } - - - @Override - public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { - if (beanType != null) { - InjectionMetadata metadata = findAutowiringMetadata(beanType); - metadata.checkConfigMembers(beanDefinition); - } - } - - @Override - public Constructor[] determineCandidateConstructors(Class beanClass, String beanName) throws BeansException { - // Quick check on the concurrent map first, with minimal locking. - Constructor[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); - if (candidateConstructors == null) { - synchronized (this.candidateConstructorsCache) { - candidateConstructors = this.candidateConstructorsCache.get(beanClass); - if (candidateConstructors == null) { - Constructor[] rawCandidates = beanClass.getDeclaredConstructors(); - List> candidates = new ArrayList<>(rawCandidates.length); - Constructor requiredConstructor = null; - Constructor defaultConstructor = null; - for (Constructor candidate : rawCandidates) { - Annotation annotation = findAutowiredAnnotation(candidate); - if (annotation != null) { - if (requiredConstructor != null) { - throw new BeanCreationException("Invalid autowire-marked constructor: " + candidate + - ". Found another constructor with 'required' Autowired annotation: " + - requiredConstructor); - } - if (candidate.getParameterTypes().length == 0) { - throw new IllegalStateException( - "Autowired annotation requires at least one argument: " + candidate); - } - boolean required = determineRequiredStatus(annotation); - if (required) { - if (!candidates.isEmpty()) { - throw new BeanCreationException( - "Invalid autowire-marked constructors: " + candidates + - ". Found another constructor with 'required' Autowired annotation: " + - requiredConstructor); - } - requiredConstructor = candidate; - } - candidates.add(candidate); - } - else if (candidate.getParameterTypes().length == 0) { - defaultConstructor = candidate; - } - } - if (!candidates.isEmpty()) { - // Add default constructor to list of optional constructors, as fallback. - if (requiredConstructor == null && defaultConstructor != null) { - candidates.add(defaultConstructor); - } - candidateConstructors = candidates.toArray(new Constructor[candidates.size()]); - } - else { - candidateConstructors = new Constructor[0]; - } - this.candidateConstructorsCache.put(beanClass, candidateConstructors); - } - } - } - return (candidateConstructors.length > 0 ? candidateConstructors : null); - } - - @Override - public PropertyValues postProcessProperties( - PropertyValues pvs, Object bean, String beanName) throws BeansException { - - InjectionMetadata metadata = findAutowiringMetadata(bean.getClass()); - try { - metadata.inject(bean, beanName, pvs); - } - catch (Throwable ex) { - throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); - } - return pvs; - } - - /** - * 'Native' processing method for direct calls with an arbitrary target instance, - * resolving all of its fields and methods which are annotated with @Autowired. - * @param bean the target instance to process - * @throws BeansException if autowiring failed - */ - public void processInjection(Object bean) throws BeansException { - Class clazz = bean.getClass(); - InjectionMetadata metadata = findAutowiringMetadata(clazz); - try { - metadata.inject(bean, null, null); - } - catch (Throwable ex) { - throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", ex); - } - } - - - protected InjectionMetadata findAutowiringMetadata(Class clazz) { - // Quick check on the concurrent map first, with minimal locking. - InjectionMetadata metadata = this.injectionMetadataCache.get(clazz); - if (metadata == null) { - synchronized (this.injectionMetadataCache) { - metadata = this.injectionMetadataCache.get(clazz); - if (metadata == null) { - metadata = buildAutowiringMetadata(clazz); - this.injectionMetadataCache.put(clazz, metadata); - } - } - } - return metadata; - } - - protected InjectionMetadata buildAutowiringMetadata(Class clazz) { - LinkedList elements = new LinkedList<>(); - Class targetClass = clazz; - - do { - LinkedList currElements = new LinkedList<>(); - for (Field field : targetClass.getDeclaredFields()) { - Annotation annotation = findAutowiredAnnotation(field); - if (annotation != null) { - if (Modifier.isStatic(field.getModifiers())) { - if (logger.isWarnEnabled()) { - logger.warn("Autowired annotation is not supported on static fields: " + field); - } - continue; - } - boolean required = determineRequiredStatus(annotation); - currElements.add(new AutowiredFieldElement(field, required)); - } - } - for (Method method : targetClass.getDeclaredMethods()) { - Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); - Annotation annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ? - findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method); - if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { - if (Modifier.isStatic(method.getModifiers())) { - if (logger.isWarnEnabled()) { - logger.warn("Autowired annotation is not supported on static methods: " + method); - } - continue; - } - if (method.getParameterTypes().length == 0) { - if (logger.isWarnEnabled()) { - logger.warn("Autowired annotation should be used on methods with actual parameters: " + method); - } - } - boolean required = determineRequiredStatus(annotation); - PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); - currElements.add(new AutowiredMethodElement(method, required, pd)); - } - } - elements.addAll(0, currElements); - targetClass = targetClass.getSuperclass(); - } - while (targetClass != null && targetClass != Object.class); - - return new InjectionMetadata(clazz, elements); - } - - protected Annotation findAutowiredAnnotation(AccessibleObject ao) { - for (Class type : this.autowiredAnnotationTypes) { - Annotation annotation = AnnotationUtils.getAnnotation(ao, type); - if (annotation != null) { - return annotation; - } - } - return null; - } - - /** - * Obtain all beans of the given type as autowire candidates. - * - * @param type the type of the bean. - * @param the type of the bean. - * @return the target beans, or an empty Collection if no bean of this type is found - * - * @throws BeansException if bean retrieval failed - */ - protected Map findAutowireCandidates(Class type) throws BeansException { - if (this.beanFactory == null) { - throw new IllegalStateException("No BeanFactory configured - " + - "override the getBeanOfType method or specify the 'beanFactory' property"); - } - return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type); - } - - /** - * Determine if the annotated field or method requires its dependency. - *

A 'required' dependency means that autowiring should fail when no beans - * are found. Otherwise, the autowiring process will simply bypass the field - * or method when no beans are found. - * @param annotation the Autowired annotation - * @return whether the annotation indicates that a dependency is required - */ - protected boolean determineRequiredStatus(Annotation annotation) { - try { - Method method = ReflectionUtils.findMethod(annotation.annotationType(), this.requiredParameterName); - if (method == null) { - // annotations like @Inject and @Value don't have a method (attribute) named "required" - // -> default to required status - return true; - } - return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, annotation)); - } - catch (Exception ex) { - // an exception was thrown during reflective invocation of the required attribute - // -> default to required status - return true; - } - } - - /** - * Register the specified bean as dependent on the autowired beans. - */ - private void registerDependentBeans(String beanName, Set autowiredBeanNames) { - if (beanName != null) { - for (String autowiredBeanName : autowiredBeanNames) { - if (this.beanFactory.containsBean(autowiredBeanName)) { - this.beanFactory.registerDependentBean(autowiredBeanName, beanName); - } - if (logger.isDebugEnabled()) { - logger.debug("Autowiring by type from bean name '" + beanName + - "' to bean named '" + autowiredBeanName + "'"); - } - } - } - } - - /** - * Resolve the specified cached method argument or field value. - */ - private Object resolvedCachedArgument(String beanName, Object cachedArgument) { - if (cachedArgument instanceof DependencyDescriptor) { - DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument; - TypeConverter typeConverter = this.beanFactory.getTypeConverter(); - return this.beanFactory.resolveDependency(descriptor, beanName, null, typeConverter); - } - else if (cachedArgument instanceof RuntimeBeanReference) { - return this.beanFactory.getBean(((RuntimeBeanReference) cachedArgument).getBeanName()); - } - else { - return cachedArgument; - } - } - - - /** - * Class representing injection information about an annotated field. - */ - private class AutowiredFieldElement extends InjectionMetadata.InjectedElement { - - private final boolean required; - - private volatile boolean cached = false; - - private volatile Object cachedFieldValue; - - public AutowiredFieldElement(Field field, boolean required) { - super(field, null); - this.required = required; - } - - @Override - protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { - Field field = (Field) this.member; - try { - Object value; - if (this.cached) { - value = resolvedCachedArgument(beanName, this.cachedFieldValue); - } - else { - DependencyDescriptor descriptor = new DependencyDescriptor(field, this.required); - Set autowiredBeanNames = new LinkedHashSet<>(1); - TypeConverter typeConverter = beanFactory.getTypeConverter(); - value = beanFactory.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); - synchronized (this) { - if (!this.cached) { - if (value != null || this.required) { - this.cachedFieldValue = descriptor; - registerDependentBeans(beanName, autowiredBeanNames); - if (autowiredBeanNames.size() == 1) { - String autowiredBeanName = autowiredBeanNames.iterator().next(); - if (beanFactory.containsBean(autowiredBeanName)) { - if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { - this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName); - } - } - } - } - else { - this.cachedFieldValue = null; - } - this.cached = true; - } - } - } - if (value != null) { - ReflectionUtils.makeAccessible(field); - field.set(bean, value); - } - } - catch (Throwable ex) { - throw new BeanCreationException("Could not autowire field: " + field, ex); - } - } - } - - - /** - * Class representing injection information about an annotated method. - */ - private class AutowiredMethodElement extends InjectionMetadata.InjectedElement { - - private final boolean required; - - private volatile boolean cached = false; - - private volatile Object[] cachedMethodArguments; - - public AutowiredMethodElement(Method method, boolean required, PropertyDescriptor pd) { - super(method, pd); - this.required = required; - } - - @Override - protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { - if (checkPropertySkipping(pvs)) { - return; - } - Method method = (Method) this.member; - try { - Object[] arguments; - if (this.cached) { - // Shortcut for avoiding synchronization... - arguments = resolveCachedArguments(beanName); - } - else { - Class[] paramTypes = method.getParameterTypes(); - arguments = new Object[paramTypes.length]; - DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length]; - Set autowiredBeanNames = new LinkedHashSet<>(paramTypes.length); - TypeConverter typeConverter = beanFactory.getTypeConverter(); - for (int i = 0; i < arguments.length; i++) { - MethodParameter methodParam = new MethodParameter(method, i).withContainingClass(bean.getClass()); - descriptors[i] = new DependencyDescriptor(methodParam, this.required); - arguments[i] = beanFactory.resolveDependency( - descriptors[i], beanName, autowiredBeanNames, typeConverter); - if (arguments[i] == null && !this.required) { - arguments = null; - break; - } - } - synchronized (this) { - if (!this.cached) { - if (arguments != null) { - this.cachedMethodArguments = new Object[arguments.length]; - for (int i = 0; i < arguments.length; i++) { - this.cachedMethodArguments[i] = descriptors[i]; - } - registerDependentBeans(beanName, autowiredBeanNames); - if (autowiredBeanNames.size() == paramTypes.length) { - Iterator it = autowiredBeanNames.iterator(); - for (int i = 0; i < paramTypes.length; i++) { - String autowiredBeanName = it.next(); - if (beanFactory.containsBean(autowiredBeanName)) { - if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { - this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName); - } - } - } - } - } - else { - this.cachedMethodArguments = null; - } - this.cached = true; - } - } - } - if (arguments != null) { - ReflectionUtils.makeAccessible(method); - method.invoke(bean, arguments); - } - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - catch (Throwable ex) { - throw new BeanCreationException("Could not autowire method: " + method, ex); - } - } - - private Object[] resolveCachedArguments(String beanName) { - if (this.cachedMethodArguments == null) { - return null; - } - Object[] arguments = new Object[this.cachedMethodArguments.length]; - for (int i = 0; i < arguments.length; i++) { - arguments[i] = resolvedCachedArgument(beanName, this.cachedMethodArguments[i]); - } - return arguments; - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/ThreadLocalClassloaderBeanPostProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/ThreadLocalClassloaderBeanPostProcessor.java deleted file mode 100644 index 22464fad6..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/ThreadLocalClassloaderBeanPostProcessor.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 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.jsr.configuration.support; - -import org.springframework.beans.BeansException; -import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.core.PriorityOrdered; - -/** - * After the {@link BeanFactory} is created, this post processor will evaluate to see - * if any of the beans referenced from a job definition (as defined by JSR-352) point - * to class names instead of bean names. If this is the case, a new {@link BeanDefinition} - * is added with the name of the class as the bean name. - * - * @author Michael Minella - * @since 3.0 - */ -public class ThreadLocalClassloaderBeanPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered { - /* (non-Javadoc) - * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory) - */ - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - String[] beanNames = beanFactory.getBeanDefinitionNames(); - - for (String curName : beanNames) { - BeanDefinition beanDefinition = beanFactory.getBeanDefinition(curName); - PropertyValue[] values = beanDefinition.getPropertyValues().getPropertyValues(); - - for (PropertyValue propertyValue : values) { - Object value = propertyValue.getValue(); - - if(value instanceof RuntimeBeanReference) { - RuntimeBeanReference ref = (RuntimeBeanReference) value; - if(!beanFactory.containsBean(ref.getBeanName())) { - AbstractBeanDefinition newBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ref.getBeanName()).getBeanDefinition(); - newBeanDefinition.setScope("step"); - ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(ref.getBeanName(), newBeanDefinition); - } - } - } - } - } - - /** - * Sets this {@link BeanFactoryPostProcessor} to the lowest precedence so that - * it is executed as late as possible in the chain of {@link BeanFactoryPostProcessor}s - */ - @Override - public int getOrder() { - return PriorityOrdered.LOWEST_PRECEDENCE; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/package-info.java deleted file mode 100644 index bd359dd44..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Extensions of Spring components to support JSR-352 functionality. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.configuration.support; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/BatchParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/BatchParser.java deleted file mode 100644 index dce8a0d94..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/BatchParser.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; - -/** - * Parser used to parse the batch.xml file as defined in JSR-352. It is not - * recommended to use the batch.xml approach with Spring to manage bean instantiation. - * It is recommended that standard Spring bean configurations (via XML or Java Config) - * be used. - * - * @author Michael Minella - * @since 3.0 - */ -public class BatchParser extends AbstractBeanDefinitionParser { - - private static final Log logger = LogFactory.getLog(BatchParser.class); - - @Override - protected boolean shouldGenerateIdAsFallback() { - return true; - } - - @Override - protected AbstractBeanDefinition parseInternal(Element element, - ParserContext parserContext) { - BeanDefinitionRegistry registry = parserContext.getRegistry(); - - parseRefElements(element, registry); - - return null; - } - - private void parseRefElements(Element element, - BeanDefinitionRegistry registry) { - List beanElements = DomUtils.getChildElementsByTagName(element, "ref"); - - if(beanElements.size() > 0) { - for (Element curElement : beanElements) { - AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(curElement.getAttribute("class")) - .getBeanDefinition(); - - beanDefinition.setScope("step"); - - String beanName = curElement.getAttribute("id"); - - if(!registry.containsBeanDefinition(beanName)) { - registry.registerBeanDefinition(beanName, beanDefinition); - } else { - if (logger.isInfoEnabled()) { - logger.info("Ignoring batch.xml bean definition for " + beanName + " because another bean of the same name has been registered"); - } - } - } - } - - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/BatchletParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/BatchletParser.java deleted file mode 100644 index 953449ff9..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/BatchletParser.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.batch.core.step.tasklet.Tasklet; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.w3c.dom.Element; - -/** - * Parser for the <batchlet /> tag defined in JSR-352. The current state - * of this parser parses a batchlet element into a {@link Tasklet} (the ref - * attribute is expected to point to an implementation of Tasklet). - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - */ -public class BatchletParser extends AbstractSingleBeanDefinitionParser { - private static final String REF = "ref"; - - public void parseBatchlet(Element batchletElement, AbstractBeanDefinition bd, ParserContext parserContext, String stepName) { - bd.setBeanClass(StepFactoryBean.class); - bd.setAttribute("isNamespaceStep", false); - - String taskletRef = batchletElement.getAttribute(REF); - - if (StringUtils.hasText(taskletRef)) { - bd.getPropertyValues().addPropertyValue("stepTasklet", new RuntimeBeanReference(taskletRef)); - } - - bd.setRole(BeanDefinition.ROLE_SUPPORT); - bd.setSource(parserContext.extractSource(batchletElement)); - - new PropertyParser(taskletRef, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(batchletElement); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/ChunkParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/ChunkParser.java deleted file mode 100644 index 9f12c65d5..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/ChunkParser.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import java.util.List; - -import org.springframework.batch.core.configuration.xml.ExceptionElementParser; -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.batch.core.step.item.ChunkOrientedTasklet; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.config.TypedStringValue; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.beans.factory.support.ManagedMap; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * Parser for the <chunk /> element as specified in JSR-352. The current state - * parses a chunk element into it's related batch artifacts ({@link ChunkOrientedTasklet}, {@link ItemReader}, - * {@link ItemProcessor}, and {@link ItemWriter}). - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - * - */ -public class ChunkParser { - private static final String TIME_LIMIT_ATTRIBUTE = "time-limit"; - private static final String ITEM_COUNT_ATTRIBUTE = "item-count"; - private static final String CHECKPOINT_ALGORITHM_ELEMENT = "checkpoint-algorithm"; - private static final String CLASS_ATTRIBUTE = "class"; - private static final String INCLUDE_ELEMENT = "include"; - private static final String NO_ROLLBACK_EXCEPTION_CLASSES_ELEMENT = "no-rollback-exception-classes"; - private static final String RETRYABLE_EXCEPTION_CLASSES_ELEMENT = "retryable-exception-classes"; - private static final String SKIPPABLE_EXCEPTION_CLASSES_ELEMENT = "skippable-exception-classes"; - private static final String WRITER_ELEMENT = "writer"; - private static final String PROCESSOR_ELEMENT = "processor"; - private static final String READER_ELEMENT = "reader"; - private static final String REF_ATTRIBUTE = "ref"; - private static final String RETRY_LIMIT_ATTRIBUTE = "retry-limit"; - private static final String SKIP_LIMIT_ATTRIBUTE = "skip-limit"; - private static final String CUSTOM_CHECKPOINT_POLICY = "custom"; - private static final String ITEM_CHECKPOINT_POLICY = "item"; - private static final String CHECKPOINT_POLICY_ATTRIBUTE = "checkpoint-policy"; - - public void parse(Element element, AbstractBeanDefinition bd, ParserContext parserContext, String stepName) { - MutablePropertyValues propertyValues = bd.getPropertyValues(); - bd.setBeanClass(StepFactoryBean.class); - bd.setAttribute("isNamespaceStep", false); - - propertyValues.addPropertyValue("hasChunkElement", Boolean.TRUE); - - String checkpointPolicy = element.getAttribute(CHECKPOINT_POLICY_ATTRIBUTE); - if(StringUtils.hasText(checkpointPolicy)) { - if(checkpointPolicy.equals(ITEM_CHECKPOINT_POLICY)) { - String itemCount = element.getAttribute(ITEM_COUNT_ATTRIBUTE); - if (StringUtils.hasText(itemCount)) { - propertyValues.addPropertyValue("commitInterval", itemCount); - } else { - propertyValues.addPropertyValue("commitInterval", "10"); - } - - parseSimpleAttribute(element, propertyValues, TIME_LIMIT_ATTRIBUTE, "timeout"); - } else if(checkpointPolicy.equals(CUSTOM_CHECKPOINT_POLICY)) { - parseCustomCheckpointAlgorithm(element, parserContext, propertyValues, stepName); - } - } else { - String itemCount = element.getAttribute(ITEM_COUNT_ATTRIBUTE); - if (StringUtils.hasText(itemCount)) { - propertyValues.addPropertyValue("commitInterval", itemCount); - } else { - propertyValues.addPropertyValue("commitInterval", "10"); - } - - parseSimpleAttribute(element, propertyValues, TIME_LIMIT_ATTRIBUTE, "timeout"); - } - - parseSimpleAttribute(element, propertyValues, SKIP_LIMIT_ATTRIBUTE, "skipLimit"); - parseSimpleAttribute(element, propertyValues, RETRY_LIMIT_ATTRIBUTE, "retryLimit"); - - NodeList children = element.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node nd = children.item(i); - - parseChildElement(element, parserContext, propertyValues, nd, stepName); - } - } - - private void parseSimpleAttribute(Element element, - MutablePropertyValues propertyValues, String attributeName, String propertyName) { - String propertyValue = element.getAttribute(attributeName); - if (StringUtils.hasText(propertyValue)) { - propertyValues.addPropertyValue(propertyName, propertyValue); - } - } - - private void parseChildElement(Element element, ParserContext parserContext, - MutablePropertyValues propertyValues, Node nd, String stepName) { - if (nd instanceof Element) { - Element nestedElement = (Element) nd; - String name = nestedElement.getLocalName(); - String artifactName = nestedElement.getAttribute(REF_ATTRIBUTE); - - if(name.equals(READER_ELEMENT)) { - if (StringUtils.hasText(artifactName)) { - propertyValues.addPropertyValue("stepItemReader", new RuntimeBeanReference(artifactName)); - } - - new PropertyParser(artifactName, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(nestedElement); - } else if(name.equals(PROCESSOR_ELEMENT)) { - if (StringUtils.hasText(artifactName)) { - propertyValues.addPropertyValue("stepItemProcessor", new RuntimeBeanReference(artifactName)); - } - - new PropertyParser(artifactName, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(nestedElement); - } else if(name.equals(WRITER_ELEMENT)) { - if (StringUtils.hasText(artifactName)) { - propertyValues.addPropertyValue("stepItemWriter", new RuntimeBeanReference(artifactName)); - } - - new PropertyParser(artifactName, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(nestedElement); - } else if(name.equals(SKIPPABLE_EXCEPTION_CLASSES_ELEMENT)) { - ManagedMap exceptionClasses = new ExceptionElementParser().parse(element, parserContext, SKIPPABLE_EXCEPTION_CLASSES_ELEMENT); - if(exceptionClasses != null) { - propertyValues.addPropertyValue("skippableExceptionClasses", exceptionClasses); - } - } else if(name.equals(RETRYABLE_EXCEPTION_CLASSES_ELEMENT)) { - ManagedMap exceptionClasses = new ExceptionElementParser().parse(element, parserContext, RETRYABLE_EXCEPTION_CLASSES_ELEMENT); - if(exceptionClasses != null) { - propertyValues.addPropertyValue("retryableExceptionClasses", exceptionClasses); - } - } else if(name.equals(NO_ROLLBACK_EXCEPTION_CLASSES_ELEMENT)) { - //TODO: Update to support excludes - ManagedList list = new ManagedList<>(); - - for (Element child : DomUtils.getChildElementsByTagName(nestedElement, INCLUDE_ELEMENT)) { - String className = child.getAttribute(CLASS_ATTRIBUTE); - list.add(new TypedStringValue(className, Class.class)); - } - - propertyValues.addPropertyValue("noRollbackExceptionClasses", list); - } - } - } - - private void parseCustomCheckpointAlgorithm(Element element, ParserContext parserContext, MutablePropertyValues propertyValues, String stepName) { - List elements = DomUtils.getChildElementsByTagName(element, CHECKPOINT_ALGORITHM_ELEMENT); - - if(elements.size() == 1) { - Element checkpointAlgorithmElement = elements.get(0); - - String name = checkpointAlgorithmElement.getAttribute(REF_ATTRIBUTE); - if(StringUtils.hasText(name)) { - propertyValues.addPropertyValue("stepChunkCompletionPolicy", new RuntimeBeanReference(name)); - } - - new PropertyParser(name, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(checkpointAlgorithmElement); - } else if(elements.size() > 1){ - parserContext.getReaderContext().error( - "The element may not appear more than once in a single <" - + element.getNodeName() + "/>.", element); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/DecisionStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/DecisionStepFactoryBean.java deleted file mode 100644 index 3d8dad0f3..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/DecisionStepFactoryBean.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import jakarta.batch.api.Decider; - -import org.springframework.batch.core.Step; -import org.springframework.batch.core.jsr.step.DecisionStep; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; - -/** - * {@link FactoryBean} for creating a {@link DecisionStep}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class DecisionStepFactoryBean implements FactoryBean, InitializingBean { - - private Decider jsrDecider; - private String name; - private JobRepository jobRepository; - - /** - * @param jobRepository All steps need to be able to reference a {@link JobRepository} - */ - public void setJobRepository(JobRepository jobRepository) { - this.jobRepository = jobRepository; - } - - /** - * @param decider a {@link Decider} - * @throws IllegalArgumentException if the type passed in is not a valid type - */ - public void setDecider(Decider decider) { - this.jsrDecider = decider; - } - - /** - * The name of the state - * - * @param name the name to be used by the DecisionStep. - */ - public void setName(String name) { - this.name = name; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObject() - */ - @Override - public Step getObject() throws Exception { - - DecisionStep decisionStep = new DecisionStep(jsrDecider); - decisionStep.setName(name); - decisionStep.setJobRepository(jobRepository); - decisionStep.setAllowStartIfComplete(true); - - return decisionStep; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ - @Override - public Class getObjectType() { - return DecisionStep.class; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#isSingleton() - */ - @Override - public boolean isSingleton() { - return true; - } - - @Override - public void afterPropertiesSet() throws Exception { - Assert.isTrue(jsrDecider != null, "A decider implementation is required"); - Assert.notNull(name, "A name is required for a decision state"); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/FlowParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/FlowParser.java deleted file mode 100644 index 1b4fe3341..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/FlowParser.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.springframework.batch.core.configuration.xml.AbstractFlowParser; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.jsr.job.flow.support.JsrFlow; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * Parses flows as defined in JSR-352. The current state parses a flow - * as it is within a regular Spring Batch job/flow. - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - */ -public class FlowParser extends AbstractFlowParser { - private static final String NEXT_ATTRIBUTE = "next"; - private static final String EXIT_STATUS_ATTRIBUTE = "exit-status"; - private static final List TRANSITION_TYPES = new ArrayList<>(); - - static { - TRANSITION_TYPES.add(NEXT_ELE); - TRANSITION_TYPES.add(STOP_ELE); - TRANSITION_TYPES.add(END_ELE); - TRANSITION_TYPES.add(FAIL_ELE); - } - - private String flowName; - private String jobFactoryRef; - private StepParser stepParser = new StepParser(); - - /** - * @param flowName The name of the flow - * @param jobFactoryRef The bean name for the job factory - */ - public FlowParser(String flowName, String jobFactoryRef) { - super.setJobFactoryRef(jobFactoryRef); - this.jobFactoryRef = jobFactoryRef; - this.flowName = flowName; - } - - @Override - protected Class getBeanClass(Element element) { - return JsrFlowFactoryBean.class; - } - - @Override - protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - builder.getRawBeanDefinition().setAttribute("flowName", flowName); - builder.addPropertyValue("name", flowName); - builder.addPropertyValue("flowType", JsrFlow.class); - - List stateTransitions = new ArrayList<>(); - - Map> reachableElementMap = new HashMap<>(); - String startElement = null; - NodeList children = element.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node node = children.item(i); - if (node instanceof Element) { - String nodeName = node.getLocalName(); - Element child = (Element) node; - if (nodeName.equals(STEP_ELE)) { - stateTransitions.addAll(stepParser.parse(child, parserContext, builder)); - } else if(nodeName.equals(SPLIT_ELE)) { - stateTransitions.addAll(new JsrSplitParser(flowName).parse(child, parserContext)); - } else if(nodeName.equals(DECISION_ELE)) { - stateTransitions.addAll(new JsrDecisionParser().parse(child, parserContext, flowName)); - } else if(nodeName.equals(FLOW_ELE)) { - stateTransitions.addAll(parseFlow(child, parserContext, builder)); - } - } - } - - Set allReachableElements = new HashSet<>(); - findAllReachableElements(startElement, reachableElementMap, allReachableElements); - for (String elementId : reachableElementMap.keySet()) { - if (!allReachableElements.contains(elementId)) { - parserContext.getReaderContext().error("The element [" + elementId + "] is unreachable", element); - } - } - - ManagedList managedList = new ManagedList<>(); - managedList.addAll(stateTransitions); - builder.addPropertyValue("stateTransitions", managedList); - } - - private Collection parseFlow(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - String idAttribute = element.getAttribute(ID_ATTRIBUTE); - - BeanDefinitionBuilder stateBuilder = BeanDefinitionBuilder - .genericBeanDefinition("org.springframework.batch.core.job.flow.support.state.FlowState"); - - FlowParser flowParser = new FlowParser(idAttribute, jobFactoryRef); - - stateBuilder.addConstructorArgValue(flowParser.parse(element, parserContext)); - stateBuilder.addConstructorArgValue(idAttribute); - - builder.getRawBeanDefinition().setAttribute("flowName", idAttribute); - builder.addPropertyValue("name", idAttribute); - - doParse(element, parserContext, builder); - builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - - return FlowParser.getNextElements(parserContext, null, stateBuilder.getBeanDefinition(), element); - } - - public static Collection getNextElements(ParserContext parserContext, BeanDefinition stateDef, - Element element) { - return getNextElements(parserContext, null, stateDef, element); - } - - public static Collection getNextElements(ParserContext parserContext, String stepId, - BeanDefinition stateDef, Element element) { - - Collection list = new ArrayList<>(); - - boolean transitionElementExists = false; - boolean failedTransitionElementExists = false; - - List childElements = DomUtils.getChildElements(element); - for(Element childElement : childElements) { - if(isChildElementTransitionElement(childElement)) { - list.addAll(parseTransitionElement(childElement, stepId, stateDef, parserContext)); - failedTransitionElementExists = failedTransitionElementExists || hasFailedTransitionElement(childElement); - transitionElementExists = true; - } - } - - String shortNextAttribute = element.getAttribute(NEXT_ATTRIBUTE); - boolean hasNextAttribute = StringUtils.hasText(shortNextAttribute); - - if (!transitionElementExists) { - list.addAll(createTransition(FlowExecutionStatus.FAILED, FlowExecutionStatus.FAILED.getName(), null, null, - stateDef, parserContext, false)); - list.addAll(createTransition(FlowExecutionStatus.UNKNOWN, FlowExecutionStatus.UNKNOWN.getName(), null, null, - stateDef, parserContext, false)); - } - - if (hasNextAttribute) { - if (transitionElementExists && !failedTransitionElementExists) { - list.addAll(createTransition(FlowExecutionStatus.FAILED, FlowExecutionStatus.FAILED.getName(), null, null, - stateDef, parserContext, false)); - } - - list.add(getStateTransitionReference(parserContext, stateDef, null, shortNextAttribute)); - } else { - list.addAll(createTransition(FlowExecutionStatus.COMPLETED, FlowExecutionStatus.COMPLETED.getName(), null, null, stateDef, parserContext, - false)); - } - - return list; - } - - private static boolean isChildElementTransitionElement(Element childElement) { - return TRANSITION_TYPES.contains(childElement.getLocalName()); - } - - private static boolean hasFailedTransitionElement(Element childName) { - return FAIL_ELE.equals(childName.getLocalName()); - } - - protected static Collection parseTransitionElement(Element transitionElement, String stateId, - BeanDefinition stateDef, ParserContext parserContext) { - FlowExecutionStatus status = getBatchStatusFromEndTransitionName(transitionElement.getNodeName()); - String onAttribute = transitionElement.getAttribute(ON_ATTR); - String restartAttribute = transitionElement.getAttribute(RESTART_ATTR); - String nextAttribute = transitionElement.getAttribute(TO_ATTR); - - if (!StringUtils.hasText(nextAttribute)) { - nextAttribute = restartAttribute; - } - String exitCodeAttribute = transitionElement.getAttribute(EXIT_STATUS_ATTRIBUTE); - - return createTransition(status, onAttribute, nextAttribute, restartAttribute, exitCodeAttribute, stateDef, parserContext, false); - } - - /** - * @param status The batch status that this transition will set. Use - * BatchStatus.UNKNOWN if not applicable. - * @param on The pattern that this transition should match. Use null for - * "no restriction" (same as "*"). - * @param next The state to which this transition should go. Use null if not - * applicable. - * @param restart The restart attribute this transition will set. - * @param exitCode The exit code that this transition will set. Use null to - * default to batchStatus. - * @param stateDef The bean definition for the current state - * @param parserContext the parser context for the bean factory - * @param abandon the abandon state this transition will set. - * @return a collection of - * {@link org.springframework.batch.core.job.flow.support.StateTransition} - * references - */ - protected static Collection createTransition(FlowExecutionStatus status, String on, String next, - String restart, String exitCode, BeanDefinition stateDef, ParserContext parserContext, boolean abandon) { - - BeanDefinition endState = null; - - if (status.isEnd()) { - - BeanDefinitionBuilder endBuilder = BeanDefinitionBuilder - .genericBeanDefinition("org.springframework.batch.core.jsr.job.flow.support.state.JsrEndState"); - - boolean exitCodeExists = StringUtils.hasText(exitCode); - - endBuilder.addConstructorArgValue(status); - - endBuilder.addConstructorArgValue(exitCodeExists ? exitCode : status.getName()); - - String endName = (status == FlowExecutionStatus.STOPPED ? STOP_ELE - : status == FlowExecutionStatus.FAILED ? FAIL_ELE : END_ELE) - + (endCounter++); - endBuilder.addConstructorArgValue(endName); - - endBuilder.addConstructorArgValue(restart); - - endBuilder.addConstructorArgValue(abandon); - - endBuilder.addConstructorArgReference("jobRepository"); - - String nextOnEnd = exitCodeExists ? null : next; - endState = getStateTransitionReference(parserContext, endBuilder.getBeanDefinition(), null, nextOnEnd); - next = endName; - - } - - Collection list = new ArrayList<>(); - list.add(getStateTransitionReference(parserContext, stateDef, on, next)); - - if(StringUtils.hasText(restart)) { - list.add(getStateTransitionReference(parserContext, stateDef, on + ".RESTART", restart)); - } - - if (endState != null) { - // - // Must be added after the state to ensure that the state is the - // first in the list - // - list.add(endState); - } - return list; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JobFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JobFactoryBean.java deleted file mode 100644 index f92ac09e2..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JobFactoryBean.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import jakarta.batch.api.listener.JobListener; - -import org.springframework.batch.core.JobExecutionListener; -import org.springframework.batch.core.JobParametersIncrementer; -import org.springframework.batch.core.JobParametersValidator; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.job.flow.Flow; -import org.springframework.batch.core.job.flow.FlowJob; -import org.springframework.batch.core.jsr.JobListenerAdapter; -import org.springframework.batch.core.jsr.job.flow.JsrFlowJob; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.SmartFactoryBean; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * This {@link FactoryBean} is used by the JSR-352 namespace parser to create - * {@link FlowJob} objects. It stores all of the properties that are - * configurable on the <job/>. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JobFactoryBean implements SmartFactoryBean { - - private String name; - - private Boolean restartable; - - private JobRepository jobRepository; - - private JobParametersValidator jobParametersValidator; - - private JobExecutionListener[] jobExecutionListeners; - - private JobParametersIncrementer jobParametersIncrementer; - - private Flow flow; - - private JobExplorer jobExplorer; - - public JobFactoryBean(String name) { - this.name = name; - } - - @Override - public final FlowJob getObject() throws Exception { - Assert.isTrue(StringUtils.hasText(name), "The job must have an id."); - JsrFlowJob flowJob = new JsrFlowJob(name); - flowJob.setJobExplorer(jobExplorer); - - if (restartable != null) { - flowJob.setRestartable(restartable); - } - - if (jobRepository != null) { - flowJob.setJobRepository(jobRepository); - } - - if (jobParametersValidator != null) { - flowJob.setJobParametersValidator(jobParametersValidator); - } - - if (jobExecutionListeners != null) { - flowJob.setJobExecutionListeners(jobExecutionListeners); - } - - if (jobParametersIncrementer != null) { - flowJob.setJobParametersIncrementer(jobParametersIncrementer); - } - - if (flow != null) { - flowJob.setFlow(flow); - } - - flowJob.afterPropertiesSet(); - return flowJob; - } - - public void setJobExplorer(JobExplorer jobExplorer) { - this.jobExplorer = jobExplorer; - } - - public void setRestartable(Boolean restartable) { - this.restartable = restartable; - } - - public void setJobRepository(JobRepository jobRepository) { - this.jobRepository = jobRepository; - } - - public void setJobParametersValidator(JobParametersValidator jobParametersValidator) { - this.jobParametersValidator = jobParametersValidator; - } - - public JobRepository getJobRepository() { - return this.jobRepository; - } - - public void setJobParametersIncrementer(JobParametersIncrementer jobParametersIncrementer) { - this.jobParametersIncrementer = jobParametersIncrementer; - } - - public void setFlow(Flow flow) { - this.flow = flow; - } - - @Override - public Class getObjectType() { - return FlowJob.class; - } - - @Override - public boolean isSingleton() { - return true; - } - - @Override - public boolean isEagerInit() { - return true; - } - - @Override - public boolean isPrototype() { - return false; - } - - /** - * Addresses wrapping {@link JobListener} as needed to be used with - * the framework. - * - * @param jobListeners a list of all job listeners - */ - public void setJobExecutionListeners(Object[] jobListeners) { - if(jobListeners != null) { - JobExecutionListener[] listeners = new JobExecutionListener[jobListeners.length]; - - for(int i = 0; i < jobListeners.length; i++) { - Object curListener = jobListeners[i]; - if(curListener instanceof JobExecutionListener) { - listeners[i] = (JobExecutionListener) curListener; - } else if(curListener instanceof JobListener){ - listeners[i] = new JobListenerAdapter((JobListener) curListener); - } - } - - this.jobExecutionListeners = listeners; - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReader.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReader.java deleted file mode 100644 index 2e86e4dfc..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReader.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.jsr.configuration.support.JsrExpressionParser; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader; -import org.springframework.util.ClassUtils; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.ls.DOMImplementationLS; -import org.w3c.dom.traversal.DocumentTraversal; -import org.w3c.dom.traversal.NodeFilter; -import org.w3c.dom.traversal.NodeIterator; - -/** - *

- * {@link DefaultBeanDefinitionDocumentReader} extension to hook into the pre processing of the provided - * XML document, ensuring any references to property operators such as jobParameters and jobProperties are - * resolved prior to loading the context. Since we know these initial values upfront, doing this transformation - * allows us to ensure values are retrieved in their resolved form prior to loading the context and property - * operators can be used on any element. This document reader will also look for references to artifacts by - * the same name and create new bean definitions to provide the ability to create new instances. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrBeanDefinitionDocumentReader extends DefaultBeanDefinitionDocumentReader { - private static final String NULL = "null"; - private static final String ROOT_JOB_ELEMENT_NAME = "job"; - private static final String JOB_PROPERTY_ELEMENT_NAME = "property"; - private static final String JOB_PROPERTIES_ELEMENT_NAME = "properties"; - private static final String JOB_PROPERTY_ELEMENT_NAME_ATTRIBUTE = "name"; - private static final String JOB_PROPERTY_ELEMENT_VALUE_ATTRIBUTE = "value"; - private static final String JOB_PROPERTIES_KEY_NAME = "jobProperties"; - private static final String JOB_PARAMETERS_KEY_NAME = "jobParameters"; - private static final String JOB_PARAMETERS_BEAN_DEFINITION_NAME = "jsr_jobParameters"; - private static final Log LOG = LogFactory.getLog(JsrBeanDefinitionDocumentReader.class); - private static final Pattern PROPERTY_KEY_SEPARATOR = Pattern.compile("'([^']*?)'"); - private static final Pattern OPERATOR_PATTERN = Pattern.compile("(#\\{(job(Properties|Parameters))[^}]+\\})"); - - private BeanDefinitionRegistry beanDefinitionRegistry; - private JsrExpressionParser expressionParser = new JsrExpressionParser(); - private Map propertyMap = new HashMap<>(); - - /** - *

- * Creates a new {@link JsrBeanDefinitionDocumentReader} instance. - *

- */ - public JsrBeanDefinitionDocumentReader() { } - - /** - *

- * Create a new {@link JsrBeanDefinitionDocumentReader} instance with the provided - * {@link BeanDefinitionRegistry}. - *

- * - * @param beanDefinitionRegistry the {@link BeanDefinitionRegistry} to use - */ - public JsrBeanDefinitionDocumentReader(BeanDefinitionRegistry beanDefinitionRegistry) { - this.beanDefinitionRegistry = beanDefinitionRegistry; - } - - @Override - protected void preProcessXml(Element root) { - if (ROOT_JOB_ELEMENT_NAME.equals(root.getLocalName())) { - initProperties(root); - transformDocument(root); - - if (LOG.isDebugEnabled()) { - LOG.debug("Transformed XML from preProcessXml: " + elementToString(root)); - } - } - } - - protected void initProperties(Element root) { - propertyMap.put(JOB_PARAMETERS_KEY_NAME, initJobParameters()); - propertyMap.put(JOB_PROPERTIES_KEY_NAME, initJobProperties(root)); - - resolvePropertyValues(propertyMap.get(JOB_PARAMETERS_KEY_NAME)); - resolvePropertyValues(propertyMap.get(JOB_PROPERTIES_KEY_NAME)); - } - - private Properties initJobParameters() { - Properties jobParameters = new Properties(); - - if (getBeanDefinitionRegistry().containsBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME)) { - BeanDefinition beanDefinition = getBeanDefinitionRegistry().getBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME); - - Properties properties = (Properties) beanDefinition.getConstructorArgumentValues() - .getGenericArgumentValue(Properties.class) - .getValue(); - - if (properties == null) { - return new Properties(); - } - - Enumeration propertyNames = properties.propertyNames(); - - while(propertyNames.hasMoreElements()) { - String curName = (String) propertyNames.nextElement(); - jobParameters.put(curName, properties.getProperty(curName)); - } - } - - return jobParameters; - } - - private Properties initJobProperties(Element root) { - Properties properties = new Properties(); - Node propertiesNode = root.getElementsByTagName(JOB_PROPERTIES_ELEMENT_NAME).item(0); - - if(propertiesNode != null) { - NodeList children = propertiesNode.getChildNodes(); - - for(int i=0; i < children.getLength(); i++) { - Node child = children.item(i); - - if(JOB_PROPERTY_ELEMENT_NAME.equals(child.getLocalName())) { - NamedNodeMap attributes = child.getAttributes(); - Node name = attributes.getNamedItem(JOB_PROPERTY_ELEMENT_NAME_ATTRIBUTE); - Node value = attributes.getNamedItem(JOB_PROPERTY_ELEMENT_VALUE_ATTRIBUTE); - - properties.setProperty(name.getNodeValue(), value.getNodeValue()); - } - } - } - - return properties; - } - - private void resolvePropertyValues(Properties properties) { - for (String propertyKey : properties.stringPropertyNames()) { - String resolvedPropertyValue = resolvePropertyValue(properties.getProperty(propertyKey)); - - if(!properties.getProperty(propertyKey).equals(resolvedPropertyValue)) { - properties.setProperty(propertyKey, resolvedPropertyValue); - } - } - } - - private String resolvePropertyValue(String propertyValue) { - String resolvedValue = resolveValue(propertyValue); - - Matcher jobParameterMatcher = OPERATOR_PATTERN.matcher(resolvedValue); - - while (jobParameterMatcher.find()) { - resolvedValue = resolvePropertyValue(resolvedValue); - } - - return resolvedValue; - } - - private String resolveValue(String value) { - StringBuffer valueBuffer = new StringBuffer(); - Matcher jobParameterMatcher = OPERATOR_PATTERN.matcher(value); - - while (jobParameterMatcher.find()) { - Matcher jobParameterKeyMatcher = PROPERTY_KEY_SEPARATOR.matcher(jobParameterMatcher.group(1)); - - if (jobParameterKeyMatcher.find()) { - String propertyType = jobParameterMatcher.group(2); - String extractedProperty = jobParameterKeyMatcher.group(1); - - Properties properties = propertyMap.get(propertyType); - - if(properties == null) { - throw new IllegalArgumentException("Unknown property type: " + propertyType); - } - - String resolvedProperty = properties.getProperty(extractedProperty, NULL); - - if (NULL.equals(resolvedProperty) && LOG.isInfoEnabled()) { - LOG.info(propertyType + " with key of: " + extractedProperty + " could not be resolved. Possible configuration error?"); - } - - jobParameterMatcher.appendReplacement(valueBuffer, resolvedProperty); - } - } - - jobParameterMatcher.appendTail(valueBuffer); - String resolvedValue = valueBuffer.toString(); - - if (NULL.equals(resolvedValue)) { - return ""; - } - - return expressionParser.parseExpression(resolvedValue); - } - - private BeanDefinitionRegistry getBeanDefinitionRegistry() { - return beanDefinitionRegistry != null ? beanDefinitionRegistry : getReaderContext().getRegistry(); - } - - private void transformDocument(Element root) { - DocumentTraversal traversal = (DocumentTraversal) root.getOwnerDocument(); - NodeIterator iterator = traversal.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, null, true); - - BeanDefinitionRegistry registry = getBeanDefinitionRegistry(); - Map referenceCountMap = new HashMap<>(); - - for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) { - NamedNodeMap map = n.getAttributes(); - - if (map.getLength() > 0) { - for (int i = 0; i < map.getLength(); i++) { - Node node = map.item(i); - - String nodeName = node.getNodeName(); - String nodeValue = node.getNodeValue(); - String resolvedValue = resolveValue(nodeValue); - String newNodeValue = resolvedValue; - - if("ref".equals(nodeName)) { - if(!referenceCountMap.containsKey(resolvedValue)) { - referenceCountMap.put(resolvedValue, 0); - } - - boolean isClass = isClass(resolvedValue); - Integer referenceCount = referenceCountMap.get(resolvedValue); - - // possibly fully qualified class name in ref tag in the JSL or pointer to bean/artifact ref. - if(isClass && !registry.containsBeanDefinition(resolvedValue)) { - AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(resolvedValue) - .getBeanDefinition(); - beanDefinition.setScope("step"); - registry.registerBeanDefinition(resolvedValue, beanDefinition); - - newNodeValue = resolvedValue; - } else { - if(registry.containsBeanDefinition(resolvedValue)) { - referenceCount++; - referenceCountMap.put(resolvedValue, referenceCount); - - newNodeValue = resolvedValue + referenceCount; - - BeanDefinition beanDefinition = registry.getBeanDefinition(resolvedValue); - registry.registerBeanDefinition(newNodeValue, beanDefinition); - } - } - } - - if(!nodeValue.equals(newNodeValue)) { - node.setNodeValue(newNodeValue); - } - } - } else { - String nodeValue = n.getTextContent(); - String resolvedValue = resolveValue(nodeValue); - - if(!nodeValue.equals(resolvedValue)) { - n.setTextContent(resolvedValue); - } - } - } - } - - private boolean isClass(String className) { - try { - Class.forName(className, false, ClassUtils.getDefaultClassLoader()); - } catch (ClassNotFoundException e) { - return false; - } - - return true; - } - - protected Properties getJobParameters() { - return propertyMap.get(JOB_PARAMETERS_KEY_NAME); - } - - protected Properties getJobProperties() { - return propertyMap.get(JOB_PROPERTIES_KEY_NAME); - } - - private String elementToString(Element root) { - DOMImplementationLS domImplLS = (DOMImplementationLS) root.getOwnerDocument().getImplementation(); - return domImplLS.createLSSerializer().writeToString(root); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParser.java deleted file mode 100644 index 78ddaaa34..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParser.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import java.util.Collection; - -import org.springframework.batch.core.job.flow.JobExecutionDecider; -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.w3c.dom.Element; - -/** - * Parser for the <decision /> element as specified in JSR-352. The current state - * parses a decision element and assumes that it refers to a {@link JobExecutionDecider} - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - */ -public class JsrDecisionParser { - - private static final String ID_ATTRIBUTE = "id"; - private static final String REF_ATTRIBUTE = "ref"; - - public Collection parse(Element element, ParserContext parserContext, String jobFactoryRef) { - BeanDefinitionBuilder factoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(); - AbstractBeanDefinition factoryDefinition = factoryBuilder.getRawBeanDefinition(); - factoryDefinition.setBeanClass(DecisionStepFactoryBean.class); - - BeanDefinitionBuilder stateBuilder = BeanDefinitionBuilder.genericBeanDefinition(JsrStepState.class); - - String idAttribute = element.getAttribute(ID_ATTRIBUTE); - - parserContext.registerBeanComponent(new BeanComponentDefinition(factoryDefinition, idAttribute)); - stateBuilder.addConstructorArgReference(idAttribute); - - String refAttribute = element.getAttribute(REF_ATTRIBUTE); - factoryDefinition.getPropertyValues().add("decider", new RuntimeBeanReference(refAttribute)); - factoryDefinition.getPropertyValues().add("name", idAttribute); - - if(StringUtils.hasText(jobFactoryRef)) { - factoryDefinition.setAttribute("jobParserJobFactoryBeanRef", jobFactoryRef); - } - - new PropertyParser(refAttribute, parserContext, BatchArtifactType.STEP_ARTIFACT, idAttribute).parseProperties(element); - - return FlowParser.getNextElements(parserContext, stateBuilder.getBeanDefinition(), element); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrFlowFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrFlowFactoryBean.java deleted file mode 100644 index 3238a2b06..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrFlowFactoryBean.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2014 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.jsr.configuration.xml; - -import org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean; -import org.springframework.batch.core.job.flow.State; -import org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState; - -/** - * Extension to the {@link SimpleFlowFactoryBean} that provides {@link org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState} - * implementations for JSR-352 based jobs. - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrFlowFactoryBean extends SimpleFlowFactoryBean { - - /* (non-Javadoc) - * @see org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean#createNewStepState(org.springframework.batch.core.job.flow.State, java.lang.String, java.lang.String) - */ - @Override - protected State createNewStepState(State state, String oldName, - String stateName) { - return new JsrStepState(stateName, ((JsrStepState) state).getStep(oldName)); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrJobListenerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrJobListenerFactoryBean.java deleted file mode 100644 index 2349d759f..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrJobListenerFactoryBean.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import jakarta.batch.api.listener.JobListener; - -import org.springframework.batch.core.JobExecutionListener; -import org.springframework.batch.core.jsr.JsrJobListenerMetaData; -import org.springframework.batch.core.listener.JobListenerMetaData; -import org.springframework.batch.core.listener.ListenerMetaData; -import org.springframework.beans.factory.FactoryBean; - -/** - * This {@link FactoryBean} is used by the JSR-352 namespace parser to create - * {@link JobExecutionListener} objects. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrJobListenerFactoryBean extends org.springframework.batch.core.listener.JobListenerFactoryBean { - - @Override - public Class getObjectType() { - return JobListener.class; - } - - @Override - protected ListenerMetaData[] getMetaDataValues() { - List values = new ArrayList<>(); - Collections.addAll(values, JobListenerMetaData.values()); - Collections.addAll(values, JsrJobListenerMetaData.values()); - - return values.toArray(new ListenerMetaData[0]); - } - - @Override - protected ListenerMetaData getMetaDataFromPropertyName(String propertyName) { - ListenerMetaData result = JobListenerMetaData.fromPropertyName(propertyName); - - if(result == null) { - result = JsrJobListenerMetaData.fromPropertyName(propertyName); - } - - return result; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrJobParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrJobParser.java deleted file mode 100644 index 43334726b..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrJobParser.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import org.springframework.batch.core.configuration.xml.CoreNamespaceUtils; -import org.springframework.batch.core.jsr.JsrStepContextFactoryBean; -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.w3c.dom.Element; - -/** - * Parses a <job /> tag as defined in JSR-352. Current state parses into - * the standard Spring Batch artifacts. - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - */ -public class JsrJobParser extends AbstractSingleBeanDefinitionParser { - private static final String ID_ATTRIBUTE = "id"; - private static final String RESTARTABLE_ATTRIBUTE = "restartable"; - - @Override - protected Class getBeanClass(Element element) { - return JobFactoryBean.class; - } - - @Override - protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - CoreNamespaceUtils.autoregisterBeansForNamespace(parserContext, parserContext.extractSource(element)); - JsrNamespaceUtils.autoregisterJsrBeansForNamespace(parserContext); - - String jobName = element.getAttribute(ID_ATTRIBUTE); - - builder.setLazyInit(true); - - builder.addConstructorArgValue(jobName); - - builder.addPropertyReference("jobExplorer", "jobExplorer"); - - String restartableAttribute = element.getAttribute(RESTARTABLE_ATTRIBUTE); - if (StringUtils.hasText(restartableAttribute)) { - builder.addPropertyValue("restartable", restartableAttribute); - } - - new PropertyParser(jobName, parserContext, BatchArtifactType.JOB).parseProperties(element); - - BeanDefinition flowDef = new FlowParser(jobName, jobName).parse(element, parserContext); - builder.addPropertyValue("flow", flowDef); - - AbstractBeanDefinition stepContextBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(JsrStepContextFactoryBean.class) - .getBeanDefinition(); - - stepContextBeanDefinition.setScope("step"); - - parserContext.getRegistry().registerBeanDefinition("stepContextFactory", stepContextBeanDefinition); - - new ListenerParser(JsrJobListenerFactoryBean.class, "jobExecutionListeners").parseListeners(element, parserContext, builder); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceHandler.java deleted file mode 100644 index 61988a062..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceHandler.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 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.jsr.configuration.xml; - -import org.springframework.beans.factory.xml.NamespaceHandlerSupport; - -/** - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrNamespaceHandler extends NamespaceHandlerSupport { - - @Override - public void init() { - this.registerBeanDefinitionParser("job", new JsrJobParser()); - this.registerBeanDefinitionParser("batch-artifacts", new BatchParser()); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespacePostProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespacePostProcessor.java deleted file mode 100644 index 8a4038895..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespacePostProcessor.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014 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.jsr.configuration.xml; - -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -/** - * @author Michael Minella - */ -public class JsrNamespacePostProcessor implements BeanPostProcessor, ApplicationContextAware { - - private static final String DEFAULT_JOB_REPOSITORY_NAME = "jobRepository"; - - private ApplicationContext applicationContext; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if(bean instanceof JobFactoryBean) { - JobFactoryBean fb = (JobFactoryBean) bean; - JobRepository jobRepository = fb.getJobRepository(); - if (jobRepository == null) { - fb.setJobRepository((JobRepository) applicationContext.getBean(DEFAULT_JOB_REPOSITORY_NAME)); - } - } - - return bean; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } -} - - - diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceUtils.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceUtils.java deleted file mode 100644 index 3e29244ac..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceUtils.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import org.springframework.batch.core.jsr.launch.support.BatchPropertyBeanPostProcessor; -import org.springframework.batch.core.jsr.configuration.support.JsrAutowiredAnnotationBeanPostProcessor; -import org.springframework.batch.core.jsr.partition.support.JsrBeanScopeBeanFactoryPostProcessor; -import org.springframework.batch.core.jsr.configuration.support.ThreadLocalClassloaderBeanPostProcessor; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.context.annotation.AnnotationConfigUtils; - -import java.util.HashMap; - -/** - * Utility methods used in parsing of the JSR-352 batch namespace and related helpers. - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - */ -class JsrNamespaceUtils { - private static final String JOB_PROPERTIES_BEAN_NAME = "jobProperties"; - private static final String BATCH_PROPERTY_POST_PROCESSOR_BEAN_NAME = "batchPropertyPostProcessor"; - private static final String THREAD_LOCAL_CLASS_LOADER_BEAN_POST_PROCESSOR_BEAN_NAME = "threadLocalClassloaderBeanPostProcessor"; - private static final String BEAN_SCOPE_POST_PROCESSOR_BEAN_NAME = "beanScopeBeanPostProcessor"; - private static final String BATCH_PROPERTY_CONTEXT_BEAN_CLASS_NAME = "org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext"; - private static final String BATCH_PROPERTY_CONTEXT_BEAN_NAME = "batchPropertyContext"; - private static final String JSR_NAMESPACE_POST_PROCESSOR = "jsrNamespacePostProcessor"; - - static void autoregisterJsrBeansForNamespace(ParserContext parserContext) { - autoRegisterJobProperties(parserContext); - autoRegisterBatchPostProcessor(parserContext); - autoRegisterJsrAutowiredAnnotationBeanPostProcessor(parserContext); - autoRegisterThreadLocalClassloaderBeanPostProcessor(parserContext); - autoRegisterBeanScopeBeanFactoryPostProcessor(parserContext); - autoRegisterBatchPropertyContext(parserContext); - autoRegisterNamespacePostProcessor(parserContext); - } - - private static void autoRegisterNamespacePostProcessor(ParserContext parserContext) { - registerPostProcessor(parserContext, JsrNamespacePostProcessor.class, BeanDefinition.ROLE_INFRASTRUCTURE, JSR_NAMESPACE_POST_PROCESSOR); - } - - private static void autoRegisterBeanScopeBeanFactoryPostProcessor( - ParserContext parserContext) { - registerPostProcessor(parserContext, JsrBeanScopeBeanFactoryPostProcessor.class, BeanDefinition.ROLE_INFRASTRUCTURE, BEAN_SCOPE_POST_PROCESSOR_BEAN_NAME); - } - - private static void autoRegisterBatchPostProcessor(ParserContext parserContext) { - registerPostProcessor(parserContext, BatchPropertyBeanPostProcessor.class, BeanDefinition.ROLE_INFRASTRUCTURE, BATCH_PROPERTY_POST_PROCESSOR_BEAN_NAME); - } - - private static void autoRegisterJsrAutowiredAnnotationBeanPostProcessor(ParserContext parserContext) { - registerPostProcessor(parserContext, JsrAutowiredAnnotationBeanPostProcessor.class, BeanDefinition.ROLE_INFRASTRUCTURE, AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME); - } - - private static void autoRegisterThreadLocalClassloaderBeanPostProcessor(ParserContext parserContext) { - registerPostProcessor(parserContext, ThreadLocalClassloaderBeanPostProcessor.class, BeanDefinition.ROLE_INFRASTRUCTURE, THREAD_LOCAL_CLASS_LOADER_BEAN_POST_PROCESSOR_BEAN_NAME); - } - - private static void registerPostProcessor(ParserContext parserContext, Class clazz, int role, String beanName) { - BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz); - - AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition(); - beanDefinition.setRole(role); - - parserContext.getRegistry().registerBeanDefinition(beanName, beanDefinition); - } - - // Registers a bean by the name of {@link #JOB_PROPERTIES_BEAN_NAME} so job level properties can be obtained through - // for example a SPeL expression referencing #{jobProperties['key']} similar to systemProperties resolution. - private static void autoRegisterJobProperties(ParserContext parserContext) { - if (!parserContext.getRegistry().containsBeanDefinition(JOB_PROPERTIES_BEAN_NAME)) { - AbstractBeanDefinition jobPropertiesBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(HashMap.class).getBeanDefinition(); - jobPropertiesBeanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - - parserContext.getRegistry().registerBeanDefinition(JOB_PROPERTIES_BEAN_NAME, jobPropertiesBeanDefinition); - } - } - - private static void autoRegisterBatchPropertyContext(ParserContext parserContext) { - if (!parserContext.getRegistry().containsBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME)) { - AbstractBeanDefinition batchPropertyContextBeanDefinition = - BeanDefinitionBuilder.genericBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_CLASS_NAME) - .getBeanDefinition(); - - batchPropertyContextBeanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - - parserContext.getRegistry().registerBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME, batchPropertyContextBeanDefinition); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrSplitParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrSplitParser.java deleted file mode 100644 index 62440141d..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrSplitParser.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 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.jsr.configuration.xml; - -import java.util.Collection; -import java.util.List; - -import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; - -/** - * Parses a <split /> element as defined in JSR-352. - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - */ -public class JsrSplitParser { - private static final String TASK_EXECUTOR_PROPERTY_NAME = "taskExecutor"; - private static final String JSR_352_SPLIT_TASK_EXECUTOR_BEAN_NAME = "jsr352splitTaskExecutor"; - - private String jobFactoryRef; - - public JsrSplitParser(String jobFactoryRef) { - this.jobFactoryRef = jobFactoryRef; - } - - public Collection parse(Element element, ParserContext parserContext) { - - String idAttribute = element.getAttribute("id"); - - BeanDefinitionBuilder stateBuilder = BeanDefinitionBuilder - .genericBeanDefinition("org.springframework.batch.core.jsr.job.flow.support.state.JsrSplitState"); - - List flowElements = DomUtils.getChildElementsByTagName(element, "flow"); - - if (flowElements.size() < 2) { - parserContext.getReaderContext().error("A must contain at least two 'flow' elements.", element); - } - - Collection flows = new ManagedList<>(); - int i = 0; - for (Element nextElement : flowElements) { - FlowParser flowParser = new FlowParser(idAttribute + "." + i, jobFactoryRef); - flows.add(flowParser.parse(nextElement, parserContext)); - i++; - } - - stateBuilder.addConstructorArgValue(flows); - stateBuilder.addConstructorArgValue(idAttribute); - - PropertyValue propertyValue = getSplitTaskExecutorPropertyValue(parserContext.getRegistry()); - stateBuilder.addPropertyValue(propertyValue.getName(), propertyValue.getValue()); - - return FlowParser.getNextElements(parserContext, null, stateBuilder.getBeanDefinition(), element); - } - - protected PropertyValue getSplitTaskExecutorPropertyValue(BeanDefinitionRegistry beanDefinitionRegistry) { - PropertyValue propertyValue; - - if (hasBeanDefinition(beanDefinitionRegistry, JSR_352_SPLIT_TASK_EXECUTOR_BEAN_NAME)) { - propertyValue = new PropertyValue(TASK_EXECUTOR_PROPERTY_NAME, new RuntimeBeanReference(JSR_352_SPLIT_TASK_EXECUTOR_BEAN_NAME)); - } else { - propertyValue = new PropertyValue(TASK_EXECUTOR_PROPERTY_NAME, new SimpleAsyncTaskExecutor()); - } - - return propertyValue; - } - - private boolean hasBeanDefinition(BeanDefinitionRegistry beanDefinitionRegistry, String beanName) { - return beanDefinitionRegistry.containsBeanDefinition(beanName); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrStepListenerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrStepListenerFactoryBean.java deleted file mode 100644 index 70f2c2d7f..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrStepListenerFactoryBean.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2014 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.jsr.configuration.xml; - -import org.springframework.batch.core.jsr.JsrStepListenerMetaData; -import org.springframework.batch.core.listener.ListenerMetaData; -import org.springframework.batch.core.listener.StepListenerFactoryBean; -import org.springframework.batch.core.listener.StepListenerMetaData; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * @author Michael Minella - */ -public class JsrStepListenerFactoryBean extends StepListenerFactoryBean { - - @Override - protected ListenerMetaData getMetaDataFromPropertyName(String propertyName) { - ListenerMetaData metaData = StepListenerMetaData.fromPropertyName(propertyName); - - if(metaData == null) { - metaData = JsrStepListenerMetaData.fromPropertyName(propertyName); - } - - return metaData; - } - - @Override - protected ListenerMetaData[] getMetaDataValues() { - List values = new ArrayList<>(); - Collections.addAll(values, StepListenerMetaData.values()); - Collections.addAll(values, JsrStepListenerMetaData.values()); - - return values.toArray(new ListenerMetaData[values.size()]); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrXmlApplicationContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrXmlApplicationContext.java deleted file mode 100644 index 802d07252..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrXmlApplicationContext.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 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.jsr.configuration.xml; - -import java.util.Properties; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.io.Resource; - -/** - *

- * {@link GenericApplicationContext} implementation providing JSR-352 related context operations. - *

- * - * @author Chris Schaefer - * @since 3.0 - */ -public class JsrXmlApplicationContext extends GenericApplicationContext { - private static final String JOB_PARAMETERS_BEAN_DEFINITION_NAME = "jsr_jobParameters"; - - private XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); - - /** - *

- * Create a new context instance with no job parameters. - *

- */ - public JsrXmlApplicationContext() { - reader.setDocumentReaderClass(JsrBeanDefinitionDocumentReader.class); - reader.setEnvironment(this.getEnvironment()); - } - - /** - *

- * Create a new context instance using the provided {@link Properties} representing job - * parameters when pre-processing the job definition document. - *

- * - * @param jobParameters the {@link Properties} representing job parameters - */ - public JsrXmlApplicationContext(Properties jobParameters) { - reader.setDocumentReaderClass(JsrBeanDefinitionDocumentReader.class); - reader.setEnvironment(this.getEnvironment()); - - storeJobParameters(jobParameters); - } - - private void storeJobParameters(Properties properties) { - BeanDefinition jobParameters = BeanDefinitionBuilder.genericBeanDefinition(Properties.class).getBeanDefinition(); - jobParameters.getConstructorArgumentValues().addGenericArgumentValue(properties != null ? properties : new Properties()); - - reader.getRegistry().registerBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME, jobParameters); - } - - protected XmlBeanDefinitionReader getReader() { - return reader; - } - - /** - * Set whether to use XML validation. Default is true. - * - * @param validating true if XML should be validated. - */ - public void setValidating(boolean validating) { - this.reader.setValidating(validating); - } - - /** - * Load bean definitions from the given XML resources. - * @param resources one or more resources to load from - */ - public void load(Resource... resources) { - this.reader.loadBeanDefinitions(resources); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/ListenerParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/ListenerParser.java deleted file mode 100644 index ae9c0de5b..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/ListenerParser.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import java.util.List; - -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.parsing.CompositeComponentDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; - -/** - * Parses the various listeners defined in JSR-352. Current state assumes - * the ref attributes point to implementations of Spring Batch interfaces - * and not JSR interfaces - * - * @author Michael Minella - * @author Chris Schaefer - * @since 3.0 - */ -public class ListenerParser { - private static final String REF_ATTRIBUTE = "ref"; - private static final String LISTENER_ELEMENT = "listener"; - private static final String LISTENERS_ELEMENT = "listeners"; - private static final String SCOPE_STEP = "step"; - private static final String SCOPE_JOB = "job"; - - private Class listenerType; - private String propertyKey; - - public ListenerParser(Class listenerType, String propertyKey) { - this.propertyKey = propertyKey; - this.listenerType = listenerType; - } - - public void parseListeners(Element element, ParserContext parserContext, AbstractBeanDefinition bd, String stepName) { - ManagedList listeners = parseListeners(element, parserContext, stepName); - - if(listeners.size() > 0) { - bd.getPropertyValues().add(propertyKey, listeners); - } - } - - public void parseListeners(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - ManagedList listeners = parseListeners(element, parserContext, ""); - - if(listeners.size() > 0) { - builder.addPropertyValue(propertyKey, listeners); - } - } - - private ManagedList parseListeners(Element element, ParserContext parserContext, String stepName) { - List listenersElements = DomUtils.getChildElementsByTagName(element, LISTENERS_ELEMENT); - - ManagedList listeners = new ManagedList<>(); - - if (listenersElements.size() == 1) { - Element listenersElement = listenersElements.get(0); - CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(listenersElement.getTagName(), - parserContext.extractSource(element)); - parserContext.pushContainingComponent(compositeDef); - listeners.setMergeEnabled(false); - List listenerElements = DomUtils.getChildElementsByTagName(listenersElement, LISTENER_ELEMENT); - for (Element listenerElement : listenerElements) { - String beanName = listenerElement.getAttribute(REF_ATTRIBUTE); - - BeanDefinitionBuilder bd = BeanDefinitionBuilder.genericBeanDefinition(listenerType); - bd.addPropertyValue("delegate", new RuntimeBeanReference(beanName)); - - applyListenerScope(beanName, parserContext.getRegistry()); - - listeners.add(bd.getBeanDefinition()); - - new PropertyParser(beanName, parserContext, getBatchArtifactType(stepName), stepName).parseProperties(listenerElement); - } - parserContext.popAndRegisterContainingComponent(); - } - else if (listenersElements.size() > 1) { - parserContext.getReaderContext().error( - "The '' element may not appear more than once in a single " + element.getLocalName(), element); - } - - return listeners; - } - - protected void applyListenerScope(String beanName, BeanDefinitionRegistry beanDefinitionRegistry) { - BeanDefinition beanDefinition = getListenerBeanDefinition(beanName, beanDefinitionRegistry); - beanDefinition.setScope(getListenerScope()); - beanDefinition.setLazyInit(isLazyInit()); - - if (!beanDefinitionRegistry.containsBeanDefinition(beanName)) { - beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition); - } - } - - private BeanDefinition getListenerBeanDefinition(String beanName, BeanDefinitionRegistry beanDefinitionRegistry) { - if (beanDefinitionRegistry.containsBeanDefinition(beanName)) { - return beanDefinitionRegistry.getBeanDefinition(beanName); - } - - return BeanDefinitionBuilder.genericBeanDefinition(beanName).getBeanDefinition(); - } - - private boolean isLazyInit() { - return listenerType == JsrJobListenerFactoryBean.class; - } - - private String getListenerScope() { - if (listenerType == JsrJobListenerFactoryBean.class) { - return SCOPE_JOB; - } - - return SCOPE_STEP; - } - - private BatchArtifactType getBatchArtifactType(String stepName) { - return (stepName != null && !"".equals(stepName)) ? BatchArtifactType.STEP_ARTIFACT - : BatchArtifactType.ARTIFACT; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParser.java deleted file mode 100644 index 7c4ccb66b..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParser.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2013-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.jsr.configuration.xml; - -import java.util.List; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.locks.ReentrantLock; - -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.batch.core.jsr.partition.JsrPartitionHandler; -import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; - -/** - * Parser for the <partition> element as defined by JSR-352. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class PartitionParser { - - private static final String REF = "ref"; - private static final String MAPPER_ELEMENT = "mapper"; - private static final String PLAN_ELEMENT = "plan"; - private static final String PARTITIONS_ATTRIBUTE = "partitions"; - private static final String THREADS_ATTRIBUTE = "threads"; - private static final String PROPERTIES_ELEMENT = "properties"; - private static final String ANALYZER_ELEMENT = "analyzer"; - private static final String COLLECTOR_ELEMENT = "collector"; - private static final String REDUCER_ELEMENT = "reducer"; - private static final String PARTITION_CONTEXT_PROPERTY = "propertyContext"; - private static final String PARTITION_MAPPER_PROPERTY = "partitionMapper"; - private static final String PARTITION_ANALYZER_PROPERTY = "partitionAnalyzer"; - private static final String PARTITION_REDUCER_PROPERTY = "partitionReducer"; - private static final String PARTITION_QUEUE_PROPERTY = "partitionDataQueue"; - private static final String LISTENERS_PROPERTY = "listeners"; - private static final String THREADS_PROPERTY = "threads"; - private static final String PARTITIONS_PROPERTY = "partitions"; - private static final String PARTITION_LOCK_PROPERTY = "partitionLock"; - - private final String name; - private boolean allowStartIfComplete = false; - - /** - * @param stepName the name of the step that is being partitioned - * @param allowStartIfComplete boolean to establish the allowStartIfComplete property for partition properties. - */ - public PartitionParser(String stepName, boolean allowStartIfComplete) { - this.name = stepName; - this.allowStartIfComplete = allowStartIfComplete; - } - - public void parse(Element element, AbstractBeanDefinition bd, ParserContext parserContext, String stepName) { - BeanDefinitionRegistry registry = parserContext.getRegistry(); - MutablePropertyValues factoryBeanProperties = bd.getPropertyValues(); - - AbstractBeanDefinition partitionHandlerDefinition = BeanDefinitionBuilder.genericBeanDefinition(JsrPartitionHandler.class) - .getBeanDefinition(); - - MutablePropertyValues properties = partitionHandlerDefinition.getPropertyValues(); - properties.addPropertyValue(PARTITION_CONTEXT_PROPERTY, new RuntimeBeanReference("batchPropertyContext")); - properties.addPropertyValue("jobRepository", new RuntimeBeanReference("jobRepository")); - properties.addPropertyValue("allowStartIfComplete", allowStartIfComplete); - - parseMapperElement(element, parserContext, properties); - parsePartitionPlan(element, parserContext, stepName, properties); - parseAnalyzerElement(element, parserContext, properties); - parseReducerElement(element, parserContext, factoryBeanProperties); - parseCollectorElement(element, parserContext, factoryBeanProperties, - properties); - - String partitionHandlerBeanName = name + ".partitionHandler"; - registry.registerBeanDefinition(partitionHandlerBeanName, partitionHandlerDefinition); - factoryBeanProperties.add("partitionHandler", new RuntimeBeanReference(partitionHandlerBeanName)); - } - - private void parseCollectorElement(Element element, - ParserContext parserContext, - MutablePropertyValues factoryBeanProperties, - MutablePropertyValues properties) { - Element collectorElement = DomUtils.getChildElementByTagName(element, COLLECTOR_ELEMENT); - - if(collectorElement != null) { - // Only needed if a collector is used - registerCollectorAnalyzerQueue(parserContext); - properties.add(PARTITION_QUEUE_PROPERTY, new RuntimeBeanReference(name + "PartitionQueue")); - properties.add(PARTITION_LOCK_PROPERTY, new RuntimeBeanReference(name + "PartitionLock")); - factoryBeanProperties.add("partitionQueue", new RuntimeBeanReference(name + "PartitionQueue")); - factoryBeanProperties.add("partitionLock", new RuntimeBeanReference(name + "PartitionLock")); - String collectorName = collectorElement.getAttribute(REF); - factoryBeanProperties.add(LISTENERS_PROPERTY, new RuntimeBeanReference(collectorName)); - new PropertyParser(collectorName, parserContext, BatchArtifactType.STEP_ARTIFACT, name).parseProperties(collectorElement); - } - } - - private void parseReducerElement(Element element, - ParserContext parserContext, - MutablePropertyValues factoryBeanProperties) { - Element reducerElement = DomUtils.getChildElementByTagName(element, REDUCER_ELEMENT); - - if(reducerElement != null) { - String reducerName = reducerElement.getAttribute(REF); - factoryBeanProperties.add(PARTITION_REDUCER_PROPERTY, new RuntimeBeanReference(reducerName)); - new PropertyParser(reducerName, parserContext, BatchArtifactType.STEP_ARTIFACT, name).parseProperties(reducerElement); - } - } - - private void parseAnalyzerElement(Element element, - ParserContext parserContext, MutablePropertyValues properties) { - Element analyzerElement = DomUtils.getChildElementByTagName(element, ANALYZER_ELEMENT); - - if(analyzerElement != null) { - String analyzerName = analyzerElement.getAttribute(REF); - properties.add(PARTITION_ANALYZER_PROPERTY, new RuntimeBeanReference(analyzerName)); - new PropertyParser(analyzerName, parserContext, BatchArtifactType.STEP_ARTIFACT, name).parseProperties(analyzerElement); - } - } - - private void parseMapperElement(Element element, - ParserContext parserContext, MutablePropertyValues properties) { - Element mapperElement = DomUtils.getChildElementByTagName(element, MAPPER_ELEMENT); - - if(mapperElement != null) { - String mapperName = mapperElement.getAttribute(REF); - properties.add(PARTITION_MAPPER_PROPERTY, new RuntimeBeanReference(mapperName)); - new PropertyParser(mapperName, parserContext, BatchArtifactType.STEP_ARTIFACT, name).parseProperties(mapperElement); - } - } - - private void registerCollectorAnalyzerQueue(ParserContext parserContext) { - AbstractBeanDefinition partitionQueueDefinition = BeanDefinitionBuilder.genericBeanDefinition(ConcurrentLinkedQueue.class) - .getBeanDefinition(); - AbstractBeanDefinition partitionLockDefinition = BeanDefinitionBuilder.genericBeanDefinition(ReentrantLock.class) - .getBeanDefinition(); - - parserContext.getRegistry().registerBeanDefinition(name + "PartitionQueue", partitionQueueDefinition); - parserContext.getRegistry().registerBeanDefinition(name + "PartitionLock", partitionLockDefinition); - } - - protected void parsePartitionPlan(Element element, - ParserContext parserContext, String stepName, - MutablePropertyValues properties) { - Element planElement = DomUtils.getChildElementByTagName(element, PLAN_ELEMENT); - - if(planElement != null) { - String partitions = planElement.getAttribute(PARTITIONS_ATTRIBUTE); - String threads = planElement.getAttribute(THREADS_ATTRIBUTE); - - if(!StringUtils.hasText(threads)) { - threads = partitions; - } - - List partitionProperties = DomUtils.getChildElementsByTagName(planElement, PROPERTIES_ELEMENT); - - if(partitionProperties != null) { - for (Element partition : partitionProperties) { - String partitionStepName = stepName + ":partition" + partition.getAttribute("partition"); - new PropertyParser(partitionStepName, parserContext, BatchArtifactType.STEP, partitionStepName).parseProperty(partition); - } - } - - properties.add(THREADS_PROPERTY, threads); - properties.add(PARTITIONS_PROPERTY, partitions); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PropertyParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PropertyParser.java deleted file mode 100644 index 475ade25d..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PropertyParser.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.ManagedMap; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; - -/** - *

- * Parser for the <properties /> element defined by JSR-352. - *

- * - * @author Chris Schaefer - * @since 3.0 - */ -public class PropertyParser { - private static final String PROPERTY_ELEMENT = "property"; - private static final String PROPERTIES_ELEMENT = "properties"; - private static final String PROPERTY_NAME_ATTRIBUTE = "name"; - private static final String PROPERTY_VALUE_ATTRIBUTE = "value"; - private static final String JOB_PROPERTIES_BEAN_NAME = "jobProperties"; - private static final String BATCH_PROPERTY_CONTEXT_BEAN_NAME = "batchPropertyContext"; - private static final String JOB_PROPERTIES_PROPERTY_NAME = "jobProperties"; - private static final String STEP_PROPERTIES_PROPERTY_NAME = "stepProperties"; - private static final String ARTIFACT_PROPERTIES_PROPERTY_NAME = "artifactProperties"; - private static final String STEP_ARTIFACT_PROPERTIES_PROPERTY_NAME = "stepArtifactProperties"; - - private String beanName; - private String stepName; - private ParserContext parserContext; - private BatchArtifactType batchArtifactType; - - public PropertyParser(String beanName, ParserContext parserContext, BatchArtifactType batchArtifactType) { - this.beanName = beanName; - this.parserContext = parserContext; - this.batchArtifactType = batchArtifactType; - } - - public PropertyParser(String beanName, ParserContext parserContext, BatchArtifactType batchArtifactType, String stepName) { - this(beanName, parserContext, batchArtifactType); - this.stepName = stepName; - } - - /** - *

- * Parses <property> tag values from the provided {@link Element} if it contains a <properties /> element. - * Only one <properties /> element may be present. <property> elements have a name and value attribute - * which represent the property entries key and value. - *

- * - * @param element the element to parse looking for <properties /> - */ - public void parseProperties(Element element) { - List propertiesElements = DomUtils.getChildElementsByTagName(element, PROPERTIES_ELEMENT); - - if (propertiesElements.size() == 1) { - parsePropertyElement(propertiesElements.get(0)); - } else if (propertiesElements.size() > 1) { - parserContext.getReaderContext().error("The element may not appear more than once.", element); - } - } - - /** - *

- * Parses a <property> tag value from the provided {@link Element}. <property> elements have a name and - * value attribute which represent the property entries key and value. - *

- * - * @param element the element to parse looking for <property/> - */ - public void parseProperty(Element element) { - parsePropertyElement(element); - } - - private void parsePropertyElement(Element propertyElement) { - Properties properties = new Properties(); - - for (Element element : DomUtils.getChildElementsByTagName(propertyElement, PROPERTY_ELEMENT)) { - properties.put(element.getAttribute(PROPERTY_NAME_ATTRIBUTE), element.getAttribute(PROPERTY_VALUE_ATTRIBUTE)); - } - - setProperties(properties); - setJobPropertiesBean(properties); - } - - private void setProperties(Properties properties) { - Object propertyValue; - BeanDefinition beanDefinition = parserContext.getRegistry().getBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME); - - if(batchArtifactType.equals(BatchArtifactType.JOB)) { - propertyValue = getJobProperties(properties); - } else if (batchArtifactType.equals(BatchArtifactType.STEP)) { - propertyValue = getProperties(stepName, properties); - } else if (batchArtifactType.equals(BatchArtifactType.ARTIFACT)) { - propertyValue = getProperties(beanName, properties); - } else if (batchArtifactType.equals(BatchArtifactType.STEP_ARTIFACT)) { - propertyValue = getStepArtifactProperties(beanDefinition, properties); - } else { - throw new IllegalStateException("Unhandled BatchArtifactType of: " + batchArtifactType); - } - - beanDefinition.getPropertyValues().addPropertyValue(getPropertyName(batchArtifactType), propertyValue); - } - - private Map getProperties(String keyName, Properties properties) { - ManagedMap stepProperties = new ManagedMap<>(); - stepProperties.setMergeEnabled(true); - stepProperties.put(keyName, properties); - - return stepProperties; - } - - private Properties getJobProperties(Properties properties) { - return properties; - } - - @SuppressWarnings("unchecked") - private Map> getStepArtifactProperties(BeanDefinition beanDefinition, Properties properties) { - ManagedMap> stepArtifacts = new ManagedMap<>(); - stepArtifacts.setMergeEnabled(true); - - Map> existingArtifacts - = (Map>) beanDefinition.getPropertyValues().get(getPropertyName(batchArtifactType)); - - ManagedMap artifactProperties = new ManagedMap<>(); - artifactProperties.setMergeEnabled(true); - - if(existingArtifacts != null && existingArtifacts.containsKey(stepName)) { - Map existingArtifactsMap = existingArtifacts.get(stepName); - - for(Map.Entry existingArtifactEntry : existingArtifactsMap.entrySet()) { - artifactProperties.put(existingArtifactEntry.getKey(), existingArtifactEntry.getValue()); - } - } - - artifactProperties.put(beanName, properties); - stepArtifacts.put(stepName, artifactProperties); - - return stepArtifacts; - } - - private void setJobPropertiesBean(Properties properties) { - if (batchArtifactType.equals(BatchArtifactType.JOB)) { - Map jobProperties = new HashMap<>(); - - if (properties != null && !properties.isEmpty()) { - for (String param : properties.stringPropertyNames()) { - jobProperties.put(param, properties.getProperty(param)); - } - } - - BeanDefinition jobPropertiesBeanDefinition = parserContext.getRegistry().getBeanDefinition(JOB_PROPERTIES_BEAN_NAME); - jobPropertiesBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(jobProperties); - } - } - - private String getPropertyName(BatchArtifactType batchArtifactType) { - if(batchArtifactType.equals(BatchArtifactType.JOB)) { - return JOB_PROPERTIES_PROPERTY_NAME; - } else if (batchArtifactType.equals(BatchArtifactType.STEP)) { - return STEP_PROPERTIES_PROPERTY_NAME; - } else if (batchArtifactType.equals(BatchArtifactType.ARTIFACT)) { - return ARTIFACT_PROPERTIES_PROPERTY_NAME; - } else if (batchArtifactType.equals(BatchArtifactType.STEP_ARTIFACT)) { - return STEP_ARTIFACT_PROPERTIES_PROPERTY_NAME; - } else { - throw new IllegalStateException("Unhandled BatchArtifactType of: " + batchArtifactType); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepFactoryBean.java deleted file mode 100644 index 11106cf6e..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepFactoryBean.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import jakarta.batch.api.Batchlet; -import jakarta.batch.api.chunk.CheckpointAlgorithm; -import jakarta.batch.api.chunk.ItemProcessor; -import jakarta.batch.api.chunk.ItemReader; -import jakarta.batch.api.chunk.ItemWriter; -import jakarta.batch.api.partition.PartitionReducer; - -import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.xml.StepParserStepFactoryBean; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.partition.JsrPartitionHandler; -import org.springframework.batch.core.jsr.step.batchlet.BatchletAdapter; -import org.springframework.batch.core.jsr.step.builder.JsrBatchletStepBuilder; -import org.springframework.batch.core.jsr.step.builder.JsrFaultTolerantStepBuilder; -import org.springframework.batch.core.jsr.step.builder.JsrPartitionStepBuilder; -import org.springframework.batch.core.jsr.step.builder.JsrSimpleStepBuilder; -import org.springframework.batch.core.step.builder.FaultTolerantStepBuilder; -import org.springframework.batch.core.step.builder.SimpleStepBuilder; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.core.step.builder.TaskletStepBuilder; -import org.springframework.batch.core.step.tasklet.Tasklet; -import org.springframework.batch.core.step.tasklet.TaskletStep; -import org.springframework.batch.jsr.item.ItemProcessorAdapter; -import org.springframework.batch.jsr.item.ItemReaderAdapter; -import org.springframework.batch.jsr.item.ItemWriterAdapter; -import org.springframework.batch.jsr.repeat.CheckpointAlgorithmAdapter; -import org.springframework.batch.repeat.CompletionPolicy; -import org.springframework.batch.repeat.policy.CompositeCompletionPolicy; -import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; -import org.springframework.batch.repeat.policy.TimeoutTerminationPolicy; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.util.Assert; - -/** - * This {@link FactoryBean} is used by the JSR-352 namespace parser to create - * {@link Step} objects. It stores all of the properties that are - * configurable on the <step/>. - * - * @author Michael Minella - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class StepFactoryBean extends StepParserStepFactoryBean { - - @SuppressWarnings("unused") - private int partitions; - private BatchPropertyContext batchPropertyContext; - - private PartitionReducer reducer; - - private Integer timeout; - - public void setPartitionReducer(PartitionReducer reducer) { - this.reducer = reducer; - } - - public void setBatchPropertyContext(BatchPropertyContext context) { - this.batchPropertyContext = context; - } - - public void setPartitions(int partitions) { - this.partitions = partitions; - } - - /** - * Create a {@link Step} from the configuration provided. - * - * @see FactoryBean#getObject() - */ - @Override - public Step getObject() throws Exception { - if(hasPartitionElement()) { - return createPartitionStep(); - } - else if (hasChunkElement()) { - Assert.isTrue(!hasTasklet(), "Step [" + getName() - + "] has both a element and a 'ref' attribute referencing a Tasklet."); - - validateFaultTolerantSettings(); - - if (isFaultTolerant()) { - return createFaultTolerantStep(); - } - else { - return createSimpleStep(); - } - } - else if (hasTasklet()) { - return createTaskletStep(); - } - else { - return createFlowStep(); - } - } - - /** - * @return a new {@link TaskletStep} - */ - @Override - protected TaskletStep createTaskletStep() { - JsrBatchletStepBuilder jsrBatchletStepBuilder = new JsrBatchletStepBuilder(new StepBuilder(getName())); - jsrBatchletStepBuilder.setBatchPropertyContext(batchPropertyContext); - TaskletStepBuilder builder = jsrBatchletStepBuilder.tasklet(getTasklet()); - enhanceTaskletStepBuilder(builder); - return builder.build(); - } - - @Override - protected void setChunk(SimpleStepBuilder builder) { - if(timeout != null && getCommitInterval() != null) { - CompositeCompletionPolicy completionPolicy = new CompositeCompletionPolicy(); - CompletionPolicy [] policies = new CompletionPolicy[2]; - policies[0] = new SimpleCompletionPolicy(getCommitInterval()); - policies[1] = new TimeoutTerminationPolicy(timeout * 1000); - completionPolicy.setPolicies(policies); - builder.chunk(completionPolicy); - } else if(timeout != null) { - builder.chunk(new TimeoutTerminationPolicy(timeout * 1000)); - } else if(getCommitInterval() != null) { - builder.chunk(getCommitInterval()); - } - - if(getCompletionPolicy() != null) { - builder.chunk(getCompletionPolicy()); - } - } - - - @Override - protected Step createPartitionStep() { - // Creating a partitioned step for the JSR needs to create two steps...the partitioned step and the step being executed. - Step executedStep = null; - - if (hasChunkElement()) { - Assert.isTrue(!hasTasklet(), "Step [" + getName() - + "] has both a element and a 'ref' attribute referencing a Tasklet."); - - validateFaultTolerantSettings(); - - if (isFaultTolerant()) { - executedStep = createFaultTolerantStep(); - } - else { - executedStep = createSimpleStep(); - } - } - else if (hasTasklet()) { - executedStep = createTaskletStep(); - } - - ((JsrPartitionHandler) super.getPartitionHandler()).setStep(executedStep); - - JsrPartitionStepBuilder builder = new JsrSimpleStepBuilder(new StepBuilder(executedStep.getName())).partitioner(executedStep); - - enhanceCommonStep(builder); - - if (getPartitionHandler() != null) { - builder.partitionHandler(getPartitionHandler()); - } - - if(reducer != null) { - builder.reducer(reducer); - } - - builder.aggregator(getStepExecutionAggergator()); - - return builder.build(); - } - - /** - * Wraps a {@link Batchlet} in a {@link BatchletAdapter} if required for consumption - * by the rest of the framework. - * - * @param tasklet {@link Tasklet} or {@link Batchlet} implementation - * @throws IllegalArgumentException if tasklet does not implement either Tasklet or Batchlet - */ - public void setStepTasklet(Object tasklet) { - if(tasklet instanceof Tasklet) { - super.setTasklet((Tasklet) tasklet); - } else if(tasklet instanceof Batchlet){ - super.setTasklet(new BatchletAdapter((Batchlet) tasklet)); - } else { - throw new IllegalArgumentException("The field tasklet must reference an implementation of " + - "either org.springframework.batch.core.step.tasklet.Tasklet or jakarta.batch.api.Batchlet"); - } - } - - /** - * Wraps a {@link ItemReader} in a {@link ItemReaderAdapter} if required for consumption - * by the rest of the framework. - * - * @param itemReader {@link ItemReader} or {@link org.springframework.batch.item.ItemReader} implementation - * @throws IllegalArgumentException if itemReader does not implement either version of ItemReader - */ - @SuppressWarnings("unchecked") - public void setStepItemReader(Object itemReader) { - if(itemReader instanceof org.springframework.batch.item.ItemReader) { - super.setItemReader((org.springframework.batch.item.ItemReader) itemReader); - } else if(itemReader instanceof ItemReader){ - super.setItemReader(new ItemReaderAdapter<>((ItemReader) itemReader)); - } else { - throw new IllegalArgumentException("The definition of an item reader must implement either " + - "org.springframework.batch.item.ItemReader or jakarta.batch.api.chunk.ItemReader"); - } - } - - /** - * Wraps a {@link ItemProcessor} in a {@link ItemProcessorAdapter} if required for consumption - * by the rest of the framework. - * - * @param itemProcessor {@link ItemProcessor} or {@link org.springframework.batch.item.ItemProcessor} implementation - * @throws IllegalArgumentException if itemProcessor does not implement either version of ItemProcessor - */ - @SuppressWarnings("unchecked") - public void setStepItemProcessor(Object itemProcessor) { - if(itemProcessor instanceof org.springframework.batch.item.ItemProcessor) { - super.setItemProcessor((org.springframework.batch.item.ItemProcessor) itemProcessor); - } else if(itemProcessor instanceof ItemProcessor){ - super.setItemProcessor(new ItemProcessorAdapter<>((ItemProcessor) itemProcessor)); - } else { - throw new IllegalArgumentException("The definition of an item processor must implement either " + - "org.springframework.batch.item.ItemProcessor or jakarta.batch.api.chunk.ItemProcessor"); - } - } - - /** - * Wraps a {@link ItemWriter} in a {@link ItemWriterAdapter} if required for consumption - * by the rest of the framework. - * - * @param itemWriter {@link ItemWriter} or {@link org.springframework.batch.item.ItemWriter} implementation - * @throws IllegalArgumentException if itemWriter does not implement either version of ItemWriter - */ - @SuppressWarnings("unchecked") - public void setStepItemWriter(Object itemWriter) { - if(itemWriter instanceof org.springframework.batch.item.ItemWriter) { - super.setItemWriter((org.springframework.batch.item.ItemWriter) itemWriter); - } else if(itemWriter instanceof ItemWriter){ - super.setItemWriter(new ItemWriterAdapter<>((ItemWriter) itemWriter)); - } else { - throw new IllegalArgumentException("The definition of an item writer must implement either " + - "org.springframework.batch.item.ItemWriter or jakarta.batch.api.chunk.ItemWriter"); - } - } - - /** - * Wraps a {@link CheckpointAlgorithm} in a {@link CheckpointAlgorithmAdapter} if required for consumption - * by the rest of the framework. - * - * @param chunkCompletionPolicy {@link CompletionPolicy} or {@link CheckpointAlgorithm} implementation - * @throws IllegalArgumentException if chunkCompletionPolicy does not implement either CompletionPolicy or CheckpointAlgorithm - */ - public void setStepChunkCompletionPolicy(Object chunkCompletionPolicy) { - if(chunkCompletionPolicy instanceof CompletionPolicy) { - super.setChunkCompletionPolicy((CompletionPolicy) chunkCompletionPolicy); - } else if(chunkCompletionPolicy instanceof CheckpointAlgorithm) { - super.setChunkCompletionPolicy(new CheckpointAlgorithmAdapter((CheckpointAlgorithm) chunkCompletionPolicy)); - } else { - throw new IllegalArgumentException("The definition of a chunk completion policy must implement either " + - "org.springframework.batch.repeat.CompletionPolicy or jakarta.batch.api.chunk.CheckpointAlgorithm"); - } - } - - @Override - protected FaultTolerantStepBuilder getFaultTolerantStepBuilder(String stepName) { - JsrFaultTolerantStepBuilder jsrFaultTolerantStepBuilder = new JsrFaultTolerantStepBuilder<>( - new StepBuilder(stepName)); - jsrFaultTolerantStepBuilder.setBatchPropertyContext(batchPropertyContext); - return jsrFaultTolerantStepBuilder; - } - - @Override - protected SimpleStepBuilder getSimpleStepBuilder(String stepName) { - JsrSimpleStepBuilder jsrSimpleStepBuilder = new JsrSimpleStepBuilder<>(new StepBuilder(stepName)); - jsrSimpleStepBuilder.setBatchPropertyContext(batchPropertyContext); - return jsrSimpleStepBuilder; - } - - public void setTimeout(Integer timeout) { - this.timeout = timeout; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepParser.java deleted file mode 100644 index a66d57c48..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepParser.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2013-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.jsr.configuration.xml; - -import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType; -import org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.Collection; - -/** - * Parser for the <step /> element defined by JSR-352. - * - * @author Michael Minella - * @author Glenn Renfro - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class StepParser extends AbstractSingleBeanDefinitionParser { - private static final String CHUNK_ELEMENT = "chunk"; - private static final String BATCHLET_ELEMENT = "batchlet"; - private static final String ALLOW_START_IF_COMPLETE_ATTRIBUTE = "allow-start-if-complete"; - private static final String START_LIMIT_ATTRIBUTE = "start-limit"; - private static final String SPLIT_ID_ATTRIBUTE = "id"; - private static final String PARTITION_ELEMENT = "partition"; - - protected Collection parse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(); - AbstractBeanDefinition bd = defBuilder.getRawBeanDefinition(); - bd.setBeanClass(StepFactoryBean.class); - bd.getPropertyValues().addPropertyValue("batchPropertyContext", new RuntimeBeanReference("batchPropertyContext")); - - BeanDefinitionBuilder stateBuilder = BeanDefinitionBuilder.genericBeanDefinition(JsrStepState.class); - - String stepName = element.getAttribute(SPLIT_ID_ATTRIBUTE); - builder.addPropertyValue("name", stepName); - - parserContext.registerBeanComponent(new BeanComponentDefinition(bd, stepName)); - stateBuilder.addConstructorArgReference(stepName); - - String startLimit = element.getAttribute(START_LIMIT_ATTRIBUTE); - if(StringUtils.hasText(startLimit)) { - bd.getPropertyValues().addPropertyValue("startLimit", startLimit); - } - - String allowStartIfComplete = element.getAttribute(ALLOW_START_IF_COMPLETE_ATTRIBUTE); - boolean allowStartIfCompleteValue = false; - if(StringUtils.hasText(allowStartIfComplete)) { - bd.getPropertyValues().addPropertyValue("allowStartIfComplete", - allowStartIfComplete); - allowStartIfCompleteValue = Boolean.valueOf(allowStartIfComplete); - } - - new ListenerParser(JsrStepListenerFactoryBean.class, "listeners").parseListeners(element, parserContext, bd, stepName); - new PropertyParser(stepName, parserContext, BatchArtifactType.STEP, stepName).parseProperties(element); - - // look at all nested elements - NodeList children = element.getChildNodes(); - - for (int i = 0; i < children.getLength(); i++) { - Node nd = children.item(i); - - if (nd instanceof Element) { - Element nestedElement = (Element) nd; - String name = nestedElement.getLocalName(); - - if(name.equalsIgnoreCase(BATCHLET_ELEMENT)) { - new BatchletParser().parseBatchlet(nestedElement, bd, parserContext, stepName); - } else if(name.equals(CHUNK_ELEMENT)) { - new ChunkParser().parse(nestedElement, bd, parserContext, stepName); - } else if(name.equals(PARTITION_ELEMENT)) { - new PartitionParser(stepName, allowStartIfCompleteValue).parse(nestedElement, bd, parserContext, stepName); - } - } - } - - return FlowParser.getNextElements(parserContext, stepName, stateBuilder.getBeanDefinition(), element); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/package-info.java deleted file mode 100644 index 582712ada..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * XML parsers for JSR-352 based Job Specification Language (JSL). - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.configuration.xml; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/JsrStepHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/JsrStepHandler.java deleted file mode 100644 index 36092e81e..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/JsrStepHandler.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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. - * 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.jsr.job; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StartLimitExceededException; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.job.SimpleStepHandler; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.JobRestartException; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -/** - * Extends {@link SimpleStepHandler} to apply JSR-352 specific logic for whether to - * start a step. - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrStepHandler extends SimpleStepHandler { - - private static final Log logger = LogFactory.getLog(JsrStepHandler.class); - - private JobExplorer jobExplorer; - - /** - * @param jobRepository instance of {@link JobRepository}. - * @param jobExplorer instance of {@link JobExplorer}. - */ - public JsrStepHandler(JobRepository jobRepository, JobExplorer jobExplorer) { - super(jobRepository, new ExecutionContext()); - this.jobExplorer = jobExplorer; - } - - @Override - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - Assert.state(jobExplorer != null, "A JobExplorer must be provided"); - } - - - /** - * Given a step and configuration, return true if the step should start, - * false if it should not, and throw an exception if the job should finish. - * @param lastStepExecution the last step execution - * @param jobExecution instance of {@link JobExecution} - * @param step instance of {@link Step} - * - * @throws StartLimitExceededException if the start limit has been exceeded - * for this step - * @throws JobRestartException if the job is in an inconsistent state from - * an earlier failure - */ - @Override - protected boolean shouldStart(StepExecution lastStepExecution, JobExecution jobExecution, Step step) - throws JobRestartException, StartLimitExceededException { - BatchStatus stepStatus; - String restartStep = null; - if (lastStepExecution == null) { - jobExecution.getExecutionContext().put("batch.startedStep", step.getName()); - stepStatus = BatchStatus.STARTING; - } - else { - stepStatus = lastStepExecution.getStatus(); - - JobExecution lastJobExecution = getLastJobExecution(jobExecution); - - if(lastJobExecution.getExecutionContext().containsKey("batch.restartStep")) { - restartStep = lastJobExecution.getExecutionContext().getString("batch.restartStep"); - - if(CollectionUtils.isEmpty(jobExecution.getStepExecutions()) && lastJobExecution.getStatus() == BatchStatus.STOPPED && StringUtils.hasText(restartStep)) { - if(!restartStep.equals(step.getName()) && !jobExecution.getExecutionContext().containsKey("batch.startedStep")) { - if (logger.isInfoEnabled()) { - logger.info("Job was stopped and should restart at step " + restartStep + ". The current step is " + step.getName()); - } - return false; - } else { - // Indicates the starting point for execution evaluation per JSR-352 - jobExecution.getExecutionContext().put("batch.startedStep", step.getName()); - } - } - } - } - - if (stepStatus == BatchStatus.UNKNOWN) { - throw new JobRestartException("Cannot restart step from UNKNOWN status. " - + "The last execution ended with a failure that could not be rolled back, " - + "so it may be dangerous to proceed. Manual intervention is probably necessary."); - } - - if ((stepStatus == BatchStatus.COMPLETED && step.isAllowStartIfComplete() == false) - || stepStatus == BatchStatus.ABANDONED) { - // step is complete, false should be returned, indicating that the - // step should not be started - if (logger.isInfoEnabled()) { - logger.info("Step already complete or not restartable, so no action to execute: " + lastStepExecution); - } - return false; - } - - if (getJobRepository().getStepExecutionCount(jobExecution.getJobInstance(), step.getName()) < step.getStartLimit()) { - // step start count is less than start max, return true - return true; - } - else { - // start max has been exceeded, throw an exception. - throw new StartLimitExceededException("Maximum start limit exceeded for step: " + step.getName() - + "StartMax: " + step.getStartLimit()); - } - } - - /** - * Since all JSR-352 jobs are run asynchronously, {@link JobRepository#getLastJobExecution(String, org.springframework.batch.core.JobParameters)} - * could return the currently running {@link JobExecution}. To get around this, we use the {@link JobExplorer} - * to get a list of the executions and get the most recent one that is not the currently running - * {@link JobExecution}. - * - * @param jobExecution - * @return the last executed JobExecution. - */ - private JobExecution getLastJobExecution(JobExecution jobExecution) { - List jobExecutions = jobExplorer.getJobExecutions(jobExecution.getJobInstance()); - JobExecution lastJobExecution = null; - - for (JobExecution curJobExecution : jobExecutions) { - if(lastJobExecution == null && curJobExecution.getId().longValue() != jobExecution.getId().longValue()) { - lastJobExecution = curJobExecution; - } else if(curJobExecution.getId().longValue() != jobExecution.getId().longValue() && (lastJobExecution == null || curJobExecution.getId().longValue() > lastJobExecution.getId().longValue())) { - lastJobExecution = curJobExecution; - } - } - return lastJobExecution; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/JsrFlowExecutor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/JsrFlowExecutor.java deleted file mode 100644 index 4b955a0bb..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/JsrFlowExecutor.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.job.flow; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.job.StepHandler; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.job.flow.JobFlowExecutor; -import org.springframework.batch.core.repository.JobRepository; - -/** - * JSR-352 specific {@link JobFlowExecutor}. Unlike the regular {@link JobFlowExecutor}, - * this extension does not promote an {@link ExitStatus} from a step to the job level if - * a custom exit status has been set on the job. - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrFlowExecutor extends JobFlowExecutor { - - public JsrFlowExecutor(JobRepository jobRepository, - StepHandler stepHandler, JobExecution execution) { - super(jobRepository, stepHandler, execution); - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.job.flow.JobFlowExecutor#addExitStatus(java.lang.String) - */ - @Override - public void addExitStatus(String code) { - ExitStatus status = new ExitStatus(code); - if((exitStatus != null && ExitStatus.isNonDefaultExitStatus(exitStatus)) && !ExitStatus.isNonDefaultExitStatus(status)) { - exitStatus = exitStatus.and(status); - } - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.job.flow.JobFlowExecutor#updateJobExecutionStatus(org.springframework.batch.core.job.flow.FlowExecutionStatus) - */ - @Override - public void updateJobExecutionStatus(FlowExecutionStatus status) { - JobExecution execution = super.getJobExecution(); - - execution.setStatus(findBatchStatus(status)); - - ExitStatus curStatus = execution.getExitStatus(); - if(ExitStatus.isNonDefaultExitStatus(curStatus)) { - exitStatus = exitStatus.and(new ExitStatus(status.getName())); - execution.setExitStatus(exitStatus); - } else { - exitStatus = exitStatus.and(curStatus); - execution.setExitStatus(exitStatus); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/JsrFlowJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/JsrFlowJob.java deleted file mode 100644 index bf69e20ad..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/JsrFlowJob.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.job.flow; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobExecutionException; -import org.springframework.batch.core.JobInterruptedException; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean.DelegateState; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.job.AbstractJob; -import org.springframework.batch.core.job.flow.Flow; -import org.springframework.batch.core.job.flow.FlowExecutionException; -import org.springframework.batch.core.job.flow.FlowJob; -import org.springframework.batch.core.job.flow.JobFlowExecutor; -import org.springframework.batch.core.job.flow.State; -import org.springframework.batch.core.job.flow.support.state.FlowState; -import org.springframework.batch.core.jsr.job.JsrStepHandler; -import org.springframework.batch.core.jsr.job.flow.support.JsrFlow; -import org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState; -import org.springframework.batch.core.jsr.step.DecisionStep; -import org.springframework.batch.core.launch.NoSuchJobException; -import org.springframework.batch.core.launch.support.ExitCodeMapper; - -/** - * JSR-352 specific extension of the {@link FlowJob}. - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrFlowJob extends FlowJob { - - private JobExplorer jobExplorer; - - /** - * No arg constructor (invalid state) - */ - public JsrFlowJob() { - super(); - } - - /** - * Main constructor - * - * @param name of the flow - */ - public JsrFlowJob(String name) { - super(name); - } - - public void setJobExplorer(JobExplorer jobExplorer) { - this.jobExplorer = jobExplorer; - } - - /** - * @see AbstractJob#doExecute(JobExecution) - */ - @Override - protected void doExecute(final JobExecution execution) throws JobExecutionException { - try { - JobFlowExecutor executor = new JsrFlowExecutor(getJobRepository(), - new JsrStepHandler(getJobRepository(), jobExplorer), execution); - - State startState = ((JsrFlow)flow).getStartState(); - - validateFirstStep(startState); - - executor.updateJobExecutionStatus(flow.start(executor).getStatus()); - } - catch (FlowExecutionException e) { - if (e.getCause() instanceof JobExecutionException) { - throw (JobExecutionException) e.getCause(); - } - throw new JobExecutionException("Flow execution ended unexpectedly", e); - } - } - - private void validateFirstStep(State startState) - throws JobExecutionException { - while(true) { - if(startState instanceof DelegateState) { - startState = ((DelegateState) startState).getState(); - } else if(startState instanceof JsrStepState) { - String stepName = startState.getName().substring(startState.getName().indexOf(".") + 1, startState.getName().length()); - Step step = ((JsrStepState) startState).getStep(stepName); - if(step instanceof DecisionStep) { - throw new JobExecutionException("Decision step is an invalid first step"); - } else { - break; - } - } else if(startState instanceof FlowState){ - Flow firstFlow = ((FlowState) startState).getFlows().iterator().next(); - startState = firstFlow.getStates().iterator().next(); - } else { - break; - } - } - } - - /** - * Default mapping from throwable to {@link ExitStatus}. - * - * @param ex the cause of the failure - * @return an {@link ExitStatus} - */ - @Override - protected ExitStatus getDefaultExitStatusForFailure(Throwable ex, JobExecution execution) { - if(!ExitStatus.isNonDefaultExitStatus(execution.getExitStatus())) { - return execution.getExitStatus(); - } else { - ExitStatus exitStatus; - if (ex instanceof JobInterruptedException - || ex.getCause() instanceof JobInterruptedException) { - exitStatus = ExitStatus.STOPPED - .addExitDescription(JobInterruptedException.class.getName()); - } else if (ex instanceof NoSuchJobException - || ex.getCause() instanceof NoSuchJobException) { - exitStatus = new ExitStatus(ExitCodeMapper.NO_SUCH_JOB, ex - .getClass().getName()); - } else { - exitStatus = ExitStatus.FAILED.addExitDescription(ex); - } - - return exitStatus; - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/package-info.java deleted file mode 100644 index e40bd8b74..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * JSR-352 specific extensions of Flow constructs (executor and job). - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.job.flow; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/JsrFlow.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/JsrFlow.java deleted file mode 100644 index 442d6d392..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/JsrFlow.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2013-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.jsr.job.flow.support; - -import java.util.Set; - -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean.DelegateState; -import org.springframework.batch.core.job.flow.Flow; -import org.springframework.batch.core.job.flow.FlowExecutionException; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.job.flow.State; -import org.springframework.batch.core.job.flow.support.SimpleFlow; -import org.springframework.batch.core.job.flow.support.StateTransition; -import org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; - -/** - * Implements JSR-352 specific logic around the execution of a flow. Specifically, this - * {@link Flow} implementation will attempt to find the next state based on the provided - * exit status. If none is found (the exit status isn't mapped), it will attempt to - * resolve the next state basing it on the last step's batch status. Only if both - * attempts fail, the flow will fail due to the inability to find the next state. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrFlow extends SimpleFlow { - - private JsrStepState currentStep; - - /** - * @param name name of the flow - */ - public JsrFlow(String name) { - super(name); - } - - @Nullable - public String getMostRecentStepName() { - if(currentStep != null) { - return currentStep.getStep().getName(); - } else { - return null; - } - } - - @Override - protected boolean isFlowContinued(State state, FlowExecutionStatus status, StepExecution stepExecution) { - if(state instanceof DelegateState) { - state = ((DelegateState) state).getState(); - } - - if(state instanceof JsrStepState) { - currentStep = (JsrStepState) state; - } - - return super.isFlowContinued(state, status, stepExecution); - } - - @Override - protected State nextState(String stateName, FlowExecutionStatus status, StepExecution stepExecution) throws FlowExecutionException { - State nextState = findState(stateName, status, stepExecution); - - if(stepExecution != null) { - ExecutionContext executionContext = stepExecution.getJobExecution().getExecutionContext(); - if(executionContext.containsKey("batch.stoppedStep")) { - String stepName = executionContext.getString("batch.stoppedStep"); - - if(stateName.endsWith(stepName)) { - if(nextState != null && executionContext.containsKey("batch.restartStep") && StringUtils.hasText(executionContext.getString("batch.restartStep"))) { - nextState = findState(stateName, new FlowExecutionStatus(status.getName() + ".RESTART"), stepExecution); - } - } - } - } - - return nextState; - } - - /** - * @return the next {@link Step} (or null if this is the end) - * @throws FlowExecutionException - */ - private State findState(String stateName, FlowExecutionStatus status, StepExecution stepExecution) throws FlowExecutionException { - Set set = getTransitionMap().get(stateName); - - if (set == null) { - throw new FlowExecutionException(String.format("No transitions found in flow=%s for state=%s", getName(), - stateName)); - } - - String next = null; - String exitCode = status.getName(); - for (StateTransition stateTransition : set) { - if (stateTransition.matches(exitCode) || (exitCode.equals("PENDING") && stateTransition.matches("STOPPED"))) { - if (stateTransition.isEnd()) { - // End of job - return null; - } - next = stateTransition.getNext(); - break; - } - } - - if (next == null) { - if(stepExecution != null) { - exitCode = stepExecution.getStatus().toString(); - - for (StateTransition stateTransition : set) { - if (stateTransition.matches(exitCode) || (exitCode.equals("PENDING") && stateTransition.matches("STOPPED"))) { - if (stateTransition.isEnd()) { - // End of job - return null; - } - next = stateTransition.getNext(); - break; - } - } - } - - if(next == null) { - throw new FlowExecutionException(String.format( - "Next state not found in flow=%s for state=%s with exit status=%s", getName(), stateName, status.getName())); - } - } - - if (!getStateMap().containsKey(next)) { - throw new FlowExecutionException(String.format("Next state not specified in flow=%s for next=%s", - getName(), next)); - } - - return getStateMap().get(next); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/package-info.java deleted file mode 100644 index b91977971..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * JSR-352 specific flow extensions. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.job.flow.support; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrEndState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrEndState.java deleted file mode 100644 index e5b3a7a3a..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrEndState.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.job.flow.support.state; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.job.flow.FlowExecutor; -import org.springframework.batch.core.job.flow.State; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.item.ExecutionContext; - -/** - * {@link State} implementation for ending a job per JSR-352 rules if it is - * in progress and continuing if just starting. - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrEndState extends org.springframework.batch.core.job.flow.support.state.EndState { - - private JobRepository jobRepository; - private String restart; - - /** - * @param status The {@link FlowExecutionStatus} to end with - * @param name The name of the state - */ - public JsrEndState(FlowExecutionStatus status, String name) { - super(status, status.getName(), name); - } - - /** - * @param status The {@link FlowExecutionStatus} to end with - * @param name The name of the state - * @param code the exit status. - */ - public JsrEndState(FlowExecutionStatus status, String code, String name) { - super(status, code, name, false); - } - - /** - * @param status The {@link FlowExecutionStatus} to end with - * @param name The name of the state - * @param abandon flag to indicate that previous step execution can be - * marked as abandoned (if there is one) - * @param code the exit status. - * - */ - public JsrEndState(FlowExecutionStatus status, String code, String name, boolean abandon) { - super(status, code, name, abandon); - } - - public JsrEndState(FlowExecutionStatus status, String code, String name, String restart, boolean abandon, JobRepository jobRepository) { - super(status, code, name, abandon); - this.jobRepository = jobRepository; - this.restart = restart; - } - - @Override - public FlowExecutionStatus handle(FlowExecutor executor) - throws Exception { - synchronized (executor) { - - // Special case. If the last step execution could not complete we - // are in an unknown state (possibly unrecoverable). - StepExecution stepExecution = executor.getStepExecution(); - if (stepExecution != null && executor.getStepExecution().getStatus() == BatchStatus.UNKNOWN) { - return FlowExecutionStatus.UNKNOWN; - } - - if (getStatus().isStop()) { - JobExecution jobExecution = stepExecution.getJobExecution(); - ExecutionContext executionContext = jobExecution.getExecutionContext(); - executionContext.put("batch.restartStep", restart); - executionContext.put("batch.stoppedStep", stepExecution.getStepName()); - jobRepository.updateExecutionContext(jobExecution); - - if (!executor.isRestart()) { - /* - * If there are step executions, then we are not at the - * beginning of a restart. - */ - if (isAbandon()) { - /* - * Only if instructed to do so, upgrade the status of - * last step execution so it is not replayed on a - * restart... - */ - executor.abandonStepExecution(); - } - } - else { - /* - * If we are a stop state and we got this far then it must - * be a restart, so return COMPLETED. - */ - return FlowExecutionStatus.COMPLETED; - } - } - - setExitStatus(executor, getCode()); - - return getStatus(); - } - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.job.flow.support.state.EndState#setExitStatus(org.springframework.batch.core.job.flow.FlowExecutor, java.lang.String) - */ - @Override - protected void setExitStatus(FlowExecutor executor, String code) { - StepExecution stepExecution = executor.getStepExecution(); - - ExitStatus status = new ExitStatus(code); - if(!ExitStatus.isNonDefaultExitStatus(status)) { - stepExecution.getJobExecution().setExitStatus(status); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrSplitState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrSplitState.java deleted file mode 100644 index c2bfd154c..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrSplitState.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2014 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.jsr.job.flow.support.state; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.job.flow.Flow; -import org.springframework.batch.core.job.flow.FlowExecution; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.job.flow.FlowExecutor; -import org.springframework.batch.core.jsr.job.flow.support.JsrFlow; - -/** - * JSR-352 states that artifacts cannot set the ExitStatus from within a split for a job. Because - * of this, this state will reset the exit status once the flows have completed (prior to aggregation - * of the results). - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrSplitState extends org.springframework.batch.core.job.flow.support.state.SplitState { - - /** - * @param flows {@link Flow}s to be executed in parallel - * @param name the name to be associated with the split state. - */ - public JsrSplitState(Collection flows, String name) { - super(flows, name); - } - - /** - * Resets the {@link JobExecution}'s exit status before aggregating the results of the flows within - * the split. - * - * @param results the {@link FlowExecution}s from each of the flows executed within this split - * @param executor the {@link FlowExecutor} used to execute the flows - */ - @Override - protected FlowExecutionStatus doAggregation(Collection results, FlowExecutor executor) { - List stepNames = new ArrayList<>(); - - for (Flow curFlow : getFlows()) { - JsrFlow flow = (JsrFlow) curFlow; - if(flow.getMostRecentStepName() != null) { - stepNames.add(flow.getMostRecentStepName()); - } - } - - if(!stepNames.isEmpty()) { - executor.getJobExecution().getExecutionContext().put("batch.lastSteps", stepNames); - } - - executor.getJobExecution().setExitStatus(null); - - return super.doAggregation(results, executor); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrStepState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrStepState.java deleted file mode 100644 index c5e3dc178..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrStepState.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2014 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.jsr.job.flow.support.state; - -import java.util.Collections; - -import org.springframework.batch.core.Step; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.job.flow.FlowExecutor; - -/** - * Extends {@link org.springframework.batch.core.job.flow.support.state.StepState} to persist what the - * last step that was executed was (used in Decisions and restarts). - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrStepState extends org.springframework.batch.core.job.flow.support.state.StepState { - - /** - * @param step the step that will be executed - */ - public JsrStepState(Step step) { - super(step); - } - - /** - * @param name for the step that will be executed - * @param step the step that will be executed - */ - public JsrStepState(String name, Step step) { - super(name, step); - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.job.flow.support.state.StepState#handle(org.springframework.batch.core.job.flow.FlowExecutor) - */ - @Override - public FlowExecutionStatus handle(FlowExecutor executor) throws Exception { - FlowExecutionStatus result = super.handle(executor); - - executor.getJobExecution().getExecutionContext().put("batch.lastSteps", Collections.singletonList(getStep().getName())); - - return result; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/package-info.java deleted file mode 100644 index 4335b22ea..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/flow/support/state/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * JSR-352 specific states used in flow execution. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.job.flow.support.state; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/package-info.java deleted file mode 100644 index 7592416e9..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/job/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * JSR-352 specific handler implementations. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.job; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/JsrJobOperator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/JsrJobOperator.java deleted file mode 100644 index 96f824844..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/JsrJobOperator.java +++ /dev/null @@ -1,850 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.launch; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Semaphore; -import jakarta.batch.operations.BatchRuntimeException; -import jakarta.batch.operations.JobExecutionAlreadyCompleteException; -import jakarta.batch.operations.JobExecutionIsRunningException; -import jakarta.batch.operations.JobExecutionNotMostRecentException; -import jakarta.batch.operations.JobExecutionNotRunningException; -import jakarta.batch.operations.JobOperator; -import jakarta.batch.operations.JobRestartException; -import jakarta.batch.operations.JobSecurityException; -import jakarta.batch.operations.JobStartException; -import jakarta.batch.operations.NoSuchJobException; -import jakarta.batch.operations.NoSuchJobExecutionException; -import jakarta.batch.operations.NoSuchJobInstanceException; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.JobInstance; -import jakarta.batch.runtime.StepExecution; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.DuplicateJobException; -import org.springframework.batch.core.converter.JobParametersConverter; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.jsr.JsrJobContextFactoryBean; -import org.springframework.batch.core.jsr.JsrJobExecution; -import org.springframework.batch.core.jsr.JsrJobParametersConverter; -import org.springframework.batch.core.jsr.JsrStepExecution; -import org.springframework.batch.core.jsr.configuration.xml.JsrXmlApplicationContext; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.batch.core.step.NoSuchStepException; -import org.springframework.batch.core.step.StepLocator; -import org.springframework.batch.core.step.tasklet.StoppableTasklet; -import org.springframework.batch.core.step.tasklet.Tasklet; -import org.springframework.batch.core.step.tasklet.TaskletStep; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.support.GenericXmlApplicationContext; -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.TaskExecutor; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.util.Assert; - -/** - * The entrance for executing batch jobs as defined by JSR-352. This class provides - * a single base {@link ApplicationContext} that is the equivalent to the following: - * - * <beans> - * <batch:job-repository id="jobRepository" ... /> - * - * <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> - * ... - * </bean> - * - * <bean id="batchJobOperator" class="org.springframework.batch.core.launch.support.SimpleJobOperator"> - * ... - * </bean> - * - * <bean id="jobExplorer" class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"> - * ... - * </bean> - * - * <bean id="dataSource" - * class="org.apache.commons.dbcp2.BasicDataSource"> - * ... - * </bean> - * - * <bean id="transactionManager" - * class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> - * ... - * </bean> - * - * <bean id="jobParametersConverter" class="org.springframework.batch.core.jsr.JsrJobParametersConverter"/> - * - * <bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/> - * - * <bean id="placeholderProperties" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> - * ... - * </bean> - * </beans> - * - * A custom configuration of the above components can be specified by providing a system property JSR-352-BASE-CONTEXT. - * The location that is provided by this system property will override any beans as defined in baseContext.xml. - * - * Calls to {@link JobOperator#start(String, Properties)} will provide a child context to the above context - * using the job definition and batch.xml if provided. - * - * By default, calls to start/restart will result in asynchronous execution of the batch job (via an asynchronous {@link TaskExecutor}. - * For synchronous behavior or customization of thread behavior, a different {@link TaskExecutor} implementation is required to - * be provided. - * - * Note: This class is intended to only be used for JSR-352 configured jobs. Use of - * this {@link JobOperator} to start/stop/restart Spring Batch jobs may result in unexpected behaviors due to - * how job instances are identified differently. - * - * @author Michael Minella - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrJobOperator implements JobOperator, ApplicationContextAware, InitializingBean { - private static final String JSR_JOB_CONTEXT_BEAN_NAME = "jsr_jobContext"; - private final Log logger = LogFactory.getLog(getClass()); - - private JobExplorer jobExplorer; - private JobRepository jobRepository; - private TaskExecutor taskExecutor; - private JobParametersConverter jobParametersConverter; - private ApplicationContext baseContext; - private PlatformTransactionManager transactionManager; - private static ExecutingJobRegistry jobRegistry = new ExecutingJobRegistry(); - - /** - * Public constructor used by {@link BatchRuntime#getJobOperator()}. This will bootstrap a - * singleton ApplicationContext if one has not already been created (and will utilize the existing - * one if it has) to populate itself. - */ - public JsrJobOperator() { - - this.baseContext = BaseContextHolder.getInstance().getContext(); - - baseContext.getAutowireCapableBeanFactory().autowireBeanProperties(this, - AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false); - - if(taskExecutor == null) { - taskExecutor = new SimpleAsyncTaskExecutor(); - } - } - - /** - * The no-arg constructor is used by the {@link BatchRuntime#getJobOperator()} and so bootstraps - * an {@link ApplicationContext}. This constructor does not and is therefore dependency injection - * friendly. Also useful for unit testing. - * - * @param jobExplorer an instance of Spring Batch's {@link JobExplorer}. - * @param jobRepository an instance of Spring Batch's {@link JobOperator}. - * @param jobParametersConverter an instance of Spring Batch's {@link JobParametersConverter}. - * @param transactionManager a {@link PlatformTransactionManager}. - */ - public JsrJobOperator(JobExplorer jobExplorer, JobRepository jobRepository, JobParametersConverter jobParametersConverter, PlatformTransactionManager transactionManager) { - Assert.notNull(jobExplorer, "A JobExplorer is required"); - Assert.notNull(jobRepository, "A JobRepository is required"); - Assert.notNull(jobParametersConverter, "A ParametersConverter is required"); - Assert.notNull(transactionManager, "A PlatformTransactionManager is required"); - - this.jobExplorer = jobExplorer; - this.jobRepository = jobRepository; - this.jobParametersConverter = jobParametersConverter; - this.transactionManager = transactionManager; - } - - public void setJobExplorer(JobExplorer jobExplorer) { - Assert.notNull(jobExplorer, "A JobExplorer is required"); - - this.jobExplorer = jobExplorer; - } - - public void setJobRepository(JobRepository jobRepository) { - Assert.notNull(jobRepository, "A JobRepository is required"); - - this.jobRepository = jobRepository; - } - - public void setTransactionManager(PlatformTransactionManager transactionManager) { - Assert.notNull(transactionManager, "A PlatformTransactionManager is required"); - - this.transactionManager = transactionManager; - } - - public void setTaskExecutor(TaskExecutor taskExecutor) { - this.taskExecutor = taskExecutor; - } - - protected TaskExecutor getTaskExecutor() { - return taskExecutor; - } - - @Override - public void afterPropertiesSet() throws Exception { - if (this.taskExecutor == null) { - this.taskExecutor = new SimpleAsyncTaskExecutor(); - } - } - - /** - * Used to convert the {@link Properties} objects used by JSR-352 to the {@link JobParameters} - * objects used in Spring Batch. The default implementation used will configure all parameters - * to be non-identifying (per the JSR). - * - * @param converter A {@link Converter} implementation used to convert {@link Properties} to - * {@link JobParameters} - */ - public void setJobParametersConverter(JobParametersConverter converter) { - Assert.notNull(converter, "A Converter is required"); - - this.jobParametersConverter = converter; - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#abandon(long) - */ - @Override - public void abandon(long jobExecutionId) throws NoSuchJobExecutionException, - JobExecutionIsRunningException, JobSecurityException { - org.springframework.batch.core.JobExecution jobExecution = jobExplorer.getJobExecution(jobExecutionId); - - if(jobExecution == null) { - throw new NoSuchJobExecutionException("Unable to retrieve JobExecution for id " + jobExecutionId); - } - - if(jobExecution.isRunning()) { - throw new JobExecutionIsRunningException("Unable to abandon a job that is currently running"); - } - - jobExecution.upgradeStatus(BatchStatus.ABANDONED); - jobRepository.update(jobExecution); - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getJobExecution(long) - */ - @Override - public JobExecution getJobExecution(long executionId) - throws NoSuchJobExecutionException, JobSecurityException { - org.springframework.batch.core.JobExecution jobExecution = jobExplorer.getJobExecution(executionId); - - if(jobExecution == null) { - throw new NoSuchJobExecutionException("No execution was found for executionId " + executionId); - } - - return new JsrJobExecution(jobExecution, jobParametersConverter); - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getJobExecutions(jakarta.batch.runtime.JobInstance) - */ - @Override - public List getJobExecutions(JobInstance jobInstance) - throws NoSuchJobInstanceException, JobSecurityException { - if(jobInstance == null) { - throw new NoSuchJobInstanceException("A null JobInstance was provided"); - } - - org.springframework.batch.core.JobInstance instance = (org.springframework.batch.core.JobInstance) jobInstance; - List batchExecutions = jobExplorer.getJobExecutions(instance); - - if(batchExecutions == null || batchExecutions.size() == 0) { - throw new NoSuchJobInstanceException("Unable to find JobInstance " + jobInstance.getInstanceId()); - } - - List results = new ArrayList<>(batchExecutions.size()); - for (org.springframework.batch.core.JobExecution jobExecution : batchExecutions) { - results.add(new JsrJobExecution(jobExecution, jobParametersConverter)); - } - - return results; - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getJobInstance(long) - */ - @Override - public JobInstance getJobInstance(long executionId) - throws NoSuchJobExecutionException, JobSecurityException { - org.springframework.batch.core.JobExecution execution = jobExplorer.getJobExecution(executionId); - - if(execution == null) { - throw new NoSuchJobExecutionException("The JobExecution was not found"); - } - - return jobExplorer.getJobInstance(execution.getJobInstance().getId()); - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getJobInstanceCount(java.lang.String) - */ - @Override - public int getJobInstanceCount(String jobName) throws NoSuchJobException, - JobSecurityException { - try { - int count = jobExplorer.getJobInstanceCount(jobName); - - if(count <= 0) { - throw new NoSuchJobException("No job instances were found for job name " + jobName); - } else { - return count; - } - } catch (org.springframework.batch.core.launch.NoSuchJobException e) { - throw new NoSuchJobException("No job instances were found for job name " + jobName); - } - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getJobInstances(java.lang.String, int, int) - */ - @Override - public List getJobInstances(String jobName, int start, int count) - throws NoSuchJobException, JobSecurityException { - List jobInstances = jobExplorer.getJobInstances(jobName, start, count); - - if(jobInstances == null || jobInstances.size() == 0) { - throw new NoSuchJobException("The job was not found"); - } - - return new ArrayList<>(jobInstances); - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getJobNames() - */ - @Override - public Set getJobNames() throws JobSecurityException { - return new HashSet<>(jobExplorer.getJobNames()); - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getParameters(long) - */ - @Override - public Properties getParameters(long executionId) - throws NoSuchJobExecutionException, JobSecurityException { - org.springframework.batch.core.JobExecution execution = jobExplorer.getJobExecution(executionId); - - if(execution == null) { - throw new NoSuchJobExecutionException("Unable to find the JobExecution for id " + executionId); - } - - Properties properties = jobParametersConverter.getProperties(execution.getJobParameters()); - properties.remove(JsrJobParametersConverter.JOB_RUN_ID); - - return properties; - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getRunningExecutions(java.lang.String) - */ - @Override - public List getRunningExecutions(String name) - throws NoSuchJobException, JobSecurityException { - Set findRunningJobExecutions = jobExplorer.findRunningJobExecutions(name); - - if(findRunningJobExecutions.isEmpty()) { - throw new NoSuchJobException("Job name: " + name + " not found."); - } - - List results = new ArrayList<>(findRunningJobExecutions.size()); - - for (org.springframework.batch.core.JobExecution jobExecution : findRunningJobExecutions) { - results.add(jobExecution.getId()); - } - - return results; - } - - /* (non-Javadoc) - * @see jakarta.batch.operations.JobOperator#getStepExecutions(long) - */ - @Override - public List getStepExecutions(long executionId) - throws NoSuchJobExecutionException, JobSecurityException { - org.springframework.batch.core.JobExecution execution = jobExplorer.getJobExecution(executionId); - - if(execution == null) { - throw new NoSuchJobException("JobExecution with the id " + executionId + " was not found"); - } - - Collection executions = execution.getStepExecutions(); - - List batchExecutions = new ArrayList<>(); - - if(executions != null) { - for (org.springframework.batch.core.StepExecution stepExecution : executions) { - if(!stepExecution.getStepName().contains(":partition")) { - batchExecutions.add(new JsrStepExecution(jobExplorer.getStepExecution(executionId, stepExecution.getId()))); - } - } - } - - return batchExecutions; - } - - /** - * Creates a child {@link ApplicationContext} for the job being requested based upon - * the /META-INF/batch.xml (if exists) and the /META-INF/batch-jobs/<jobName>.xml - * configuration and restart the job. - * - * @param executionId the database id of the job execution to be restarted. - * @param params any job parameters to be used during the execution of this job. - * @throws JobExecutionAlreadyCompleteException thrown if the requested job execution has - * a status of COMPLETE - * @throws NoSuchJobExecutionException throw if the requested job execution does not exist - * in the repository - * @throws JobExecutionNotMostRecentException thrown if the requested job execution is not - * the most recent attempt for the job instance it's related to. - * @throws JobRestartException thrown for any general errors during the job restart process - */ - @Override - public long restart(long executionId, Properties params) - throws JobExecutionAlreadyCompleteException, - NoSuchJobExecutionException, JobExecutionNotMostRecentException, - JobRestartException, JobSecurityException { - org.springframework.batch.core.JobExecution previousJobExecution = jobExplorer.getJobExecution(executionId); - - if (previousJobExecution == null) { - throw new NoSuchJobExecutionException("No JobExecution found for id: [" + executionId + "]"); - } else if(previousJobExecution.getStatus().equals(BatchStatus.COMPLETED)) { - throw new JobExecutionAlreadyCompleteException("The requested job has already completed"); - } - - List previousExecutions = jobExplorer.getJobExecutions(previousJobExecution.getJobInstance()); - - for (org.springframework.batch.core.JobExecution jobExecution : previousExecutions) { - if(jobExecution.getCreateTime().compareTo(previousJobExecution.getCreateTime()) > 0) { - throw new JobExecutionNotMostRecentException("The requested JobExecution to restart was not the most recently run"); - } - - if(jobExecution.getStatus().equals(BatchStatus.ABANDONED)) { - throw new JobRestartException("JobExecution ID: " + jobExecution.getId() + " is abandoned and attempted to be restarted."); - } - } - - final String jobName = previousJobExecution.getJobInstance().getJobName(); - - Properties jobRestartProperties = getJobRestartProperties(params, previousJobExecution); - - final JsrXmlApplicationContext batchContext = new JsrXmlApplicationContext(jobRestartProperties); - batchContext.setValidating(false); - - Resource batchXml = new ClassPathResource("/META-INF/batch.xml"); - Resource jobXml = new ClassPathResource(previousJobExecution.getJobConfigurationName()); - - if(batchXml.exists()) { - batchContext.load(batchXml); - } - - if(jobXml.exists()) { - batchContext.load(jobXml); - } - - AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.batch.core.jsr.JsrJobContextFactoryBean").getBeanDefinition(); - beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); - batchContext.registerBeanDefinition(JSR_JOB_CONTEXT_BEAN_NAME, beanDefinition); - - batchContext.setParent(baseContext); - - try { - batchContext.refresh(); - } catch (BeanCreationException e) { - throw new JobRestartException(e); - } - - final org.springframework.batch.core.JobExecution jobExecution; - - try { - JobParameters jobParameters = jobParametersConverter.getJobParameters(jobRestartProperties); - jobExecution = jobRepository.createJobExecution(previousJobExecution.getJobInstance(), jobParameters, previousJobExecution.getJobConfigurationName()); - } catch (Exception e) { - throw new JobRestartException(e); - } - - try { - final Semaphore semaphore = new Semaphore(1); - final List exceptionHolder = Collections.synchronizedList(new ArrayList<>()); - semaphore.acquire(); - - taskExecutor.execute(new Runnable() { - - @Override - public void run() { - JsrJobContextFactoryBean factoryBean = null; - try { - factoryBean = (JsrJobContextFactoryBean) batchContext.getBean("&" + JSR_JOB_CONTEXT_BEAN_NAME); - factoryBean.setJobExecution(jobExecution); - final Job job = batchContext.getBean(Job.class); - - if(!job.isRestartable()) { - throw new JobRestartException("Job " + jobName + " is not restartable"); - } - - semaphore.release(); - // Initialization of the JobExecution for job level dependencies - jobRegistry.register(job, jobExecution); - job.execute(jobExecution); - jobRegistry.remove(jobExecution); - } - catch (Exception e) { - exceptionHolder.add(e); - } finally { - if(factoryBean != null) { - factoryBean.close(); - } - - batchContext.close(); - - if(semaphore.availablePermits() == 0) { - semaphore.release(); - } - } - } - }); - - semaphore.acquire(); - if(exceptionHolder.size() > 0) { - semaphore.release(); - throw new JobRestartException(exceptionHolder.get(0)); - } - } - catch (Exception e) { - jobExecution.upgradeStatus(BatchStatus.FAILED); - if (jobExecution.getExitStatus().equals(ExitStatus.UNKNOWN)) { - jobExecution.setExitStatus(ExitStatus.FAILED.addExitDescription(e)); - } - - jobRepository.update(jobExecution); - - if(batchContext.isActive()) { - batchContext.close(); - } - - throw new JobRestartException(e); - } - - return jobExecution.getId(); - } - - protected Properties getJobRestartProperties(Properties params, org.springframework.batch.core.JobExecution previousJobExecution) { - Properties jobRestartProperties = new Properties(); - - if (previousJobExecution != null) { - JobParameters previousJobParameters = previousJobExecution.getJobParameters(); - - if (previousJobParameters != null && !previousJobParameters.isEmpty()) { - jobRestartProperties.putAll(previousJobParameters.toProperties()); - } - } - - if (params != null) { - Enumeration propertyNames = params.propertyNames(); - - while(propertyNames.hasMoreElements()) { - String curName = (String) propertyNames.nextElement(); - jobRestartProperties.setProperty(curName, params.getProperty(curName)); - } - } - - return jobRestartProperties; - } - - /** - * Creates a child {@link ApplicationContext} for the job being requested based upon - * the /META-INF/batch.xml (if exists) and the /META-INF/batch-jobs/<jobName>.xml - * configuration and launches the job. Per JSR-352, calls to this method will always - * create a new {@link JobInstance} (and related {@link JobExecution}). - * - * @param jobName the name of the job XML file without the .xml that is located within the - * /META-INF/batch-jobs directory. - * @param params any job parameters to be used during the execution of this job. - */ - @Override - public long start(String jobName, Properties params) throws JobStartException, - JobSecurityException { - final JsrXmlApplicationContext batchContext = new JsrXmlApplicationContext(params); - batchContext.setValidating(false); - - Resource batchXml = new ClassPathResource("/META-INF/batch.xml"); - String jobConfigurationLocation = "/META-INF/batch-jobs/" + jobName + ".xml"; - Resource jobXml = new ClassPathResource(jobConfigurationLocation); - - if(batchXml.exists()) { - batchContext.load(batchXml); - } - - if(jobXml.exists()) { - batchContext.load(jobXml); - } - - AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.batch.core.jsr.JsrJobContextFactoryBean").getBeanDefinition(); - beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); - batchContext.registerBeanDefinition(JSR_JOB_CONTEXT_BEAN_NAME, beanDefinition); - - if(baseContext != null) { - batchContext.setParent(baseContext); - } else { - batchContext.getBeanFactory().registerSingleton("jobExplorer", jobExplorer); - batchContext.getBeanFactory().registerSingleton("jobRepository", jobRepository); - batchContext.getBeanFactory().registerSingleton("jobParametersConverter", jobParametersConverter); - batchContext.getBeanFactory().registerSingleton("transactionManager", transactionManager); - } - - try { - batchContext.refresh(); - } catch (BeanCreationException e) { - throw new JobStartException(e); - } - - Assert.notNull(jobName, "The job name must not be null."); - - final org.springframework.batch.core.JobExecution jobExecution; - - try { - JobParameters jobParameters = jobParametersConverter.getJobParameters(params); - String [] jobNames = batchContext.getBeanNamesForType(Job.class); - - if(jobNames == null || jobNames.length <= 0) { - throw new BatchRuntimeException("No Job defined in current context"); - } - - org.springframework.batch.core.JobInstance jobInstance = jobRepository.createJobInstance(jobNames[0], jobParameters); - jobExecution = jobRepository.createJobExecution(jobInstance, jobParameters, jobConfigurationLocation); - } catch (Exception e) { - throw new JobStartException(e); - } - - try { - final Semaphore semaphore = new Semaphore(1); - final List exceptionHolder = Collections.synchronizedList(new ArrayList<>()); - semaphore.acquire(); - - taskExecutor.execute(new Runnable() { - - @Override - public void run() { - JsrJobContextFactoryBean factoryBean = null; - try { - factoryBean = (JsrJobContextFactoryBean) batchContext.getBean("&" + JSR_JOB_CONTEXT_BEAN_NAME); - factoryBean.setJobExecution(jobExecution); - final Job job = batchContext.getBean(Job.class); - semaphore.release(); - // Initialization of the JobExecution for job level dependencies - jobRegistry.register(job, jobExecution); - job.execute(jobExecution); - jobRegistry.remove(jobExecution); - } - catch (Exception e) { - exceptionHolder.add(e); - } finally { - if(factoryBean != null) { - factoryBean.close(); - } - - batchContext.close(); - - if(semaphore.availablePermits() == 0) { - semaphore.release(); - } - } - } - }); - - semaphore.acquire(); - if(exceptionHolder.size() > 0) { - semaphore.release(); - throw new JobStartException(exceptionHolder.get(0)); - } - } - catch (Exception e) { - if(jobRegistry.exists(jobExecution.getId())) { - jobRegistry.remove(jobExecution); - } - jobExecution.upgradeStatus(BatchStatus.FAILED); - if (jobExecution.getExitStatus().equals(ExitStatus.UNKNOWN)) { - jobExecution.setExitStatus(ExitStatus.FAILED.addExitDescription(e)); - } - jobRepository.update(jobExecution); - - if(batchContext.isActive()) { - batchContext.close(); - } - - throw new JobStartException(e); - } - return jobExecution.getId(); - } - - /** - * Stops the running job execution if it is currently running. - * - * @param executionId the database id for the {@link JobExecution} to be stopped. - * @throws NoSuchJobExecutionException thrown if {@link JobExecution} instance does not exist. - * @throws JobExecutionNotRunningException thrown if {@link JobExecution} is not running. - */ - @Override - public void stop(long executionId) throws NoSuchJobExecutionException, - JobExecutionNotRunningException, JobSecurityException { - org.springframework.batch.core.JobExecution jobExecution = jobExplorer.getJobExecution(executionId); - // Indicate the execution should be stopped by setting it's status to - // 'STOPPING'. It is assumed that - // the step implementation will check this status at chunk boundaries. - BatchStatus status = jobExecution.getStatus(); - if (!(status == BatchStatus.STARTED || status == BatchStatus.STARTING)) { - throw new JobExecutionNotRunningException("JobExecution must be running so that it can be stopped: "+jobExecution); - } - jobExecution.setStatus(BatchStatus.STOPPING); - jobRepository.update(jobExecution); - - try { - Job job = jobRegistry.getJob(jobExecution.getId()); - if (job instanceof StepLocator) {//can only process as StepLocator is the only way to get the step object - //get the current stepExecution - for (org.springframework.batch.core.StepExecution stepExecution : jobExecution.getStepExecutions()) { - if (stepExecution.getStatus().isRunning()) { - try { - //have the step execution that's running -> need to 'stop' it - Step step = ((StepLocator)job).getStep(stepExecution.getStepName()); - if (step instanceof TaskletStep) { - Tasklet tasklet = ((TaskletStep)step).getTasklet(); - if (tasklet instanceof StoppableTasklet) { - StepSynchronizationManager.register(stepExecution); - ((StoppableTasklet)tasklet).stop(); - StepSynchronizationManager.release(); - } - } - } - catch (NoSuchStepException e) { - logger.warn("Step not found",e); - } - } - } - } - } - catch (NoSuchJobException e) { - logger.warn("Cannot find Job object",e); - } - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - baseContext = applicationContext; - } - - private static class ExecutingJobRegistry { - - private Map registry = new ConcurrentHashMap<>(); - - public void register(Job job, org.springframework.batch.core.JobExecution jobExecution) throws DuplicateJobException { - - if(registry.containsKey(jobExecution.getId())) { - throw new DuplicateJobException("This job execution has already been registered"); - } else { - registry.put(jobExecution.getId(), job); - } - } - - public void remove(org.springframework.batch.core.JobExecution jobExecution) { - if(!registry.containsKey(jobExecution.getId())) { - throw new NoSuchJobExecutionException("The job execution " + jobExecution.getId() + " was not found"); - } else { - registry.remove(jobExecution.getId()); - } - } - - public boolean exists(long jobExecutionId) { - return registry.containsKey(jobExecutionId); - } - - public Job getJob(long jobExecutionId) { - if(!registry.containsKey(jobExecutionId)) { - throw new NoSuchJobExecutionException("The job execution " + jobExecutionId + " was not found"); - } else { - return registry.get(jobExecutionId); - } - } - } - - /** - * A singleton holder used to lazily bootstrap the base context used in JSR-352. - */ - protected static class BaseContextHolder { - - private ApplicationContext context; - - private static BaseContextHolder instance; - - private BaseContextHolder() { - synchronized (BaseContextHolder.class) { - if(this.context == null) { - String overrideContextLocation = System.getProperty("JSR-352-BASE-CONTEXT"); - - List contextLocations = new ArrayList<>(); - - contextLocations.add("jsrBaseContext.xml"); - - if(overrideContextLocation != null) { - contextLocations.add(overrideContextLocation); - } - - this.context = new GenericXmlApplicationContext( - contextLocations.toArray(new String[contextLocations.size()])); - } - } - } - - public static BaseContextHolder getInstance() { - synchronized (BaseContextHolder.class) { - if(instance == null) { - instance = new BaseContextHolder(); - } - } - - return instance; - } - - public ApplicationContext getContext() { - return this.context; - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/package-info.java deleted file mode 100644 index 00f60e37a..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Implementation of the JSR-352 specific job launching facilities. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.launch; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/support/BatchPropertyBeanPostProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/support/BatchPropertyBeanPostProcessor.java deleted file mode 100644 index 42b77f099..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/launch/support/BatchPropertyBeanPostProcessor.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.launch.support; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; - -import jakarta.batch.api.BatchProperty; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.configuration.support.JsrExpressionParser; -import org.springframework.batch.core.scope.StepScope; -import org.springframework.batch.core.scope.context.StepContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.BeanExpressionContext; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.expression.StandardBeanExpressionResolver; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - *

- * {@link BeanPostProcessor} implementation used to inject JSR-352 String properties into batch artifact fields - * that are marked with the {@link BatchProperty} annotation. - *

- * - * @author Chris Schaefer - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -@SuppressWarnings("unchecked") -public class BatchPropertyBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { - private static final String SCOPED_TARGET_BEAN_PREFIX = "scopedTarget."; - private static final Log LOGGER = LogFactory.getLog(BatchPropertyBeanPostProcessor.class); - private static final Set> REQUIRED_ANNOTATIONS = new HashSet<>(); - - private JsrExpressionParser jsrExpressionParser; - private BatchPropertyContext batchPropertyContext; - - static { - ClassLoader cl = BatchPropertyBeanPostProcessor.class.getClassLoader(); - - try { - REQUIRED_ANNOTATIONS.add((Class) cl.loadClass("jakarta.inject.Inject")); - } catch (ClassNotFoundException ex) { - LOGGER.warn("jakarta.inject.Inject not found - @BatchProperty marked fields will not be processed."); - } - - REQUIRED_ANNOTATIONS.add(BatchProperty.class); - } - - @Override - public Object postProcessBeforeInitialization(final Object artifact, String artifactName) throws BeansException { - Properties artifactProperties = getArtifactProperties(artifactName); - - if (artifactProperties.isEmpty()) { - return artifact; - } - - injectBatchProperties(artifact, artifactProperties); - - return artifact; - } - - @Override - public Object postProcessAfterInitialization(Object artifact, String artifactName) throws BeansException { - return artifact; - } - - private Properties getArtifactProperties(String artifactName) { - String originalArtifactName = artifactName; - - if(originalArtifactName.startsWith(SCOPED_TARGET_BEAN_PREFIX)) { - originalArtifactName = artifactName.substring(SCOPED_TARGET_BEAN_PREFIX.length()); - } - - StepContext stepContext = StepSynchronizationManager.getContext(); - - if (stepContext != null) { - return batchPropertyContext.getStepArtifactProperties(stepContext.getStepName(), originalArtifactName); - } - - return batchPropertyContext.getArtifactProperties(originalArtifactName); - } - - private void injectBatchProperties(final Object artifact, final Properties artifactProperties) { - ReflectionUtils.doWithFields(artifact.getClass(), new ReflectionUtils.FieldCallback() { - @Override - public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { - if (isValidFieldModifier(field) && isAnnotated(field)) { - boolean isAccessible = field.isAccessible(); - field.setAccessible(true); - - String batchProperty = getBatchPropertyFieldValue(field, artifactProperties); - - if (StringUtils.hasText(batchProperty)) { - field.set(artifact, batchProperty); - } - - field.setAccessible(isAccessible); - } - } - }); - } - - private String getBatchPropertyFieldValue(Field field, Properties batchArtifactProperties) { - BatchProperty batchProperty = field.getAnnotation(BatchProperty.class); - - if (!"".equals(batchProperty.name())) { - return getBatchProperty(batchProperty.name(), batchArtifactProperties); - } - - return getBatchProperty(field.getName(), batchArtifactProperties); - } - - private String getBatchProperty(String propertyKey, Properties batchArtifactProperties) { - if (batchArtifactProperties.containsKey(propertyKey)) { - String propertyValue = (String) batchArtifactProperties.get(propertyKey); - - return jsrExpressionParser.parseExpression(propertyValue); - } - - return null; - } - - private boolean isAnnotated(Field field) { - for (Class annotation : REQUIRED_ANNOTATIONS) { - if (!field.isAnnotationPresent(annotation)) { - return false; - } - } - - return true; - } - - private boolean isValidFieldModifier(Field field) { - return !Modifier.isStatic(field.getModifiers()) && !Modifier.isFinal(field.getModifiers()); - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { - throw new IllegalArgumentException( - "BatchPropertyBeanPostProcessor requires a ConfigurableListableBeanFactory"); - } - - ConfigurableListableBeanFactory configurableListableBeanFactory = (ConfigurableListableBeanFactory) beanFactory; - - BeanExpressionContext beanExpressionContext = new BeanExpressionContext(configurableListableBeanFactory, - configurableListableBeanFactory.getBean(StepScope.class)); - - this.jsrExpressionParser = new JsrExpressionParser(new StandardBeanExpressionResolver(), beanExpressionContext); - } - - @Autowired - public void setBatchPropertyContext(BatchPropertyContext batchPropertyContext) { - this.batchPropertyContext = batchPropertyContext; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/package-info.java deleted file mode 100644 index 45b3edde3..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Extensions of core batch components to apply JSR-352 specific logic. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandler.java deleted file mode 100644 index e2049b334..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandler.java +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.partition; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.locks.ReentrantLock; - -import jakarta.batch.api.partition.PartitionAnalyzer; -import jakarta.batch.api.partition.PartitionCollector; -import jakarta.batch.api.partition.PartitionMapper; -import jakarta.batch.api.partition.PartitionPlan; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecutionException; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.partition.PartitionHandler; -import org.springframework.batch.core.partition.StepExecutionSplitter; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.task.TaskRejectedException; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.util.Assert; - -/** - * Executes a step instance per thread using a {@link ThreadPoolTaskExecutor} in - * accordance with JSR-352. The results from each step is aggregated into a - * cumulative result. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrPartitionHandler implements PartitionHandler, InitializingBean { - - private static final int DEFAULT_POLLING_INTERVAL = 500; - - // TODO: Replace with proper Channel and Messages once minimum support level for Spring is 4 - private Queue partitionDataQueue; - private ReentrantLock lock; - private Step step; - private int partitions; - private PartitionAnalyzer analyzer; - private PartitionMapper mapper; - private int threads; - private BatchPropertyContext propertyContext; - private JobRepository jobRepository; - private boolean allowStartIfComplete = false; - private Set partitionStepNames = new HashSet<>(); - private int pollingInterval = DEFAULT_POLLING_INTERVAL; - - /** - * @return the step that will be executed by each partition - */ - public Step getStep() { - return step; - } - - /** - * @return the names of each partitioned step - */ - public Collection getPartitionStepNames() { - return partitionStepNames; - } - - /** - * @param allowStartIfComplete flag stating if the step should restart if it - * was complete in a previous run - */ - public void setAllowStartIfComplete(boolean allowStartIfComplete) { - this.allowStartIfComplete = allowStartIfComplete; - } - - /** - * @param queue {@link Queue} to receive the output of the {@link PartitionCollector} - */ - public void setPartitionDataQueue(Queue queue) { - this.partitionDataQueue = queue; - } - - public void setPartitionLock(ReentrantLock lock) { - this.lock = lock; - } - - /** - * @param context {@link BatchPropertyContext} to resolve partition level step properties - */ - public void setPropertyContext(BatchPropertyContext context) { - this.propertyContext = context; - } - - /** - * @param mapper {@link PartitionMapper} used to configure partitioning - */ - public void setPartitionMapper(PartitionMapper mapper) { - this.mapper = mapper; - } - - /** - * @param step the step to be executed as a partitioned step - */ - public void setStep(Step step) { - this.step = step; - } - - /** - * @param analyzer {@link PartitionAnalyzer} - */ - public void setPartitionAnalyzer(PartitionAnalyzer analyzer) { - this.analyzer = analyzer; - } - - /** - * @param threads the number of threads to execute the partitions to be run - * within. The default is the number of partitions. - */ - public void setThreads(int threads) { - this.threads = threads; - } - - /** - * @param partitions the number of partitions to be executed - */ - public void setPartitions(int partitions) { - this.partitions = partitions; - } - - /** - * @param jobRepository {@link JobRepository} - */ - public void setJobRepository(JobRepository jobRepository) { - this.jobRepository = jobRepository; - } - - /** - * @param pollingInterval the duration of partitions completion polling interval - * (in milliseconds). The default value is 500ms. - */ - public void setPollingInterval(int pollingInterval) { - this.pollingInterval = pollingInterval; - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.partition.PartitionHandler#handle(org.springframework.batch.core.partition.StepExecutionSplitter, org.springframework.batch.core.StepExecution) - */ - @Override - public Collection handle(StepExecutionSplitter stepSplitter, - StepExecution stepExecution) throws Exception { - final List> tasks = new ArrayList<>(); - final Set result = new HashSet<>(); - final ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); - - int stepExecutionCount = jobRepository.getStepExecutionCount(stepExecution.getJobExecution().getJobInstance(), stepExecution.getStepName()); - - boolean isRestart = stepExecutionCount > 1; - - Set partitionStepExecutions = splitStepExecution(stepExecution, isRestart); - - for (StepExecution curStepExecution : partitionStepExecutions) { - partitionStepNames.add(curStepExecution.getStepName()); - } - - taskExecutor.setCorePoolSize(threads); - taskExecutor.setMaxPoolSize(threads); - - taskExecutor.initialize(); - - try { - for (final StepExecution curStepExecution : partitionStepExecutions) { - final FutureTask task = createTask(step, curStepExecution); - - try { - taskExecutor.execute(task); - tasks.add(task); - } catch (TaskRejectedException e) { - // couldn't execute one of the tasks - ExitStatus exitStatus = ExitStatus.FAILED - .addExitDescription("TaskExecutor rejected the task for this step."); - /* - * Set the status in case the caller is tracking it through the - * JobExecution. - */ - curStepExecution.setStatus(BatchStatus.FAILED); - curStepExecution.setExitStatus(exitStatus); - result.add(stepExecution); - } - } - - processPartitionResults(tasks, result); - } - finally { - taskExecutor.shutdown(); - } - - return result; - } - - /** - * Blocks until all partitioned steps have completed. As each step completes - * the PartitionAnalyzer analyzes the collector data received from each - * partition (if there is any). - * - * @param tasks The {@link Future} that contains the reference to the executing step - * @param result Set of completed {@link StepExecution}s - * @throws Exception - */ - private void processPartitionResults( - final List> tasks, - final Set result) throws Exception { - while(true) { - Thread.sleep(pollingInterval); - try { - lock.lock(); - while(!partitionDataQueue.isEmpty()) { - analyzer.analyzeCollectorData(partitionDataQueue.remove()); - } - - processFinishedPartitions(tasks, result); - - if(tasks.size() == 0) { - break; - } - } finally { - if(lock.isHeldByCurrentThread()) { - lock.unlock(); - } - } - } - } - - /** - * Uses either the {@link PartitionMapper} or the hard coded configuration to split - * the supplied manager StepExecution into the worker StepExecutions. - * - * @param stepExecution manager {@link StepExecution} - * @param isRestart true if this step is being restarted - * @return a {@link Set} of {@link StepExecution}s to be executed - * @throws Exception - * @throws JobExecutionException - */ - private Set splitStepExecution(StepExecution stepExecution, - boolean isRestart) throws Exception, JobExecutionException { - Set partitionStepExecutions = new HashSet<>(); - if(isRestart) { - if(mapper != null) { - PartitionPlan plan = mapper.mapPartitions(); - - if(plan.getPartitionsOverride()) { - partitionStepExecutions = applyPartitionPlan(stepExecution, plan, false); - - for (StepExecution curStepExecution : partitionStepExecutions) { - curStepExecution.setExecutionContext(new ExecutionContext()); - } - } else { - Properties[] partitionProps = plan.getPartitionProperties(); - - plan = (PartitionPlanState) stepExecution.getExecutionContext().get("partitionPlanState"); - plan.setPartitionProperties(partitionProps); - - partitionStepExecutions = applyPartitionPlan(stepExecution, plan, true); - } - - } else { - StepExecutionSplitter stepSplitter = new JsrStepExecutionSplitter(jobRepository, allowStartIfComplete, stepExecution.getStepName(), true); - partitionStepExecutions = stepSplitter.split(stepExecution, partitions); - } - } else { - if(mapper != null) { - PartitionPlan plan = mapper.mapPartitions(); - partitionStepExecutions = applyPartitionPlan(stepExecution, plan, true); - } else { - StepExecutionSplitter stepSplitter = new JsrStepExecutionSplitter(jobRepository, allowStartIfComplete, stepExecution.getStepName(), true); - partitionStepExecutions = stepSplitter.split(stepExecution, partitions); - } - } - return partitionStepExecutions; - } - - private Set applyPartitionPlan(StepExecution stepExecution, - PartitionPlan plan, boolean restoreState) throws JobExecutionException { - StepExecutionSplitter stepSplitter; - Set partitionStepExecutions; - if(plan.getThreads() > 0) { - threads = plan.getThreads(); - } else if(plan.getPartitions() > 0) { - threads = plan.getPartitions(); - } else { - throw new IllegalArgumentException("Either a number of threads or partitions are required"); - } - - PartitionPlanState partitionPlanState = new PartitionPlanState(); - partitionPlanState.setPartitionPlan(plan); - - stepExecution.getExecutionContext().put("partitionPlanState", partitionPlanState); - - stepSplitter = new JsrStepExecutionSplitter(jobRepository, allowStartIfComplete, stepExecution.getStepName(), restoreState); - partitionStepExecutions = stepSplitter.split(stepExecution, plan.getPartitions()); - registerPartitionProperties(partitionStepExecutions, plan); - return partitionStepExecutions; - } - - private void processFinishedPartitions( - final List> tasks, - final Set result) throws Exception { - for(int i = 0; i < tasks.size(); i++) { - Future curTask = tasks.get(i); - - if(curTask.isDone()) { - StepExecution curStepExecution = curTask.get(); - - if(analyzer != null) { - analyzer.analyzeStatus(curStepExecution.getStatus().getBatchStatus(), curStepExecution.getExitStatus().getExitCode()); - } - - result.add(curStepExecution); - - tasks.remove(i); - i--; - } - } - } - - private void registerPartitionProperties( - Set partitionStepExecutions, PartitionPlan plan) { - Properties[] partitionProperties = plan.getPartitionProperties(); - if(partitionProperties != null) { - Iterator executions = partitionStepExecutions.iterator(); - - int i = 0; - while(executions.hasNext()) { - StepExecution curExecution = executions.next(); - - if(i < partitionProperties.length) { - Properties partitionPropertyValues = partitionProperties[i]; - if(partitionPropertyValues != null) { - propertyContext.setStepProperties(curExecution.getStepName(), partitionPropertyValues); - } - - i++; - } else { - break; - } - } - } - } - - /** - * Creates the task executing the given step in the context of the given execution. - * - * @param step the step to execute - * @param stepExecution the given execution - * @return the task executing the given step - */ - protected FutureTask createTask(final Step step, - final StepExecution stepExecution) { - return new FutureTask<>(new Callable() { - @Override - public StepExecution call() throws Exception { - step.execute(stepExecution); - return stepExecution; - } - }); - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.notNull(propertyContext, "A BatchPropertyContext is required"); - Assert.isTrue(mapper != null || (threads > 0 || partitions > 0), "Either a mapper implementation or the number of partitions/threads is required"); - Assert.notNull(jobRepository, "A JobRepository is required"); - Assert.isTrue(pollingInterval >= 0, "The polling interval must be positive"); - - if(partitionDataQueue == null) { - partitionDataQueue = new LinkedBlockingQueue<>(); - } - - if(lock == null) { - lock = new ReentrantLock(); - } - } - - /** - * Since a {@link PartitionPlan} could provide dynamic data (different results from run to run), - * the batch runtime needs to save off the results for restarts. This class serves as a container - * used to save off that state. - * - * @author Michael Minella - * @since 3.0 - */ - public static class PartitionPlanState implements PartitionPlan, Serializable { - - private static final long serialVersionUID = 1L; - private Properties[] partitionProperties; - private int partitions; - private int threads; - - /** - * @param plan the {@link PartitionPlan} that is the source of the state - */ - public PartitionPlanState(PartitionPlan plan) { - partitionProperties = plan.getPartitionProperties(); - partitions = plan.getPartitions(); - threads = plan.getThreads(); - } - - public PartitionPlanState() { - } - - public void setPartitionPlan(PartitionPlan plan) { - this.partitionProperties = plan.getPartitionProperties(); - this.partitions = plan.getPartitions(); - this.threads = plan.getThreads(); - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#getPartitionProperties() - */ - @Override - public Properties[] getPartitionProperties() { - return partitionProperties; - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#getPartitions() - */ - @Override - public int getPartitions() { - return partitions; - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#getThreads() - */ - @Override - public int getThreads() { - return threads; - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#setPartitions(int) - */ - @Override - public void setPartitions(int count) { - this.partitions = count; - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#setPartitionsOverride(boolean) - */ - @Override - public void setPartitionsOverride(boolean override) { - // Intentional No-op - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#getPartitionsOverride() - */ - @Override - public boolean getPartitionsOverride() { - return false; - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#setThreads(int) - */ - @Override - public void setThreads(int count) { - this.threads = count; - } - - /* (non-Javadoc) - * @see jakarta.batch.api.partition.PartitionPlan#setPartitionProperties(java.util.Properties[]) - */ - @Override - public void setPartitionProperties(Properties[] props) { - this.partitionProperties = props; - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrStepExecutionSplitter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrStepExecutionSplitter.java deleted file mode 100644 index 257489de8..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrStepExecutionSplitter.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.partition; - -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobExecutionException; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.launch.JsrJobOperator; -import org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.item.ExecutionContext; - -import java.util.Comparator; -import java.util.Set; -import java.util.TreeSet; - -/** - * Provides JSR-352 specific behavior for the splitting of {@link StepExecution}s. - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrStepExecutionSplitter extends SimpleStepExecutionSplitter { - - private String stepName; - private JobRepository jobRepository; - private boolean restoreState; - - public JsrStepExecutionSplitter(JobRepository jobRepository, boolean allowStartIfComplete, String stepName, boolean restoreState) { - super(jobRepository, allowStartIfComplete, stepName, null); - this.stepName = stepName; - this.jobRepository = jobRepository; - this.restoreState = restoreState; - } - - @Override - public String getStepName() { - return this.stepName; - } - - /** - * Returns the same number of {@link StepExecution}s as the gridSize specifies. Each - * of the child StepExecutions will not be available via the {@link JsrJobOperator} per - * JSR-352. - * - * @see https://java.net/projects/jbatch/lists/public/archive/2013-10/message/10 - */ - @Override - public Set split(StepExecution stepExecution, int gridSize) - throws JobExecutionException { - Set executions = new TreeSet<>(new Comparator() { - - @Override - public int compare(StepExecution arg0, StepExecution arg1) { - String r1 = ""; - String r2 = ""; - if (arg0 != null) { - r1 = arg0.getStepName(); - } - if (arg1 != null) { - r2 = arg1.getStepName(); - } - - return r1.compareTo(r2); - } - }); - JobExecution jobExecution = stepExecution.getJobExecution(); - - for(int i = 0; i < gridSize; i++) { - String stepName = this.stepName + ":partition" + i; - JobExecution curJobExecution = new JobExecution(jobExecution); - StepExecution curStepExecution = new StepExecution(stepName, curJobExecution); - - if(!restoreState || isStartable(curStepExecution, new ExecutionContext())) { - executions.add(curStepExecution); - } - } - - jobRepository.addAll(executions); - - return executions; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/PartitionCollectorAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/PartitionCollectorAdapter.java deleted file mode 100644 index 806eb3e1d..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/PartitionCollectorAdapter.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.partition; - -import java.io.Serializable; -import java.util.Queue; -import java.util.concurrent.locks.ReentrantLock; - -import jakarta.batch.api.partition.PartitionCollector; -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.util.Assert; - -/** - * Adapter class used to wrap a {@link PartitionCollector} so that it can be consumed - * as a {@link ChunkListener}. A thread-safe {@link Queue} is required along with the - * {@link PartitionCollector}. The {@link Queue} is where the result of the call to - * the PartitionCollector will be placed. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class PartitionCollectorAdapter implements ChunkListener { - - private PartitionCollector collector; - private Queue partitionQueue; - private ReentrantLock lock; - - public PartitionCollectorAdapter(Queue queue, PartitionCollector collector) { - Assert.notNull(queue, "A thread-safe Queue is required"); - Assert.notNull(collector, "A PartitionCollector is required"); - - this.partitionQueue = queue; - this.collector = collector; - } - - public void setPartitionLock(ReentrantLock lock) { - this.lock = lock; - } - - @Override - public void beforeChunk(ChunkContext context) { - } - - @Override - public void afterChunk(ChunkContext context) { - try { - if(context.isComplete()) { - lock.lock(); - Serializable collectPartitionData = collector.collectPartitionData(); - - if(collectPartitionData != null) { - partitionQueue.add(collectPartitionData); - } - } - } catch (Throwable e) { - throw new BatchRuntimeException("An error occurred while collecting data from the PartitionCollector", e); - } finally { - if(lock.isHeldByCurrentThread()) { - lock.unlock(); - } - } - } - - @Override - public void afterChunkError(ChunkContext context) { - try { - lock.lock(); - if(context.isComplete()) { - Serializable collectPartitionData = collector.collectPartitionData(); - - if(collectPartitionData != null) { - partitionQueue.add(collectPartitionData); - } - } - } catch (Throwable e) { - throw new BatchRuntimeException("An error occurred while collecting data from the PartitionCollector", e); - } finally { - if(lock.isHeldByCurrentThread()) { - lock.unlock(); - } - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/package-info.java deleted file mode 100644 index 7ab8ea49e..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Implementation of JSR-352 specific partitioning extensions. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.partition; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/JsrBeanScopeBeanFactoryPostProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/JsrBeanScopeBeanFactoryPostProcessor.java deleted file mode 100644 index 067f19fe3..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/JsrBeanScopeBeanFactoryPostProcessor.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.partition.support; - -import org.springframework.batch.core.jsr.configuration.xml.StepFactoryBean; -import org.springframework.batch.core.jsr.partition.JsrPartitionHandler; -import org.springframework.beans.BeansException; -import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.RuntimeBeanReference; - -import jakarta.batch.api.partition.PartitionAnalyzer; -import jakarta.batch.api.partition.PartitionMapper; -import jakarta.batch.api.partition.PartitionReducer; - -/** - * In order for property resolution to occur correctly within the scope of a JSR-352 - * batch job, initialization of job level artifacts must occur on the same thread that - * the job is executing. To allow this to occur, {@link PartitionMapper}, - * {@link PartitionReducer}, and {@link PartitionAnalyzer} are all configured to - * lazy initialization (equivalent to lazy-init="true"). - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrBeanScopeBeanFactoryPostProcessor implements BeanFactoryPostProcessor { - - private JobLevelBeanLazyInitializer initializer; - - /* (non-Javadoc) - * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory) - */ - @Override - public void postProcessBeanFactory( - ConfigurableListableBeanFactory beanFactory) throws BeansException { - if (initializer == null) { - this.initializer = new JobLevelBeanLazyInitializer(beanFactory); - } - - String[] beanNames = beanFactory.getBeanDefinitionNames(); - - for (String curName : beanNames) { - initializer.visitBeanDefinition(beanFactory.getBeanDefinition(curName)); - } - } - - /** - * Looks for beans that may have dependencies that need to be lazily initialized and - * configures the corresponding {@link BeanDefinition} accordingly. - * - * @author Michael Minella - * @since 3.0 - */ - public static class JobLevelBeanLazyInitializer { - - private ConfigurableListableBeanFactory beanFactory; - - public JobLevelBeanLazyInitializer(ConfigurableListableBeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - public void visitBeanDefinition(BeanDefinition beanDefinition) { - String beanClassName = beanDefinition.getBeanClassName(); - - if(StepFactoryBean.class.getName().equals(beanClassName)) { - PropertyValue [] values = beanDefinition.getPropertyValues().getPropertyValues(); - for (PropertyValue propertyValue : values) { - if(propertyValue.getName().equalsIgnoreCase("partitionReducer")) { - RuntimeBeanReference ref = (RuntimeBeanReference) propertyValue.getValue(); - beanFactory.getBeanDefinition(ref.getBeanName()).setLazyInit(true); - } - } - } - - if(JsrPartitionHandler.class.getName().equals(beanClassName)) { - PropertyValue [] values = beanDefinition.getPropertyValues().getPropertyValues(); - for (PropertyValue propertyValue : values) { - String propertyName = propertyValue.getName(); - if(propertyName.equalsIgnoreCase("partitionMapper") || propertyName.equalsIgnoreCase("partitionAnalyzer")) { - RuntimeBeanReference ref = (RuntimeBeanReference) propertyValue.getValue(); - beanFactory.getBeanDefinition(ref.getBeanName()).setLazyInit(true); - } - } - } - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/JsrStepExecutionAggregator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/JsrStepExecutionAggregator.java deleted file mode 100644 index ad95e4260..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/JsrStepExecutionAggregator.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 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.jsr.partition.support; - -import java.util.Collection; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.partition.support.StepExecutionAggregator; -import org.springframework.util.Assert; - -/** - * Aggregates {@link StepExecution}s based on the rules outlined in JSR-352. Specifically - * it aggregates all counts and determines the correct BatchStatus. However, the ExitStatus - * for each child StepExecution is ignored. - * - * @author Michael Minella - * @since 3.0 - */ -public class JsrStepExecutionAggregator implements StepExecutionAggregator { - - /* (non-Javadoc) - * @see org.springframework.batch.core.partition.support.StepExecutionAggregator#aggregate(org.springframework.batch.core.StepExecution, java.util.Collection) - */ - @Override - public void aggregate(StepExecution result, - Collection executions) { - Assert.notNull(result, "To aggregate into a result it must be non-null."); - if (executions == null) { - return; - } - for (StepExecution stepExecution : executions) { - BatchStatus status = stepExecution.getStatus(); - result.setStatus(BatchStatus.max(result.getStatus(), status)); - result.setCommitCount(result.getCommitCount() + stepExecution.getCommitCount()); - result.setRollbackCount(result.getRollbackCount() + stepExecution.getRollbackCount()); - result.setReadCount(result.getReadCount() + stepExecution.getReadCount()); - result.setReadSkipCount(result.getReadSkipCount() + stepExecution.getReadSkipCount()); - result.setWriteCount(result.getWriteCount() + stepExecution.getWriteCount()); - result.setWriteSkipCount(result.getWriteSkipCount() + stepExecution.getWriteSkipCount()); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/package-info.java deleted file mode 100644 index 226692c75..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/support/package-info.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 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. - */ - -/** - * Support classes for JSR-352 partitioning configuration. - * - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.partition.support; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/BatchletStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/BatchletStep.java deleted file mode 100644 index 034d6e940..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/BatchletStep.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 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.jsr.step; - -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.batch.core.step.tasklet.TaskletStep; -import org.springframework.util.Assert; - -/** - * Special sub class of the {@link TaskletStep} for use with JSR-352 jobs. This - * implementation addresses the registration of a {@link BatchPropertyContext} for - * resolution of late binding parameters. - * - * @author Michael Minella - * @since 3.0 - */ -public class BatchletStep extends TaskletStep { - - private BatchPropertyContext propertyContext; - - /** - * @param name name of the step - * @param propertyContext {@link BatchPropertyContext} used to resolve batch properties. - */ - public BatchletStep(String name, BatchPropertyContext propertyContext) { - super(name); - Assert.notNull(propertyContext, "A propertyContext is required"); - this.propertyContext = propertyContext; - } - - @Override - protected void doExecutionRegistration(StepExecution stepExecution) { - StepSynchronizationManager.register(stepExecution, propertyContext); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/DecisionStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/DecisionStep.java deleted file mode 100644 index 35e2d82d0..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/DecisionStep.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import jakarta.batch.api.Decider; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.JsrStepExecution; -import org.springframework.batch.core.step.AbstractStep; -import org.springframework.batch.item.ExecutionContext; - -/** - * Implements a {@link Step} to follow the rules for a decision state - * as defined by JSR-352. Currently does not support the JSR requirement - * to provide all of the last {@link jakarta.batch.runtime.StepExecution}s from - * a split. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class DecisionStep extends AbstractStep { - - private final Decider decider; - - /** - * @param decider a {@link Decider} implementation - */ - public DecisionStep(Decider decider) { - this.decider = decider; - } - - @SuppressWarnings("unchecked") - @Override - protected void doExecute(StepExecution stepExecution) throws Exception { - ExecutionContext executionContext = stepExecution.getJobExecution().getExecutionContext(); - List stepExecutions = new ArrayList<>(); - - if(executionContext.containsKey("batch.lastSteps")) { - List stepNames = (List) executionContext.get("batch.lastSteps"); - - for (String stepName : stepNames) { - StepExecution curStepExecution = getJobRepository().getLastStepExecution(stepExecution.getJobExecution().getJobInstance(), stepName); - stepExecutions.add(new JsrStepExecution(curStepExecution)); - } - } else { - Collection currentRunStepExecutions = stepExecution.getJobExecution().getStepExecutions(); - - StepExecution lastExecution = null; - - if(stepExecutions != null) { - for (StepExecution curStepExecution : currentRunStepExecutions) { - if(lastExecution == null || (curStepExecution.getEndTime() != null && curStepExecution.getEndTime().after(lastExecution.getEndTime()))) { - lastExecution = curStepExecution; - } - } - - stepExecutions.add(new JsrStepExecution(lastExecution)); - } - } - - try { - ExitStatus exitStatus = new ExitStatus(decider.decide(stepExecutions.toArray(new jakarta.batch.runtime.StepExecution[0]))); - - stepExecution.getJobExecution().setExitStatus(exitStatus); - stepExecution.setExitStatus(exitStatus); - - if(executionContext.containsKey("batch.lastSteps")) { - executionContext.remove("batch.lastSteps"); - } - } catch (Exception e) { - stepExecution.setTerminateOnly(); - stepExecution.addFailureException(e); - throw e; - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/PartitionStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/PartitionStep.java deleted file mode 100644 index de040ed18..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/PartitionStep.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step; - -import java.util.Collection; - -import jakarta.batch.api.partition.PartitionReducer; -import jakarta.batch.api.partition.PartitionReducer.PartitionStatus; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.JobExecutionException; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.partition.JsrPartitionHandler; -import org.springframework.batch.core.jsr.partition.support.JsrStepExecutionAggregator; -import org.springframework.batch.core.partition.PartitionHandler; -import org.springframework.batch.core.partition.StepExecutionSplitter; -import org.springframework.batch.core.partition.support.StepExecutionAggregator; -import org.springframework.batch.core.step.NoSuchStepException; -import org.springframework.batch.core.step.StepLocator; -import org.springframework.batch.item.ExecutionContext; - -/** - * An extension of the {@link PartitionStep} that provides additional semantics - * required by JSR-352. Specifically, this implementation adds the required - * lifecycle calls to the {@link PartitionReducer} if it is used. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class PartitionStep extends org.springframework.batch.core.partition.support.PartitionStep implements StepLocator { - - private PartitionReducer reducer; - private boolean hasReducer = false; - private StepExecutionAggregator stepExecutionAggregator = new JsrStepExecutionAggregator(); - - public void setPartitionReducer(PartitionReducer reducer) { - this.reducer = reducer; - hasReducer = reducer != null; - } - - /** - * Delegate execution to the {@link PartitionHandler} provided. The - * {@link StepExecution} passed in here becomes the parent or manager - * execution for the partition, summarizing the status on exit of the - * logical grouping of work carried out by the {@link PartitionHandler}. The - * individual step executions and their input parameters (through - * {@link ExecutionContext}) for the partition elements are provided by the - * {@link StepExecutionSplitter}. - * - * @param stepExecution the manager step execution for the partition - * - * @see Step#execute(StepExecution) - */ - @Override - protected void doExecute(StepExecution stepExecution) throws Exception { - - if(hasReducer) { - reducer.beginPartitionedStep(); - } - - // Wait for task completion and then aggregate the results - Collection stepExecutions = getPartitionHandler().handle(null, stepExecution); - stepExecution.upgradeStatus(BatchStatus.COMPLETED); - stepExecutionAggregator.aggregate(stepExecution, stepExecutions); - - if (stepExecution.getStatus().isUnsuccessful()) { - if (hasReducer) { - reducer.rollbackPartitionedStep(); - reducer.afterPartitionedStepCompletion(PartitionStatus.ROLLBACK); - } - throw new JobExecutionException("Partition handler returned an unsuccessful step"); - } - - if (hasReducer) { - reducer.beforePartitionedStepCompletion(); - reducer.afterPartitionedStepCompletion(PartitionStatus.COMMIT); - } - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.step.StepLocator#getStepNames() - */ - @Override - public Collection getStepNames() { - return ((JsrPartitionHandler) getPartitionHandler()).getPartitionStepNames(); - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.step.StepLocator#getStep(java.lang.String) - */ - @Override - public Step getStep(String stepName) throws NoSuchStepException { - JsrPartitionHandler partitionHandler = (JsrPartitionHandler) getPartitionHandler(); - Collection names = partitionHandler.getPartitionStepNames(); - - if(names.contains(stepName)) { - return partitionHandler.getStep(); - } else { - throw new NoSuchStepException(stepName + " was not found"); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/batchlet/BatchletAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/batchlet/BatchletAdapter.java deleted file mode 100644 index f886aefe3..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/batchlet/BatchletAdapter.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.batchlet; - -import jakarta.batch.api.Batchlet; -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.batch.core.step.tasklet.StoppableTasklet; -import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class BatchletAdapter implements StoppableTasklet { - - private Batchlet batchlet; - - public BatchletAdapter(Batchlet batchlet) { - Assert.notNull(batchlet, "A Batchlet implementation is required"); - this.batchlet = batchlet; - } - - @Nullable - @Override - public RepeatStatus execute(StepContribution contribution, - ChunkContext chunkContext) throws Exception { - String exitStatus; - try { - exitStatus = batchlet.process(); - } finally { - chunkContext.setComplete(); - } - - if(StringUtils.hasText(exitStatus)) { - contribution.setExitStatus(new ExitStatus(exitStatus)); - } - - - return RepeatStatus.FINISHED; - } - - @Override - public void stop() { - try { - batchlet.stop(); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/batchlet/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/batchlet/package-info.java deleted file mode 100644 index 1c60e42fd..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/batchlet/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Classes for supporting JSR-352's {@link jakarta.batch.api.Batchlet}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.step.batchlet; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrBatchletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrBatchletStepBuilder.java deleted file mode 100644 index 923f497de..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrBatchletStepBuilder.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2013-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.jsr.step.builder; - -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.step.BatchletStep; -import org.springframework.batch.core.step.builder.StepBuilderException; -import org.springframework.batch.core.step.builder.StepBuilderHelper; -import org.springframework.batch.core.step.builder.TaskletStepBuilder; -import org.springframework.batch.core.step.tasklet.TaskletStep; -import org.springframework.batch.item.ItemStream; -import org.springframework.batch.repeat.support.RepeatTemplate; -import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; - -/** - * Extension of the {@link TaskletStepBuilder} that uses a {@link BatchletStep} instead - * of a {@link TaskletStep}. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrBatchletStepBuilder extends TaskletStepBuilder { - - private BatchPropertyContext batchPropertyContext; - - /** - * @param context used to resolve lazy bound properties - */ - public void setBatchPropertyContext(BatchPropertyContext context) { - this.batchPropertyContext = context; - } - - public JsrBatchletStepBuilder(StepBuilderHelper> parent) { - super(parent); - } - - /** - * Build the step from the components collected by the fluent setters. Delegates first to {@link #enhance(Step)} and - * then to {@link #createTasklet()} in subclasses to create the actual tasklet. - * - * @return a tasklet step fully configured and read to execute - */ - @Override - public TaskletStep build() { - - registerStepListenerAsChunkListener(); - - BatchletStep step = new BatchletStep(getName(), batchPropertyContext); - - super.enhance(step); - - step.setChunkListeners(chunkListeners.toArray(new ChunkListener[0])); - - if (getTransactionAttribute() != null) { - step.setTransactionAttribute(getTransactionAttribute()); - } - - if (getStepOperations() == null) { - - stepOperations(new RepeatTemplate()); - - if (getTaskExecutor() != null) { - TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); - repeatTemplate.setTaskExecutor(getTaskExecutor()); - repeatTemplate.setThrottleLimit(getThrottleLimit()); - stepOperations(repeatTemplate); - } - - ((RepeatTemplate) getStepOperations()).setExceptionHandler(getExceptionHandler()); - - } - step.setStepOperations(getStepOperations()); - step.setTasklet(createTasklet()); - - step.setStreams(getStreams().toArray(new ItemStream[0])); - - try { - step.afterPropertiesSet(); - } - catch (Exception e) { - throw new StepBuilderException(e); - } - - return step; - - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrFaultTolerantStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrFaultTolerantStepBuilder.java deleted file mode 100644 index 776635784..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrFaultTolerantStepBuilder.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 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.jsr.step.builder; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepListener; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.step.BatchletStep; -import org.springframework.batch.core.jsr.step.item.JsrChunkProvider; -import org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor; -import org.springframework.batch.core.step.builder.FaultTolerantStepBuilder; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.core.step.builder.StepBuilderException; -import org.springframework.batch.core.step.item.ChunkOrientedTasklet; -import org.springframework.batch.core.step.item.ChunkProcessor; -import org.springframework.batch.core.step.item.ChunkProvider; -import org.springframework.batch.core.step.skip.SkipPolicy; -import org.springframework.batch.core.step.tasklet.TaskletStep; -import org.springframework.batch.item.ItemStream; -import org.springframework.batch.repeat.support.RepeatTemplate; -import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; - -/** - * A step builder that extends the {@link FaultTolerantStepBuilder} to create JSR-352 - * specific {@link ChunkProvider} and {@link ChunkProcessor} supporting both the chunking - * pattern defined by the spec as well as skip/retry logic. - * - * @author Michael Minella - * @author Chris Schaefer - * - * @param The input type for the step - * @param The output type for the step - */ -public class JsrFaultTolerantStepBuilder extends FaultTolerantStepBuilder { - - private BatchPropertyContext batchPropertyContext; - - public void setBatchPropertyContext(BatchPropertyContext batchPropertyContext) { - this.batchPropertyContext = batchPropertyContext; - } - - public JsrFaultTolerantStepBuilder(StepBuilder parent) { - super(parent); - } - - @Override - public FaultTolerantStepBuilder faultTolerant() { - return this; - } - - - /** - * Build the step from the components collected by the fluent setters. Delegates first to {@link #enhance(Step)} and - * then to {@link #createTasklet()} in subclasses to create the actual tasklet. - * - * @return a tasklet step fully configured and read to execute - */ - @Override - public TaskletStep build() { - registerStepListenerAsSkipListener(); - registerAsStreamsAndListeners(getReader(), getProcessor(), getWriter()); - - registerStepListenerAsChunkListener(); - - BatchletStep step = new BatchletStep(getName(), batchPropertyContext); - - super.enhance(step); - - step.setChunkListeners(chunkListeners.toArray(new ChunkListener[0])); - - if (getTransactionAttribute() != null) { - step.setTransactionAttribute(getTransactionAttribute()); - } - - if (getStepOperations() == null) { - - stepOperations(new RepeatTemplate()); - - if (getTaskExecutor() != null) { - TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); - repeatTemplate.setTaskExecutor(getTaskExecutor()); - repeatTemplate.setThrottleLimit(getThrottleLimit()); - stepOperations(repeatTemplate); - } - - ((RepeatTemplate) getStepOperations()).setExceptionHandler(getExceptionHandler()); - - } - step.setStepOperations(getStepOperations()); - step.setTasklet(createTasklet()); - - step.setStreams(getStreams().toArray(new ItemStream[0])); - - try { - step.afterPropertiesSet(); - } - catch (Exception e) { - throw new StepBuilderException(e); - } - - return step; - - } - - @Override - protected ChunkProvider createChunkProvider() { - return new JsrChunkProvider<>(); - } - - /** - * Provides a JSR-352 specific implementation of a {@link ChunkProcessor} for use - * within the {@link ChunkOrientedTasklet} - * - * @return a JSR-352 implementation of the {@link ChunkProcessor} - * @see JsrFaultTolerantChunkProcessor - */ - @Override - protected ChunkProcessor createChunkProcessor() { - SkipPolicy skipPolicy = getFatalExceptionAwareProxy(createSkipPolicy()); - JsrFaultTolerantChunkProcessor chunkProcessor = - new JsrFaultTolerantChunkProcessor<>(getReader(), getProcessor(), - getWriter(), createChunkOperations(), createRetryOperations()); - chunkProcessor.setSkipPolicy(skipPolicy); - chunkProcessor.setRollbackClassifier(getRollbackClassifier()); - detectStreamInReader(); - chunkProcessor.setChunkMonitor(getChunkMonitor()); - chunkProcessor.setListeners(getChunkListeners()); - - return chunkProcessor; - } - - private List getChunkListeners() { - List listeners = new ArrayList<>(); - listeners.addAll(getItemListeners()); - listeners.addAll(getSkipListeners()); - listeners.addAll(getJsrRetryListeners()); - - return listeners; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrPartitionStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrPartitionStepBuilder.java deleted file mode 100644 index ef0789343..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrPartitionStepBuilder.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.builder; - -import jakarta.batch.api.partition.PartitionReducer; - -import org.springframework.batch.core.Step; -import org.springframework.batch.core.jsr.step.PartitionStep; -import org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter; -import org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler; -import org.springframework.batch.core.step.builder.PartitionStepBuilder; -import org.springframework.batch.core.step.builder.StepBuilderException; -import org.springframework.batch.core.step.builder.StepBuilderHelper; -import org.springframework.core.task.SyncTaskExecutor; - -/** - * An extension of the {@link PartitionStepBuilder} that uses {@link PartitionStep} - * so that JSR-352 specific semantics are honored. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrPartitionStepBuilder extends PartitionStepBuilder { - - private PartitionReducer reducer; - - /** - * @param parent parent step builder for basic step properties - */ - public JsrPartitionStepBuilder(StepBuilderHelper parent) { - super(parent); - } - - /** - * @param reducer used to provide a single callback at the beginning and end - * of a partitioned step. - * - * @return this - */ - public JsrPartitionStepBuilder reducer(PartitionReducer reducer) { - this.reducer = reducer; - return this; - } - - @Override - public JsrPartitionStepBuilder step(Step step) { - super.step(step); - return this; - } - - @Override - public Step build() { - PartitionStep step = new PartitionStep(); - step.setName(getName()); - super.enhance(step); - - if (getPartitionHandler() != null) { - step.setPartitionHandler(getPartitionHandler()); - } - else { - TaskExecutorPartitionHandler partitionHandler = new TaskExecutorPartitionHandler(); - partitionHandler.setStep(getStep()); - if (getTaskExecutor() == null) { - taskExecutor(new SyncTaskExecutor()); - } - partitionHandler.setGridSize(getGridSize()); - partitionHandler.setTaskExecutor(getTaskExecutor()); - step.setPartitionHandler(partitionHandler); - } - - if (getSplitter() != null) { - step.setStepExecutionSplitter(getSplitter()); - } - else { - - boolean allowStartIfComplete = isAllowStartIfComplete(); - String name = getStepName(); - if (getStep() != null) { - try { - allowStartIfComplete = getStep().isAllowStartIfComplete(); - name = getStep().getName(); - } - catch (Exception e) { - if (logger.isInfoEnabled()) { - logger.info("Ignored exception from step asking for name and allowStartIfComplete flag. " - + "Using default from enclosing PartitionStep (" + name + "," + allowStartIfComplete + ")."); - } - } - } - SimpleStepExecutionSplitter splitter = new SimpleStepExecutionSplitter(); - splitter.setPartitioner(getPartitioner()); - splitter.setJobRepository(getJobRepository()); - splitter.setAllowStartIfComplete(allowStartIfComplete); - splitter.setStepName(name); - splitter(splitter); - step.setStepExecutionSplitter(splitter); - - } - - if (getAggregator() != null) { - step.setStepExecutionAggregator(getAggregator()); - } - - if(reducer != null) { - step.setPartitionReducer(reducer); - } - - try { - step.afterPropertiesSet(); - } - catch (Exception e) { - throw new StepBuilderException(e); - } - - return step; - - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrSimpleStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrSimpleStepBuilder.java deleted file mode 100644 index 254f20374..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/JsrSimpleStepBuilder.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2013-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.core.jsr.step.builder; - -import java.util.ArrayList; - -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.step.BatchletStep; -import org.springframework.batch.core.jsr.step.item.JsrChunkProcessor; -import org.springframework.batch.core.jsr.step.item.JsrChunkProvider; -import org.springframework.batch.core.step.builder.FaultTolerantStepBuilder; -import org.springframework.batch.core.step.builder.SimpleStepBuilder; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.core.step.builder.StepBuilderException; -import org.springframework.batch.core.step.item.ChunkOrientedTasklet; -import org.springframework.batch.core.step.item.ChunkProcessor; -import org.springframework.batch.core.step.item.ChunkProvider; -import org.springframework.batch.core.step.tasklet.Tasklet; -import org.springframework.batch.core.step.tasklet.TaskletStep; -import org.springframework.batch.item.ItemStream; -import org.springframework.batch.repeat.RepeatOperations; -import org.springframework.batch.repeat.support.RepeatTemplate; -import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; -import org.springframework.util.Assert; - -/** - * A step builder that extends the {@link FaultTolerantStepBuilder} to create JSR-352 - * specific {@link ChunkProvider} and {@link ChunkProcessor} supporting the chunking - * pattern defined by the spec. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * - * @param The input type for the step - * @param The output type for the step - */ -public class JsrSimpleStepBuilder extends SimpleStepBuilder { - - private BatchPropertyContext batchPropertyContext; - - public JsrSimpleStepBuilder(StepBuilder parent) { - super(parent); - } - - public JsrPartitionStepBuilder partitioner(Step step) { - return new JsrPartitionStepBuilder(this).step(step); - } - - public void setBatchPropertyContext(BatchPropertyContext batchPropertyContext) { - this.batchPropertyContext = batchPropertyContext; - } - - /** - * Build the step from the components collected by the fluent setters. Delegates first to {@link #enhance(Step)} and - * then to {@link #createTasklet()} in subclasses to create the actual tasklet. - * - * @return a tasklet step fully configured and read to execute - */ - @Override - public TaskletStep build() { - registerStepListenerAsItemListener(); - registerAsStreamsAndListeners(getReader(), getProcessor(), getWriter()); - registerStepListenerAsChunkListener(); - - BatchletStep step = new BatchletStep(getName(), batchPropertyContext); - - super.enhance(step); - - step.setChunkListeners(chunkListeners.toArray(new ChunkListener[0])); - - if (getTransactionAttribute() != null) { - step.setTransactionAttribute(getTransactionAttribute()); - } - - if (getStepOperations() == null) { - - stepOperations(new RepeatTemplate()); - - if (getTaskExecutor() != null) { - TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); - repeatTemplate.setTaskExecutor(getTaskExecutor()); - repeatTemplate.setThrottleLimit(getThrottleLimit()); - stepOperations(repeatTemplate); - } - - ((RepeatTemplate) getStepOperations()).setExceptionHandler(getExceptionHandler()); - - } - step.setStepOperations(getStepOperations()); - step.setTasklet(createTasklet()); - - ItemStream[] streams = getStreams().toArray(new ItemStream[0]); - step.setStreams(streams); - - try { - step.afterPropertiesSet(); - } - catch (Exception e) { - throw new StepBuilderException(e); - } - - return step; - - } - - @Override - protected Tasklet createTasklet() { - Assert.state(getReader() != null, "ItemReader must be provided"); - Assert.state(getProcessor() != null || getWriter() != null, "ItemWriter or ItemProcessor must be provided"); - RepeatOperations repeatOperations = createRepeatOperations(); - ChunkProvider chunkProvider = new JsrChunkProvider<>(); - JsrChunkProcessor chunkProcessor = new JsrChunkProcessor<>(getReader(), getProcessor(), getWriter(), repeatOperations); - chunkProcessor.setListeners(new ArrayList<>(getItemListeners())); - ChunkOrientedTasklet tasklet = new ChunkOrientedTasklet<>(chunkProvider, chunkProcessor); - tasklet.setBuffering(!isReaderTransactionalQueue()); - return tasklet; - } - - private RepeatOperations createRepeatOperations() { - RepeatTemplate repeatOperations = new RepeatTemplate(); - repeatOperations.setCompletionPolicy(getChunkCompletionPolicy()); - repeatOperations.setExceptionHandler(getExceptionHandler()); - return repeatOperations; - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/package-info.java deleted file mode 100644 index 2dbcacea8..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/builder/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Extensions to step related builders to implement JSR-352 specific functionality - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.step.builder; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrChunkProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrChunkProcessor.java deleted file mode 100644 index e2c490928..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrChunkProcessor.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 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.jsr.step.item; - -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.StepListener; -import org.springframework.batch.core.listener.MulticasterBatchListener; -import org.springframework.batch.core.step.item.Chunk; -import org.springframework.batch.core.step.item.ChunkProcessor; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.repeat.RepeatCallback; -import org.springframework.batch.repeat.RepeatContext; -import org.springframework.batch.repeat.RepeatOperations; -import org.springframework.batch.repeat.RepeatStatus; - -/** - * {@link ChunkProcessor} implementation that implements JSR-352's chunking pattern - * (read and process in a loop until the chunk is complete then write). This - * implementation is responsible for all three phases of chunk based processing - * (reading, processing and writing). - * - * @author Michael Minella - * - * @param The input type for the step - * @param The output type for the step - */ -public class JsrChunkProcessor implements ChunkProcessor { - - private final Log logger = LogFactory.getLog(getClass()); - private ItemReader itemReader; - private final MulticasterBatchListener listener = new MulticasterBatchListener<>(); - private RepeatOperations repeatTemplate; - private ItemProcessor itemProcessor; - private ItemWriter itemWriter; - - public JsrChunkProcessor() { - this(null, null, null, null); - } - - public JsrChunkProcessor(ItemReader reader, ItemProcessor processor, ItemWriter writer, RepeatOperations repeatTemplate) { - this.itemReader = reader; - this.itemProcessor = processor; - this.itemWriter = writer; - this.repeatTemplate = repeatTemplate; - } - - protected MulticasterBatchListener getListener() { - return listener; - } - - /** - * Loops through reading (via {@link #provide(StepContribution, Chunk)} and - * processing (via {@link #transform(StepContribution, Object)}) until the chunk - * is complete. Once the chunk is complete, the results are written (via - * {@link #persist(StepContribution, Chunk)}. - * - * @see ChunkProcessor#process(StepContribution, Chunk) - * @param contribution a {@link StepContribution} - * @param chunk a {@link Chunk} - */ - @Override - public void process(final StepContribution contribution, final Chunk chunk) - throws Exception { - - final AtomicInteger filterCount = new AtomicInteger(0); - final Chunk output = new Chunk<>(); - - repeatTemplate.iterate(new RepeatCallback() { - - @Override - public RepeatStatus doInIteration(RepeatContext context) throws Exception { - I item = provide(contribution, chunk); - - if(item != null) { - contribution.incrementReadCount(); - } else { - return RepeatStatus.FINISHED; - } - - O processedItem = transform(contribution, item); - - if(processedItem == null) { - filterCount.incrementAndGet(); - } else { - output.add(processedItem); - } - - return RepeatStatus.CONTINUABLE; - } - }); - - contribution.incrementFilterCount(filterCount.get()); - if(output.size() > 0) { - persist(contribution, output); - } - } - - /** - * Register some {@link StepListener}s with the handler. Each will get the - * callbacks in the order specified at the correct stage. - * - * @param listeners list of listeners to be used within this step - */ - public void setListeners(List listeners) { - for (StepListener listener : listeners) { - registerListener(listener); - } - } - - /** - * Register a listener for callbacks at the appropriate stages in a process. - * - * @param listener a {@link StepListener} - */ - public void registerListener(StepListener listener) { - this.listener.register(listener); - } - - /** - * Responsible for the reading portion of the chunking loop. In this implementation, delegates - * to {@link #doProvide(StepContribution, Chunk)} - * - * @param contribution a {@link StepContribution} - * @param chunk a {@link Chunk} - * @return an item - * @throws Exception thrown if error occurs during the reading portion of the chunking loop. - */ - protected I provide(final StepContribution contribution, final Chunk chunk) throws Exception { - return doProvide(contribution, chunk); - } - - /** - * Implements reading as well as any related listener calls required. - * - * @param contribution a {@link StepContribution} - * @param chunk a {@link Chunk} - * @return an item - * @throws Exception thrown if error occurs during reading or listener calls. - */ - protected final I doProvide(final StepContribution contribution, final Chunk chunk) throws Exception { - try { - listener.beforeRead(); - I item = itemReader.read(); - if(item != null) { - listener.afterRead(item); - } else { - chunk.setEnd(); - } - - return item; - } - catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug(e.getMessage() + " : " + e.getClass().getName()); - } - listener.onReadError(e); - throw e; - } - } - - /** - * Responsible for the processing portion of the chunking loop. In this implementation, delegates to the - * {@link #doTransform(Object)} if a processor is available (returns the item unmodified if it is not) - * - * @param contribution a {@link StepContribution} - * @param item an item - * @return a processed item if a processor is present (the unmodified item if it is not) - * @throws Exception thrown if error occurs during the processing portion of the chunking loop. - */ - protected O transform(final StepContribution contribution, final I item) throws Exception { - if (itemProcessor == null) { - @SuppressWarnings("unchecked") - O result = (O) item; - return result; - } - - return doTransform(item); - } - - /** - * Implements processing and all related listener calls. - * - * @param item the item to be processed - * @return the processed item - * @throws Exception thrown if error occurs during processing. - */ - protected final O doTransform(I item) throws Exception { - try { - listener.beforeProcess(item); - O result = itemProcessor.process(item); - listener.afterProcess(item, result); - return result; - } - catch (Exception e) { - listener.onProcessError(item, e); - throw e; - } - } - - /** - * Responsible for the writing portion of the chunking loop. In this implementation, delegates to the - * {{@link #doPersist(StepContribution, Chunk)}. - * - * @param contribution a {@link StepContribution} - * @param chunk a {@link Chunk} - * @throws Exception thrown if error occurs during the writing portion of the chunking loop. - */ - protected void persist(final StepContribution contribution, final Chunk chunk) throws Exception { - doPersist(contribution, chunk); - - contribution.incrementWriteCount(chunk.getItems().size()); - } - - /** - * Implements writing and all related listener calls - * - * @param contribution a {@link StepContribution} - * @param chunk a {@link Chunk} - * @throws Exception thrown if error occurs during the writing portion of the chunking loop. - */ - protected final void doPersist(final StepContribution contribution, final Chunk chunk) throws Exception { - try { - List items = chunk.getItems(); - listener.beforeWrite(items); - itemWriter.write(items); - listener.afterWrite(items); - } - catch (Exception e) { - listener.onWriteError(e, chunk.getItems()); - throw e; - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrChunkProvider.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrChunkProvider.java deleted file mode 100644 index 2772468d9..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrChunkProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 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.jsr.step.item; - -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.step.item.Chunk; -import org.springframework.batch.core.step.item.ChunkProvider; - -/** - * A no-op {@link ChunkProvider}. The JSR-352 chunking model does not cache the - * input as the regular Spring Batch implementations do so this component is not - * needed within a chunking loop. - * - * @author Michael Minella - * - * @param The type of input for the step - */ -public class JsrChunkProvider implements ChunkProvider { - - /* (non-Javadoc) - * @see org.springframework.batch.core.step.item.ChunkProvider#provide(org.springframework.batch.core.StepContribution) - */ - @Override - public Chunk provide(StepContribution contribution) throws Exception { - return new Chunk<>(); - } - - /* (non-Javadoc) - * @see org.springframework.batch.core.step.item.ChunkProvider#postProcess(org.springframework.batch.core.StepContribution, org.springframework.batch.core.step.item.Chunk) - */ - @Override - public void postProcess(StepContribution contribution, Chunk chunk) { - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrFaultTolerantChunkProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrFaultTolerantChunkProcessor.java deleted file mode 100644 index 951f93c96..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/JsrFaultTolerantChunkProcessor.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.item; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.StepListener; -import org.springframework.batch.core.listener.MulticasterBatchListener; -import org.springframework.batch.core.step.item.BatchRetryTemplate; -import org.springframework.batch.core.step.item.Chunk; -import org.springframework.batch.core.step.item.ChunkMonitor; -import org.springframework.batch.core.step.item.ForceRollbackForWriteSkipException; -import org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy; -import org.springframework.batch.core.step.skip.SkipException; -import org.springframework.batch.core.step.skip.SkipPolicy; -import org.springframework.batch.core.step.skip.SkipPolicyFailedException; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.repeat.RepeatOperations; -import org.springframework.classify.BinaryExceptionClassifier; -import org.springframework.classify.Classifier; -import org.springframework.retry.RecoveryCallback; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryException; -import org.springframework.util.Assert; - -import jakarta.batch.operations.BatchRuntimeException; -import java.util.List; - -/** - * Extension of the {@link JsrChunkProcessor} that adds skip and retry functionality. - * - * @author Michael Minella - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * - * @param input type for the step - * @param output type for the step - */ -public class JsrFaultTolerantChunkProcessor extends JsrChunkProcessor { - protected final Log logger = LogFactory.getLog(getClass()); - private SkipPolicy skipPolicy = new LimitCheckingItemSkipPolicy(); - private Classifier rollbackClassifier = new BinaryExceptionClassifier(true); - private final BatchRetryTemplate batchRetryTemplate; - private ChunkMonitor chunkMonitor = new ChunkMonitor(); - private boolean hasProcessor = false; - - public JsrFaultTolerantChunkProcessor(ItemReader reader, ItemProcessor processor, ItemWriter writer, RepeatOperations repeatTemplate, BatchRetryTemplate batchRetryTemplate) { - super(reader, processor, writer, repeatTemplate); - hasProcessor = processor != null; - this.batchRetryTemplate = batchRetryTemplate; - } - - /** - * @param skipPolicy a {@link SkipPolicy} - */ - public void setSkipPolicy(SkipPolicy skipPolicy) { - Assert.notNull(skipPolicy, "A skip policy is required"); - - this.skipPolicy = skipPolicy; - } - - /** - * @param rollbackClassifier a {@link Classifier} - */ - public void setRollbackClassifier(Classifier rollbackClassifier) { - Assert.notNull(rollbackClassifier, "A rollbackClassifier is required"); - - this.rollbackClassifier = rollbackClassifier; - } - - /** - * @param chunkMonitor a {@link ChunkMonitor} - */ - public void setChunkMonitor(ChunkMonitor chunkMonitor) { - Assert.notNull(chunkMonitor, "A chunkMonitor is required"); - - this.chunkMonitor = chunkMonitor; - } - - /** - * Register some {@link StepListener}s with the handler. Each will get the - * callbacks in the order specified at the correct stage. - * - * @param listeners listeners to be registered - */ - @Override - public void setListeners(List listeners) { - for (StepListener listener : listeners) { - registerListener(listener); - } - } - - /** - * Register a listener for callbacks at the appropriate stages in a process. - * - * @param listener a {@link StepListener} - */ - @Override - public void registerListener(StepListener listener) { - getListener().register(listener); - } - - /** - * Adds retry and skip logic to the reading phase of the chunk loop. - * - * @param contribution a {@link StepContribution} - * @param chunk a {@link Chunk} - * @return I an item - * @throws Exception thrown if error occurs. - */ - @Override - protected I provide(final StepContribution contribution, final Chunk chunk) throws Exception { - RetryCallback retryCallback = new RetryCallback() { - - @Override - public I doWithRetry(RetryContext arg0) throws Exception { - while (true) { - try { - return doProvide(contribution, chunk); - } - catch (Exception e) { - if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) { - - // increment skip count and try again - contribution.incrementReadSkipCount(); - chunk.skip(e); - - getListener().onSkipInRead(e); - - logger.debug("Skipping failed input", e); - } - else { - getListener().onRetryReadException(e); - - if(rollbackClassifier.classify(e)) { - throw e; - } - else { - throw e; - } - } - } - } - } - }; - - RecoveryCallback recoveryCallback = new RecoveryCallback() { - - @Override - public I recover(RetryContext context) throws Exception { - Throwable e = context.getLastThrowable(); - if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) { - contribution.incrementReadSkipCount(); - logger.debug("Skipping after failed process", e); - return null; - } - else { - if (rollbackClassifier.classify(e)) { - // Default is to rollback unless the classifier - // allows us to continue - throw new RetryException("Non-skippable exception in recoverer while reading", e); - } - - throw new BatchRuntimeException(e); - } - } - - }; - - return batchRetryTemplate.execute(retryCallback, recoveryCallback); - } - - /** - * Convenience method for calling process skip policy. - * - * @param policy the skip policy - * @param e the cause of the skip - * @param skipCount the current skip count - */ - private boolean shouldSkip(SkipPolicy policy, Throwable e, long skipCount) { - try { - return policy.shouldSkip(e, skipCount); - } - catch (SkipException ex) { - throw ex; - } - catch (RuntimeException ex) { - throw new SkipPolicyFailedException("Fatal exception in SkipPolicy.", ex, e); - } - } - - /** - * Adds retry and skip logic to the process phase of the chunk loop. - * - * @param contribution a {@link StepContribution} - * @param item an item to be processed - * @return O an item that has been processed if a processor is available - * @throws Exception thrown if error occurs. - */ - @Override - @SuppressWarnings("unchecked") - protected O transform(final StepContribution contribution, final I item) throws Exception { - if (!hasProcessor) { - return (O) item; - } - - RetryCallback retryCallback = new RetryCallback() { - - @Override - public O doWithRetry(RetryContext context) throws Exception { - try { - return doTransform(item); - } - catch (Exception e) { - if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) { - // If we are not re-throwing then we should check if - // this is skippable - contribution.incrementProcessSkipCount(); - logger.debug("Skipping after failed process with no rollback", e); - // If not re-throwing then the listener will not be - // called in next chunk. - getListener().onSkipInProcess(item, e); - } else { - getListener().onRetryProcessException(item, e); - - if (rollbackClassifier.classify(e)) { - // Default is to rollback unless the classifier - // allows us to continue - throw e; - } - else { - throw e; - } - } - } - return null; - } - - }; - - RecoveryCallback recoveryCallback = new RecoveryCallback() { - @Override - public O recover(RetryContext context) throws Exception { - Throwable e = context.getLastThrowable(); - if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) { - contribution.incrementProcessSkipCount(); - logger.debug("Skipping after failed process", e); - return null; - } - else { - if (rollbackClassifier.classify(e)) { - // Default is to rollback unless the classifier - // allows us to continue - throw new RetryException("Non-skippable exception in recoverer while processing", e); - } - - throw new BatchRuntimeException(e); - } - } - }; - - return batchRetryTemplate.execute(retryCallback, recoveryCallback); - } - - /** - * Adds retry and skip logic to the write phase of the chunk loop. - * - * @param contribution a {@link StepContribution} - * @param chunk a {@link Chunk} - * @throws Exception thrown if error occurs. - */ - @Override - protected void persist(final StepContribution contribution, final Chunk chunk) throws Exception { - - RetryCallback retryCallback = new RetryCallback() { - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Object doWithRetry(RetryContext context) throws Exception { - - chunkMonitor.setChunkSize(chunk.size()); - try { - doPersist(contribution, chunk); - } - catch (Exception e) { - if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) { - // Per section 9.2.7 of JSR-352, the SkipListener receives all the items within the chunk - ((MulticasterBatchListener) getListener()).onSkipInWrite(chunk.getItems(), e); - } else { - getListener().onRetryWriteException((List) chunk.getItems(), e); - - if (rollbackClassifier.classify(e)) { - throw e; - } - } - /* - * If the exception is marked as no-rollback, we need to - * override that, otherwise there's no way to write the - * rest of the chunk or to honour the skip listener - * contract. - */ - throw new ForceRollbackForWriteSkipException( - "Force rollback on skippable exception so that skipped item can be located.", e); - } - contribution.incrementWriteCount(chunk.size()); - return null; - - } - }; - - RecoveryCallback recoveryCallback = new RecoveryCallback() { - - @Override - public O recover(RetryContext context) throws Exception { - Throwable e = context.getLastThrowable(); - if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) { - contribution.incrementWriteSkipCount(); - logger.debug("Skipping after failed write", e); - return null; - } - else { - if (rollbackClassifier.classify(e)) { - // Default is to rollback unless the classifier - // allows us to continue - throw new RetryException("Non-skippable exception in recoverer while write", e); - } - return null; - } - } - - }; - - batchRetryTemplate.execute(retryCallback, recoveryCallback); - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/package-info.java deleted file mode 100644 index 90ad4517a..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/item/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * JSR-352 specific components for implementing item based processing including fault tolerance. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.step.item; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/package-info.java deleted file mode 100644 index 0fba98d0c..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/step/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * JSR-352 extensions of existing batch {@link org.springframework.batch.core.Step} types. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.core.jsr.step; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryProcessListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryProcessListener.java deleted file mode 100644 index 86ef3fe22..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryProcessListener.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.listener; - -import java.util.Iterator; -import java.util.List; -import jakarta.batch.api.chunk.listener.RetryProcessListener; - -/** - *

- * Composite class holding {@link RetryProcessListener}'s. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class CompositeRetryProcessListener implements RetryProcessListener { - private OrderedComposite listeners = new OrderedComposite<>(); - - /** - *

- * Public setter for the {@link RetryProcessListener}'s. - *

- * - * @param listeners the {@link RetryProcessListener}'s to set - */ - public void setListeners(List listeners) { - this.listeners.setItems(listeners); - } - - /** - *

- * Register an additional {@link RetryProcessListener}. - *

- * - * @param listener the {@link RetryProcessListener} to register - */ - public void register(RetryProcessListener listener) { - listeners.add(listener); - } - - @Override - public void onRetryProcessException(Object item, Exception ex) throws Exception { - for (Iterator iterator = listeners.reverse(); iterator.hasNext();) { - RetryProcessListener listener = iterator.next(); - listener.onRetryProcessException(item, ex); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryReadListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryReadListener.java deleted file mode 100644 index e50fbbcb6..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryReadListener.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.listener; - -import java.util.Iterator; -import java.util.List; -import jakarta.batch.api.chunk.listener.RetryReadListener; - -/** - *

- * Composite class holding {@link RetryReadListener}'s. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class CompositeRetryReadListener implements RetryReadListener { - private OrderedComposite listeners = new OrderedComposite<>(); - - /** - *

- * Public setter for the {@link RetryReadListener}'s. - *

- * - * @param listeners the {@link RetryReadListener}'s to set - */ - public void setListeners(List listeners) { - this.listeners.setItems(listeners); - } - - /** - *

- * Register an additional {@link RetryReadListener}. - *

- * - * @param listener the {@link RetryReadListener} to register - */ - public void register(RetryReadListener listener) { - listeners.add(listener); - } - - @Override - public void onRetryReadException(Exception ex) throws Exception { - for (Iterator iterator = listeners.reverse(); iterator.hasNext();) { - RetryReadListener listener = iterator.next(); - listener.onRetryReadException(ex); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryWriteListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryWriteListener.java deleted file mode 100644 index 0238abdfd..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeRetryWriteListener.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.listener; - -import java.util.Iterator; -import java.util.List; -import jakarta.batch.api.chunk.listener.RetryWriteListener; - -/** - *

- * Composite class holding {@link RetryWriteListener}'s. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class CompositeRetryWriteListener implements RetryWriteListener { - private OrderedComposite listeners = new OrderedComposite<>(); - - /** - *

- * Public setter for the {@link RetryWriteListener}'s. - *

- * - * @param listeners the {@link RetryWriteListener}'s to set - */ - public void setListeners(List listeners) { - this.listeners.setItems(listeners); - } - - /** - *

- * Register an additional {@link RetryWriteListener}. - *

- * - * @param listener the {@link RetryWriteListener} to register - */ - public void register(RetryWriteListener listener) { - listeners.add(listener); - } - - @Override - public void onRetryWriteException(List items, Exception ex) throws Exception { - for (Iterator iterator = listeners.reverse(); iterator.hasNext();) { - RetryWriteListener listener = iterator.next(); - listener.onRetryWriteException(items, ex); - } - } -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java index 0eee67e41..cc9144069 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java @@ -18,10 +18,6 @@ package org.springframework.batch.core.listener; import java.lang.reflect.InvocationTargetException; import java.util.List; -import jakarta.batch.api.chunk.listener.RetryProcessListener; -import jakarta.batch.api.chunk.listener.RetryReadListener; -import jakarta.batch.api.chunk.listener.RetryWriteListener; -import jakarta.batch.operations.BatchRuntimeException; import org.springframework.batch.core.ChunkListener; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ItemProcessListener; @@ -42,7 +38,7 @@ import org.springframework.lang.Nullable; * @author Mahmoud Ben Hassine */ public class MulticasterBatchListener implements StepExecutionListener, ChunkListener, ItemReadListener, -ItemProcessListener, ItemWriteListener, SkipListener, RetryReadListener, RetryProcessListener, RetryWriteListener { +ItemProcessListener, ItemWriteListener, SkipListener { private CompositeStepExecutionListener stepListener = new CompositeStepExecutionListener(); @@ -56,12 +52,6 @@ ItemProcessListener, ItemWriteListener, SkipListener, RetryReadLi private CompositeSkipListener skipListener = new CompositeSkipListener<>(); - private CompositeRetryReadListener retryReadListener = new CompositeRetryReadListener(); - - private CompositeRetryProcessListener retryProcessListener = new CompositeRetryProcessListener(); - - private CompositeRetryWriteListener retryWriteListener = new CompositeRetryWriteListener(); - /** * Initialize the listener instance. */ @@ -115,15 +105,6 @@ ItemProcessListener, ItemWriteListener, SkipListener, RetryReadLi SkipListener skipListener = (SkipListener) listener; this.skipListener.register(skipListener); } - if(listener instanceof RetryReadListener) { - this.retryReadListener.register((RetryReadListener) listener); - } - if(listener instanceof RetryProcessListener) { - this.retryProcessListener.register((RetryProcessListener) listener); - } - if(listener instanceof RetryWriteListener) { - this.retryWriteListener.register((RetryWriteListener) listener); - } } /** @@ -334,33 +315,6 @@ ItemProcessListener, ItemWriteListener, SkipListener, RetryReadLi } } - @Override - public void onRetryReadException(Exception ex) throws Exception { - try { - retryReadListener.onRetryReadException(ex); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Override - public void onRetryProcessException(Object item, Exception ex) throws Exception { - try { - retryProcessListener.onRetryProcessException(item, ex); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - @Override - public void onRetryWriteException(List items, Exception ex) throws Exception { - try { - retryWriteListener.onRetryWriteException(items, ex); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - /** * Unwrap the target exception from a wrapped {@link InvocationTargetException}. * @param e the exception to introspect diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.java index a65a7a51b..15471953b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.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. @@ -68,18 +68,6 @@ public interface JobRepository { */ JobInstance createJobInstance(String jobName, JobParameters jobParameters); - /** - * Create a new {@link JobExecution} based upon the {@link JobInstance} it's associated - * with, the {@link JobParameters} used to execute it with and the location of the configuration - * file that defines the job. - * - * @param jobInstance {@link JobInstance} instance to initialize the new JobExecution. - * @param jobParameters {@link JobParameters} instance to initialize the new JobExecution. - * @param jobConfigurationLocation {@link String} instance to initialize the new JobExecution. - * @return the new {@link JobExecution}. - */ - JobExecution createJobExecution(JobInstance jobInstance, JobParameters jobParameters, String jobConfigurationLocation); - /** *

* Create a {@link JobExecution} for a given {@link Job} and diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java index 273a5b2f6..9f00db673 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java @@ -297,8 +297,7 @@ public class Jackson2ExecutionContextStringSerializer implements ExecutionContex "java.util.Properties", "[Ljava.util.Properties;", "org.springframework.batch.core.JobParameter", - "org.springframework.batch.core.JobParameters", - "org.springframework.batch.core.jsr.partition.JsrPartitionHandler$PartitionPlanState" + "org.springframework.batch.core.JobParameters" ))); private final Set trustedClassNames = new LinkedHashSet<>(TRUSTED_CLASS_NAMES); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java index 6463ea66c..5cbb17b0d 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java @@ -66,7 +66,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements private static final Log logger = LogFactory.getLog(JdbcJobExecutionDao.class); private static final String SAVE_JOB_EXECUTION = "INSERT into %PREFIX%JOB_EXECUTION(JOB_EXECUTION_ID, JOB_INSTANCE_ID, START_TIME, " - + "END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, VERSION, CREATE_TIME, LAST_UPDATED, JOB_CONFIGURATION_LOCATION) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + "END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, VERSION, CREATE_TIME, LAST_UPDATED) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; private static final String CHECK_JOB_EXECUTION_EXISTS = "SELECT COUNT(*) FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID = ?"; @@ -75,17 +75,17 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements private static final String UPDATE_JOB_EXECUTION = "UPDATE %PREFIX%JOB_EXECUTION set START_TIME = ?, END_TIME = ?, " + " STATUS = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, CREATE_TIME = ?, LAST_UPDATED = ? where JOB_EXECUTION_ID = ? and VERSION = ?"; - private static final String FIND_JOB_EXECUTIONS = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION, JOB_CONFIGURATION_LOCATION" + private static final String FIND_JOB_EXECUTIONS = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION" + " from %PREFIX%JOB_EXECUTION where JOB_INSTANCE_ID = ? order by JOB_EXECUTION_ID desc"; - private static final String GET_LAST_EXECUTION = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION, JOB_CONFIGURATION_LOCATION " + private static final String GET_LAST_EXECUTION = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION " + "from %PREFIX%JOB_EXECUTION E where JOB_INSTANCE_ID = ? and JOB_EXECUTION_ID in (SELECT max(JOB_EXECUTION_ID) from %PREFIX%JOB_EXECUTION E2 where E2.JOB_INSTANCE_ID = ?)"; - private static final String GET_EXECUTION_BY_ID = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION, JOB_CONFIGURATION_LOCATION" + private static final String GET_EXECUTION_BY_ID = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION" + " from %PREFIX%JOB_EXECUTION where JOB_EXECUTION_ID = ?"; private static final String GET_RUNNING_EXECUTIONS = "SELECT E.JOB_EXECUTION_ID, E.START_TIME, E.END_TIME, E.STATUS, E.EXIT_CODE, E.EXIT_MESSAGE, E.CREATE_TIME, E.LAST_UPDATED, E.VERSION, " - + "E.JOB_INSTANCE_ID, E.JOB_CONFIGURATION_LOCATION from %PREFIX%JOB_EXECUTION E, %PREFIX%JOB_INSTANCE I where E.JOB_INSTANCE_ID=I.JOB_INSTANCE_ID and I.JOB_NAME=? and E.START_TIME is not NULL and E.END_TIME is NULL order by E.JOB_EXECUTION_ID desc"; + + "E.JOB_INSTANCE_ID from %PREFIX%JOB_EXECUTION E, %PREFIX%JOB_INSTANCE I where E.JOB_INSTANCE_ID=I.JOB_INSTANCE_ID and I.JOB_NAME=? and E.START_TIME is not NULL and E.END_TIME is NULL order by E.JOB_EXECUTION_ID desc"; private static final String CURRENT_VERSION_JOB_EXECUTION = "SELECT VERSION FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID=?"; @@ -154,13 +154,12 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements Object[] parameters = new Object[] { jobExecution.getId(), jobExecution.getJobId(), jobExecution.getStartTime(), jobExecution.getEndTime(), jobExecution.getStatus().toString(), jobExecution.getExitStatus().getExitCode(), jobExecution.getExitStatus().getExitDescription(), - jobExecution.getVersion(), jobExecution.getCreateTime(), jobExecution.getLastUpdated(), - jobExecution.getJobConfigurationName() }; + jobExecution.getVersion(), jobExecution.getCreateTime(), jobExecution.getLastUpdated() }; getJdbcTemplate().update( getQuery(SAVE_JOB_EXECUTION), parameters, new int[] { Types.BIGINT, Types.BIGINT, Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR }); + Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.TIMESTAMP, Types.TIMESTAMP }); insertJobParameters(jobExecution.getId(), jobExecution.getJobParameters()); } @@ -412,17 +411,16 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements @Override public JobExecution mapRow(ResultSet rs, int rowNum) throws SQLException { Long id = rs.getLong(1); - String jobConfigurationLocation = rs.getString(10); JobExecution jobExecution; if (jobParameters == null) { jobParameters = getJobParameters(id); } if (jobInstance == null) { - jobExecution = new JobExecution(id, jobParameters, jobConfigurationLocation); + jobExecution = new JobExecution(id, jobParameters); } else { - jobExecution = new JobExecution(jobInstance, id, jobParameters, jobConfigurationLocation); + jobExecution = new JobExecution(jobInstance, id, jobParameters); } jobExecution.setStartTime(rs.getTimestamp(2)); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java index c5743ea2c..4c92623b2 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java @@ -149,7 +149,7 @@ public class SimpleJobRepository implements JobRepository { executionContext = new ExecutionContext(); } - JobExecution jobExecution = new JobExecution(jobInstance, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, jobParameters); jobExecution.setExecutionContext(executionContext); jobExecution.setLastUpdated(new Date(System.currentTimeMillis())); @@ -290,23 +290,4 @@ public class SimpleJobRepository implements JobRepository { return jobInstance; } - @Override - public JobExecution createJobExecution(JobInstance jobInstance, - JobParameters jobParameters, String jobConfigurationLocation) { - - Assert.notNull(jobInstance, "A JobInstance is required to associate the JobExecution with"); - Assert.notNull(jobParameters, "A JobParameters object is required to create a JobExecution"); - - JobExecution jobExecution = new JobExecution(jobInstance, jobParameters, jobConfigurationLocation); - ExecutionContext executionContext = new ExecutionContext(); - jobExecution.setExecutionContext(executionContext); - jobExecution.setLastUpdated(new Date(System.currentTimeMillis())); - - // Save the JobExecution so that it picks up an ID (useful for clients - // monitoring asynchronous executions): - jobExecutionDao.saveJobExecution(jobExecution); - ecDao.saveExecutionContext(jobExecution); - - return jobExecution; - } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java index 1870e9191..ba0892c23 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-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,7 +17,6 @@ package org.springframework.batch.core.scope.context; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; import org.springframework.lang.Nullable; /** @@ -37,7 +36,7 @@ public class JobSynchronizationManager { private static final SynchronizationManagerSupport manager = new SynchronizationManagerSupport() { @Override - protected JobContext createNewContext(JobExecution execution, @Nullable BatchPropertyContext args) { + protected JobContext createNewContext(JobExecution execution) { return new JobContext(execution); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java index 99c35c66d..20ff9fe4d 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -30,7 +30,6 @@ import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.UnexpectedJobExecutionException; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; import org.springframework.batch.core.scope.StepScope; import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.repeat.context.SynchronizedAttributeAccessor; @@ -57,8 +56,6 @@ public class StepContext extends SynchronizedAttributeAccessor { private Map> callbacks = new HashMap<>(); - private BatchPropertyContext propertyContext = null; - /** * Create a new instance of {@link StepContext} for this * {@link StepExecution}. @@ -71,13 +68,6 @@ public class StepContext extends SynchronizedAttributeAccessor { this.stepExecution = stepExecution; } - public StepContext(StepExecution stepExecution, BatchPropertyContext propertyContext) { - super(); - Assert.notNull(stepExecution, "A StepContext must have a non-null StepExecution"); - this.stepExecution = stepExecution; - this.propertyContext = propertyContext; - } - /** * Convenient accessor for current step name identifier. Usually this is the * same as the bean name of the step that is executing (but might not be @@ -158,18 +148,6 @@ public class StepContext extends SynchronizedAttributeAccessor { return Collections.unmodifiableMap(result); } - @SuppressWarnings({"rawtypes", "unchecked"}) - public Map getPartitionPlan() { - Map partitionPlanProperties = new HashMap<>(); - - if(propertyContext != null) { - Map partitionProperties = propertyContext.getStepProperties(getStepName()); - partitionPlanProperties = partitionProperties; - } - - return Collections.unmodifiableMap(partitionPlanProperties); - } - /** * Allow clients to register callbacks for clean up on close. * diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java index 72907c137..88ac3ab47 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -17,7 +17,6 @@ package org.springframework.batch.core.scope.context; import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; import org.springframework.lang.Nullable; /** @@ -38,16 +37,8 @@ public class StepSynchronizationManager { new SynchronizationManagerSupport() { @Override - protected StepContext createNewContext(StepExecution execution, @Nullable BatchPropertyContext propertyContext) { - StepContext context; - - if(propertyContext != null) { - context = new StepContext(execution, propertyContext); - } else { - context = new StepContext(execution); - } - - return context; + protected StepContext createNewContext(StepExecution execution) { + return new StepContext(execution); } @Override @@ -80,21 +71,6 @@ public class StepSynchronizationManager { return manager.register(stepExecution); } - /** - * Register a context with the current thread - always put a matching - * {@link #close()} call in a finally block to ensure that the correct - * context is available in the enclosing block. - * - * @param stepExecution the step context to register - * @param propertyContext an instance of {@link BatchPropertyContext} to be - * used by the StepSynchronizationManager. - * @return a new {@link StepContext} or the current one if it has the same - * {@link StepExecution} - */ - public static StepContext register(StepExecution stepExecution, BatchPropertyContext propertyContext) { - return manager.register(stepExecution, propertyContext); - } - /** * Method for unregistering the current context - should always and only be * used by in conjunction with a matching {@link #register(StepExecution)} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java index ba9e695d8..72c4e7d5a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-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. @@ -20,7 +20,6 @@ import java.util.Stack; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; import org.springframework.lang.Nullable; @@ -97,35 +96,7 @@ public abstract class SynchronizationManagerSupport { synchronized (contexts) { context = contexts.get(execution); if (context == null) { - context = createNewContext(execution, null); - contexts.put(execution, context); - } - } - increment(); - return context; - } - - /** - * Register a context with the current thread - always put a matching {@link #close()} call in a finally block to - * ensure that the correct - * context is available in the enclosing block. - * - * @param execution the execution to register - * @param propertyContext instance of {@link BatchPropertyContext} to be registered with this thread. - * @return a new context or the current one if it has the same - * execution - */ - @Nullable - public C register(@Nullable E execution, @Nullable BatchPropertyContext propertyContext) { - if (execution == null) { - return null; - } - getCurrent().push(execution); - C context; - synchronized (contexts) { - context = contexts.get(execution); - if (context == null) { - context = createNewContext(execution, propertyContext); + context = createNewContext(execution); contexts.put(execution, context); } } @@ -202,6 +173,6 @@ public abstract class SynchronizationManagerSupport { protected abstract void close(C context); - protected abstract C createNewContext(E execution, @Nullable BatchPropertyContext propertyContext); + protected abstract C createNewContext(E execution); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java index f97e69965..53c2f4660 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java @@ -25,8 +25,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import jakarta.batch.operations.BatchRuntimeException; - import org.springframework.batch.core.ChunkListener; import org.springframework.batch.core.JobInterruptedException; import org.springframework.batch.core.SkipListener; @@ -124,8 +122,6 @@ public class FaultTolerantStepBuilder extends SimpleStepBuilder { private Set> skipListeners = new LinkedHashSet<>(); - private Set jsrRetryListeners = new LinkedHashSet<>(); - private int skipLimit = 0; private SkipPolicy skipPolicy; @@ -227,11 +223,6 @@ public class FaultTolerantStepBuilder extends SimpleStepBuilder { return this; } - public FaultTolerantStepBuilder listener(org.springframework.batch.core.jsr.RetryListener listener) { - jsrRetryListeners.add(listener); - return this; - } - @Override public FaultTolerantStepBuilder listener(ChunkListener listener) { super.listener(new TerminateOnExceptionChunkListenerDelegate(listener)); @@ -492,7 +483,7 @@ public class FaultTolerantStepBuilder extends SimpleStepBuilder { addNonRetryableExceptionIfMissing(SkipLimitExceededException.class, NonSkippableReadException.class, TransactionException.class, FatalStepExecutionException.class, SkipListenerFailedException.class, SkipPolicyFailedException.class, RetryException.class, JobInterruptedException.class, Error.class, - BatchRuntimeException.class, BeanCreationException.class); + BeanCreationException.class); } protected void detectStreamInReader() { @@ -647,10 +638,6 @@ public class FaultTolerantStepBuilder extends SimpleStepBuilder { return skipListeners; } - protected Set getJsrRetryListeners() { - return jsrRetryListeners; - } - /** * Wrap the provided {@link org.springframework.retry.RetryPolicy} so that it never retries explicitly non-retryable * exceptions. diff --git a/spring-batch-core/src/main/resources/META-INF/services/jakarta.batch.operations.JobOperator b/spring-batch-core/src/main/resources/META-INF/services/jakarta.batch.operations.JobOperator deleted file mode 100644 index 7bb1f526d..000000000 --- a/spring-batch-core/src/main/resources/META-INF/services/jakarta.batch.operations.JobOperator +++ /dev/null @@ -1 +0,0 @@ -org.springframework.batch.core.jsr.launch.JsrJobOperator \ No newline at end of file diff --git a/spring-batch-core/src/main/resources/META-INF/spring.handlers b/spring-batch-core/src/main/resources/META-INF/spring.handlers index 2663f5208..fbdf08e4f 100644 --- a/spring-batch-core/src/main/resources/META-INF/spring.handlers +++ b/spring-batch-core/src/main/resources/META-INF/spring.handlers @@ -1,2 +1 @@ -http\://www.springframework.org/schema/batch=org.springframework.batch.core.configuration.xml.CoreNamespaceHandler -http\://xmlns.jcp.org/xml/ns/javaee=org.springframework.batch.core.jsr.configuration.xml.JsrNamespaceHandler \ No newline at end of file +http\://www.springframework.org/schema/batch=org.springframework.batch.core.configuration.xml.CoreNamespaceHandler \ No newline at end of file diff --git a/spring-batch-core/src/main/resources/META-INF/spring.schemas b/spring-batch-core/src/main/resources/META-INF/spring.schemas index b01f5fede..5fd42f30e 100644 --- a/spring-batch-core/src/main/resources/META-INF/spring.schemas +++ b/spring-batch-core/src/main/resources/META-INF/spring.schemas @@ -3,12 +3,8 @@ http\://www.springframework.org/schema/batch/spring-batch-3.0.xsd=/org/springfra http\://www.springframework.org/schema/batch/spring-batch-2.2.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.2.xsd http\://www.springframework.org/schema/batch/spring-batch-2.1.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.1.xsd http\://www.springframework.org/schema/batch/spring-batch-2.0.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.0.xsd -http\://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd=/org/springframework/batch/core/jsr/configuration/xml/jobXML_1_0.xsd -http\://xmlns.jcp.org/xml/ns/javaee/batchXML_1_0.xsd=/org/springframework/batch/core/jsr/configuration/xml/batchXML_1_0.xsd https\://www.springframework.org/schema/batch/spring-batch.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-3.0.xsd https\://www.springframework.org/schema/batch/spring-batch-3.0.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-3.0.xsd https\://www.springframework.org/schema/batch/spring-batch-2.2.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.2.xsd https\://www.springframework.org/schema/batch/spring-batch-2.1.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.1.xsd https\://www.springframework.org/schema/batch/spring-batch-2.0.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.0.xsd -https\://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd=/org/springframework/batch/core/jsr/configuration/xml/jobXML_1_0.xsd -https\://xmlns.jcp.org/xml/ns/javaee/batchXML_1_0.xsd=/org/springframework/batch/core/jsr/configuration/xml/batchXML_1_0.xsd diff --git a/spring-batch-core/src/main/resources/beanRefContext.xml b/spring-batch-core/src/main/resources/beanRefContext.xml deleted file mode 100644 index 92a295f11..000000000 --- a/spring-batch-core/src/main/resources/beanRefContext.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/spring-batch-core/src/main/resources/jsrBaseContext.xml b/spring-batch-core/src/main/resources/jsrBaseContext.xml deleted file mode 100644 index cd4e2e10c..000000000 --- a/spring-batch-core/src/main/resources/jsrBaseContext.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - classpath:batch-${ENVIRONMENT:hsql}.properties - - - - - - - diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml/batchXML_1_0.xsd b/spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml/batchXML_1_0.xsd deleted file mode 100644 index fdbd192c1..000000000 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml/batchXML_1_0.xsd +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml/jobXML_1_0.xsd b/spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml/jobXML_1_0.xsd deleted file mode 100755 index a0504bad0..000000000 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml/jobXML_1_0.xsd +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - Job Specification Language (JSL) specifies a job, - its steps, and directs their execution. - JSL also can be referred to as "Job XML". - - - - - - - This is a helper type. Though it is not otherwise - called out by this name - in the specification, it captures the fact - that the xs:string value refers - to a batch artifact, across numerous - other JSL type definitions. - - - - - - - - - The type of a job definition, whether concrete or - abstract. This is the type of the root element of any JSL document. - - - - - - - The job-level properties, which are accessible - via the JobContext.getProperties() API in a batch artifact. - - - - - - - Note that "listeners" sequence order in XML does - not imply order of execution by - the batch runtime, per the - specification. - - - - - - - - - - - - - - - - - - - The definition of an job, whether concrete or - abstract. This is the - type of the root element of any JSL document. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This grouping provides allows for the reuse of the - 'end', 'fail', 'next', 'stop' element sequences which - may appear at the end of a 'step', 'flow', 'split' or 'decision'. - The term 'TransitionElements' does not formally appear in the spec, it is - a schema convenience. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note that "listeners" sequence order in XML does - not imply order of execution by - the batch runtime, per the - specification. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Specifies the checkpoint policy that governs - commit behavior for this chunk. - Valid values are: "item" or - "custom". The "item" policy means the - chunk is checkpointed after a - specified number of items are - processed. The "custom" policy means - the chunk is checkpointed - according to a checkpoint algorithm - implementation. Specifying - "custom" requires that the - checkpoint-algorithm element is also - specified. It is an optional - attribute. The default policy is - "item". However, we chose not to define - a schema-specified default for this attribute. - - - - - - - Specifies the number of items to process per chunk - when using the item - checkpoint policy. It must be valid XML integer. - It is an optional - attribute. The default is 10. The item-count - attribute is ignored - for "custom" checkpoint policy. However, to - make it easier for implementations to support JSL inheritance - we - abstain from defining a schema-specified default for this - attribute. - - - - - - - Specifies the amount of time in seconds before - taking a checkpoint for the - item checkpoint policy. It must be valid - XML integer. It is an - optional attribute. The default is 0, which - means no limit. However, to - make it easier for implementations to - support JSL inheritance - we abstain from defining a schema-specified - default for this attribute. - When a value greater than zero is - specified, a checkpoint is taken when - time-limit is reached or - item-count items have been processed, - whichever comes first. The - time-limit attribute is ignored for - "custom" checkpoint policy. - - - - - - - Specifies the number of exceptions a step will - skip if any configured - skippable exceptions are thrown by chunk - processing. It must be a - valid XML integer value. It is an optional - attribute. The default - is no limit. - - - - - - - Specifies the number of times a step will retry if - any configured retryable - exceptions are thrown by chunk processing. - It must be a valid XML - integer value. It is an optional attribute. - The default is no - limit. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-db2.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-db2.sql index e37118ad9..ac4e0b6e2 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-db2.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-db2.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-derby.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-derby.sql index 09a8e53ef..2f70cd6e0 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-derby.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-derby.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) DEFAULT NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-h2.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-h2.sql index fb19c6554..af047d873 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-h2.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-h2.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hsqldb.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hsqldb.sql index 4de04851f..297fd0845 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hsqldb.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-hsqldb.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-mysql.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-mysql.sql index 1a5d87b65..a6b805ecc 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-mysql.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-mysql.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED DATETIME(6), - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ENGINE=InnoDB; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-oracle10g.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-oracle10g.sql index 0d6e18729..2e8c6dbe7 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-oracle10g.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-oracle10g.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR2(2500 char) , EXIT_MESSAGE VARCHAR2(2500 char) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500 char) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) SEGMENT CREATION IMMEDIATE; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-postgresql.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-postgresql.sql index fe3299a07..acfaefca7 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-postgresql.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-postgresql.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlite.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlite.sql index 5df5e404a..0ca50c5d3 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlite.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlite.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(100) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500), constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlserver.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlserver.sql index f1cf0d994..1b7c2c2bb 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlserver.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlserver.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) NULL, EXIT_MESSAGE VARCHAR(2500) NULL, LAST_UPDATED DATETIME NULL, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sybase.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sybase.sql index aeea56c27..073ef1358 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sybase.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sybase.sql @@ -19,7 +19,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(2500) NULL, EXIT_MESSAGE VARCHAR(2500) NULL, LAST_UPDATED DATETIME, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/BatchStatusTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/BatchStatusTests.java index ec0b2c2b4..43c0dfd05 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/BatchStatusTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/BatchStatusTests.java @@ -120,14 +120,4 @@ public class BatchStatusTests { assertEquals(BatchStatus.COMPLETED, status); } - @Test - public void testJsrConversion() { - assertEquals(jakarta.batch.runtime.BatchStatus.ABANDONED, BatchStatus.ABANDONED.getBatchStatus()); - assertEquals(jakarta.batch.runtime.BatchStatus.COMPLETED, BatchStatus.COMPLETED.getBatchStatus()); - assertEquals(jakarta.batch.runtime.BatchStatus.STARTED, BatchStatus.STARTED.getBatchStatus()); - assertEquals(jakarta.batch.runtime.BatchStatus.STARTING, BatchStatus.STARTING.getBatchStatus()); - assertEquals(jakarta.batch.runtime.BatchStatus.STOPPED, BatchStatus.STOPPED.getBatchStatus()); - assertEquals(jakarta.batch.runtime.BatchStatus.STOPPING, BatchStatus.STOPPING.getBatchStatus()); - assertEquals(jakarta.batch.runtime.BatchStatus.FAILED, BatchStatus.FAILED.getBatchStatus()); - } } 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 d58f21210..927a85710 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 @@ -31,12 +31,13 @@ import org.springframework.util.SerializationUtils; /** * @author Dave Syer * @author Dimitrios Liapis + * @author Mahmoud Ben Hassine * */ public class JobExecutionTests { private JobExecution execution = new JobExecution(new JobInstance(11L, "foo"), - 12L, new JobParameters(), null); + 12L, new JobParameters()); @Test public void testJobExecution() { @@ -54,12 +55,6 @@ public class JobExecutionTests { assertEquals(100L, execution.getEndTime().getTime()); } - @Test - public void testGetJobConfigurationName() { - execution = new JobExecution(new JobInstance(null, "foo"), null, "/META-INF/batch-jobs/someJob.xml"); - assertEquals("/META-INF/batch-jobs/someJob.xml", execution.getJobConfigurationName()); - } - /** * Test method for * {@link org.springframework.batch.core.JobExecution#getEndTime()}. @@ -122,7 +117,7 @@ public class JobExecutionTests { @Test public void testGetJobId() { assertEquals(11, execution.getJobId().longValue()); - execution = new JobExecution(new JobInstance(23L, "testJob"), null, new JobParameters(), null); + execution = new JobExecution(new JobInstance(23L, "testJob"), null, new JobParameters()); assertEquals(23, execution.getJobId().longValue()); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java index 1416e8731..902aebee5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java @@ -252,7 +252,7 @@ public class JobParametersBuilderTests { } private JobExecution getJobExecution(JobInstance jobInstance, BatchStatus batchStatus) { - JobExecution jobExecution = new JobExecution(jobInstance, 1L, null, "TestConfig"); + JobExecution jobExecution = new JobExecution(jobInstance, 1L, null); if(batchStatus != null) { jobExecution.setStatus(batchStatus); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java index 51e0bac4d..97626b2e3 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java @@ -34,6 +34,7 @@ import org.springframework.util.SerializationUtils; /** * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public class StepExecutionTests { @@ -305,7 +306,7 @@ public class StepExecutionTests { private StepExecution newStepExecution(Step step, Long jobExecutionId, long stepExecutionId) { JobInstance job = new JobInstance(3L, "testJob"); - StepExecution execution = new StepExecution(step.getName(), new JobExecution(job, jobExecutionId, new JobParameters(), null), stepExecutionId); + StepExecution execution = new StepExecution(step.getName(), new JobExecution(job, jobExecutionId, new JobParameters()), stepExecutionId); return execution; } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DummyJobRepository.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DummyJobRepository.java index fd2ebb050..1883b9222 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DummyJobRepository.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DummyJobRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -31,6 +31,7 @@ import org.springframework.lang.Nullable; /** * @author Dan Garrette * @author David Turanski + * @author Mahmoud Ben Hassine * @since 2.0.1 */ public class DummyJobRepository implements JobRepository, BeanNameAware { @@ -104,9 +105,4 @@ public class DummyJobRepository implements JobRepository, BeanNameAware { return null; } - @Override - public JobExecution createJobExecution(JobInstance jobInstance, - JobParameters jobParameters, String jobConfigurationLocation) { - return null; - } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java index 290243acc..fcdb50afd 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -59,7 +59,7 @@ public class SimpleJobExplorerTests { private ExecutionContextDao ecDao; - private JobExecution jobExecution = new JobExecution(jobInstance, 1234L, new JobParameters(), null); + private JobExecution jobExecution = new JobExecution(jobInstance, 1234L, new JobParameters()); @Before public void setUp() throws Exception { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java index 466d7e130..0b36f4083 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java @@ -35,10 +35,6 @@ import org.springframework.batch.core.job.flow.support.state.EndState; import org.springframework.batch.core.job.flow.support.state.FlowState; import org.springframework.batch.core.job.flow.support.state.SplitState; import org.springframework.batch.core.job.flow.support.state.StepState; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.partition.JsrPartitionHandler; -import org.springframework.batch.core.jsr.step.PartitionStep; -import org.springframework.batch.core.jsr.partition.JsrStepExecutionSplitter; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; import org.springframework.batch.core.step.StepSupport; @@ -571,38 +567,6 @@ public class FlowJobTests { assertEquals("step2", step.getName()); } - @Test - public void testGetPartitionedStep() throws Exception { - SimpleFlow flow = new SimpleFlow("job"); - List transitions = new ArrayList<>(); - PartitionStep step = new PartitionStep(); - step.setName("step1"); - JsrPartitionHandler partitionHandler = new JsrPartitionHandler(); - partitionHandler.setPropertyContext(new BatchPropertyContext()); - partitionHandler.setPartitions(3); - partitionHandler.setJobRepository(jobRepository); - partitionHandler.setStep(new StubStep("subStep")); - partitionHandler.afterPropertiesSet(); - step.setPartitionHandler(partitionHandler); - step.setStepExecutionSplitter(new JsrStepExecutionSplitter(jobRepository, false, "step1", true)); - step.setJobRepository(jobRepository); - step.afterPropertiesSet(); - transitions.add(StateTransition.createStateTransition(new StepState("job.step", step), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - - job.execute(jobRepository.createJobExecution("partitionJob", new JobParameters())); - - assertEquals(3, step.getStepNames().size()); - Step subStep = job.getStep("step1:partition0"); - assertNotNull(subStep); - assertEquals("subStep", subStep.getName()); - assertNull(job.getStep("step that does not exist")); - } - @Test public void testGetStepExistsWithPrefix() throws Exception { SimpleFlow flow = new SimpleFlow("job"); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/AbstractJsrTestCase.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/AbstractJsrTestCase.java deleted file mode 100644 index ae13eba0d..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/AbstractJsrTestCase.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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. - * 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.jsr; - -import java.util.Date; -import java.util.Properties; -import java.util.concurrent.TimeoutException; - -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.Metric; -import jakarta.batch.runtime.StepExecution; - -/** - * @author mminella - * @author Mahmoud Ben Hassine - */ -public abstract class AbstractJsrTestCase { - - protected static JobOperator operator; - - static { - operator = BatchRuntime.getJobOperator(); - } - - /** - * Executes a job and waits for it's status to be any of {@link jakarta.batch.runtime.BatchStatus#STOPPED}, - * {@link jakarta.batch.runtime.BatchStatus#COMPLETED}, or {@link jakarta.batch.runtime.BatchStatus#FAILED}. If the job does not - * reach one of those statuses within the given timeout, a {@link java.util.concurrent.TimeoutException} is - * thrown. - * - * @param jobName Name of the job to run - * @param properties Properties to pass the job - * @param timeout length of time to wait for a job to finish - * @return the {@link jakarta.batch.runtime.JobExecution} for the final state of the job - * @throws java.util.concurrent.TimeoutException if the timeout occurs - */ - public static JobExecution runJob(String jobName, Properties properties, long timeout) throws TimeoutException { - System.out.println("Operator = " + operator); - long executionId = operator.start(jobName, properties); - JobExecution execution = operator.getJobExecution(executionId); - - Date curDate = new Date(); - BatchStatus curBatchStatus = execution.getBatchStatus(); - - while(true) { - if(curBatchStatus == BatchStatus.STOPPED || curBatchStatus == BatchStatus.COMPLETED || curBatchStatus == BatchStatus.FAILED) { - break; - } - - if(new Date().getTime() - curDate.getTime() > timeout) { - throw new TimeoutException("Job processing did not complete in time"); - } - - execution = operator.getJobExecution(executionId); - curBatchStatus = execution.getBatchStatus(); - } - return execution; - } - - /** - * Restarts a job and waits for it's status to be any of {@link BatchStatus#STOPPED}, - * {@link BatchStatus#COMPLETED}, or {@link BatchStatus#FAILED}. If the job does not - * reach one of those statuses within the given timeout, a {@link java.util.concurrent.TimeoutException} is - * thrown. - * - * @param executionId The execution id to restart - * @param properties The Properties to pass to the new run - * @param timeout The length of time to wait for the job to run - * @return the {@link JobExecution} for the final state of the job - * @throws java.util.concurrent.TimeoutException if the timeout occurs - */ - public static JobExecution restartJob(long executionId, Properties properties, long timeout) throws TimeoutException { - long restartId = operator.restart(executionId, properties); - JobExecution execution = operator.getJobExecution(restartId); - - Date curDate = new Date(); - BatchStatus curBatchStatus = execution.getBatchStatus(); - - while(true) { - if(curBatchStatus == BatchStatus.STOPPED || curBatchStatus == BatchStatus.COMPLETED || curBatchStatus == BatchStatus.FAILED) { - break; - } - - if(new Date().getTime() - curDate.getTime() > timeout) { - throw new TimeoutException("Job processing did not complete in time"); - } - - execution = operator.getJobExecution(restartId); - curBatchStatus = execution.getBatchStatus(); - } - return execution; - } - - public static Metric getMetric(StepExecution stepExecution, Metric.MetricType type) { - Metric[] metrics = stepExecution.getMetrics(); - - for (Metric metric : metrics) { - if(metric.getType() == type) { - return metric; - } - } - - return null; - } - - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ChunkListenerAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ChunkListenerAdapterTests.java deleted file mode 100644 index 40e73ad2c..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ChunkListenerAdapterTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import jakarta.batch.api.chunk.listener.ChunkListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.batch.core.step.tasklet.UncheckedTransactionException; - -public class ChunkListenerAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private ChunkListenerAdapter adapter; - @Mock - private ChunkListener delegate; - @Mock - private ChunkContext context; - - @Before - public void setUp() { - adapter = new ChunkListenerAdapter(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testNullDelegate() { - adapter = new ChunkListenerAdapter(null); - } - - @Test - public void testBeforeChunk() throws Exception { - adapter.beforeChunk(null); - - verify(delegate).beforeChunk(); - } - - @Test(expected=UncheckedTransactionException.class) - public void testBeforeChunkException() throws Exception { - doThrow(new Exception("This is expected")).when(delegate).beforeChunk(); - adapter.beforeChunk(null); - } - - @Test - public void testAfterChunk() throws Exception { - adapter.afterChunk(null); - - verify(delegate).afterChunk(); - } - - @Test(expected=UncheckedTransactionException.class) - public void testAfterChunkException() throws Exception { - doThrow(new Exception("This is expected")).when(delegate).afterChunk(); - adapter.afterChunk(null); - } - - @Test(expected=BatchRuntimeException.class) - public void testAfterChunkErrorNullContext() throws Exception { - adapter.afterChunkError(null); - } - - @Test(expected=UncheckedTransactionException.class) - public void testAfterChunkErrorException() throws Exception { - doThrow(new Exception("This is expected")).when(delegate).afterChunk(); - adapter.afterChunk(null); - } - - @Test - public void testAfterChunkError() throws Exception { - Exception exception = new Exception("This was expected"); - - when(context.getAttribute(org.springframework.batch.core.ChunkListener.ROLLBACK_EXCEPTION_KEY)).thenReturn(exception); - - adapter.afterChunkError(context); - - verify(delegate).onError(exception); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemProcessListenerAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemProcessListenerAdapterTests.java deleted file mode 100644 index f8518894d..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemProcessListenerAdapterTests.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; - -import jakarta.batch.api.chunk.listener.ItemProcessListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -public class ItemProcessListenerAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private ItemProcessListenerAdapter adapter; - @Mock - private ItemProcessListener delegate; - - @Before - public void setUp() throws Exception { - adapter = new ItemProcessListenerAdapter<>(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testNullCreation() { - adapter = new ItemProcessListenerAdapter<>(null); - } - - @Test - public void testBeforeProcess() throws Exception { - String item = "This is my item"; - - adapter.beforeProcess(item); - - verify(delegate).beforeProcess(item); - } - - @Test(expected=BatchRuntimeException.class) - public void testBeforeProcessException() throws Exception { - Exception exception = new Exception("This should occur"); - String item = "This is the bad item"; - - doThrow(exception).when(delegate).beforeProcess(item); - - adapter.beforeProcess(item); - } - - @Test - public void testAfterProcess() throws Exception { - String item = "This is the input"; - String result = "This is the output"; - - adapter.afterProcess(item, result); - - verify(delegate).afterProcess(item, result); - } - - @Test(expected=BatchRuntimeException.class) - public void testAfterProcessException() throws Exception { - String item = "This is the input"; - String result = "This is the output"; - Exception exception = new Exception("This is expected"); - - doThrow(exception).when(delegate).afterProcess(item, result); - - adapter.afterProcess(item, result); - } - - @Test - public void testOnProcessError() throws Exception { - String item = "This is the input"; - Exception cause = new Exception("This was the cause"); - - adapter.onProcessError(item, cause); - - verify(delegate).onProcessError(item, cause); - } - - @Test(expected=BatchRuntimeException.class) - public void testOnProcessErrorException() throws Exception { - String item = "This is the input"; - Exception cause = new Exception("This was the cause"); - Exception exception = new Exception("This is expected"); - - doThrow(exception).when(delegate).onProcessError(item, cause); - - adapter.onProcessError(item, cause); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemReadListenerAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemReadListenerAdapterTests.java deleted file mode 100644 index d8073a723..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemReadListenerAdapterTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; - -import jakarta.batch.api.chunk.listener.ItemReadListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -public class ItemReadListenerAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private ItemReadListenerAdapter adapter; - @Mock - private ItemReadListener delegate; - - @Before - public void setUp() throws Exception { - adapter = new ItemReadListenerAdapter<>(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testNullDelegate() { - adapter = new ItemReadListenerAdapter<>(null); - } - - @Test - public void testBeforeRead() throws Exception { - adapter.beforeRead(); - - verify(delegate).beforeRead(); - } - - @Test(expected=BatchRuntimeException.class) - public void testBeforeReadException() throws Exception { - doThrow(new Exception("Should occur")).when(delegate).beforeRead(); - - adapter.beforeRead(); - } - - @Test - public void testAfterRead() throws Exception { - String item = "item"; - - adapter.afterRead(item); - - verify(delegate).afterRead(item); - } - - @Test(expected=BatchRuntimeException.class) - public void testAfterReadException() throws Exception { - String item = "item"; - Exception expected = new Exception("expected"); - - doThrow(expected).when(delegate).afterRead(item); - - adapter.afterRead(item); - } - - @Test - public void testOnReadError() throws Exception { - Exception cause = new Exception ("cause"); - - adapter.onReadError(cause); - - verify(delegate).onReadError(cause); - } - - @Test(expected=BatchRuntimeException.class) - public void testOnReadErrorException() throws Exception { - Exception cause = new Exception ("cause"); - Exception result = new Exception("result"); - - doThrow(result).when(delegate).onReadError(cause); - - adapter.onReadError(cause); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemWriteListenerAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemWriteListenerAdapterTests.java deleted file mode 100644 index 0fdbf662d..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/ItemWriteListenerAdapterTests.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; - -import java.util.ArrayList; -import java.util.List; - -import jakarta.batch.api.chunk.listener.ItemWriteListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -@SuppressWarnings({"rawtypes", "unchecked"}) -public class ItemWriteListenerAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private ItemWriteListenerAdapter adapter; - @Mock - private ItemWriteListener delegate; - private List items = new ArrayList(); - - @Before - public void setUp() throws Exception { - adapter = new ItemWriteListenerAdapter<>(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new ItemWriteListenerAdapter<>(null); - } - - @Test - public void testBeforeWrite() throws Exception { - adapter.beforeWrite(items); - - verify(delegate).beforeWrite(items); - } - - @Test(expected=BatchRuntimeException.class) - public void testBeforeTestWriteException() throws Exception { - doThrow(new Exception("expected")).when(delegate).beforeWrite(items); - - adapter.beforeWrite(items); - } - - @Test - public void testAfterWrite() throws Exception { - adapter.afterWrite(items); - - verify(delegate).afterWrite(items); - } - - @Test(expected=BatchRuntimeException.class) - public void testAfterTestWriteException() throws Exception { - doThrow(new Exception("expected")).when(delegate).afterWrite(items); - - adapter.afterWrite(items); - } - - @Test - public void testOnWriteError() throws Exception { - Exception cause = new Exception("cause"); - - adapter.onWriteError(cause, items); - - verify(delegate).onWriteError(items, cause); - } - - @Test(expected=BatchRuntimeException.class) - public void testOnWriteErrorException() throws Exception { - Exception cause = new Exception("cause"); - - doThrow(new Exception("expected")).when(delegate).onWriteError(items, cause); - - adapter.onWriteError(cause, items); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JobListenerAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JobListenerAdapterTests.java deleted file mode 100644 index c90b8da4e..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JobListenerAdapterTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; - -import jakarta.batch.api.listener.JobListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -public class JobListenerAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private JobListenerAdapter adapter; - @Mock - private JobListener delegate; - - @Before - public void setUp() throws Exception { - adapter = new JobListenerAdapter(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new JobListenerAdapter(null); - } - - @Test - public void testBeforeJob() throws Exception { - adapter.beforeJob(null); - - verify(delegate).beforeJob(); - } - - @Test(expected=BatchRuntimeException.class) - public void testBeforeJobException() throws Exception { - doThrow(new Exception("expected")).when(delegate).beforeJob(); - - adapter.beforeJob(null); - } - - @Test - public void testAfterJob() throws Exception { - adapter.afterJob(null); - - verify(delegate).afterJob(); - } - - @Test(expected=BatchRuntimeException.class) - public void testAfterJobException() throws Exception { - doThrow(new Exception("expected")).when(delegate).afterJob(); - - adapter.afterJob(null); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobContextFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobContextFactoryBeanTests.java deleted file mode 100644 index 269b993ec..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobContextFactoryBeanTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; - -import jakarta.batch.runtime.context.JobContext; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.beans.factory.FactoryBeanNotInitializedException; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; - -public class JsrJobContextFactoryBeanTests { - - private JsrJobContextFactoryBean factoryBean; - private BatchPropertyContext propertyContext; - - @Before - public void setUp() throws Exception { - StepSynchronizationManager.close(); - propertyContext = new BatchPropertyContext(); - factoryBean = new JsrJobContextFactoryBean(); - } - - @After - public void tearDown() throws Exception { - factoryBean.close(); - StepSynchronizationManager.close(); - } - - @Test - public void testInitialCreationSingleThread() throws Exception { - factoryBean.setJobExecution(new JobExecution(5L)); - factoryBean.setBatchPropertyContext(propertyContext); - - assertTrue(factoryBean.getObjectType().isAssignableFrom(JobContext.class)); - assertFalse(factoryBean.isSingleton()); - - JobContext jobContext1 = factoryBean.getObject(); - JobContext jobContext2 = factoryBean.getObject(); - - assertEquals(5L, jobContext1.getExecutionId()); - assertEquals(5L, jobContext2.getExecutionId()); - assertTrue(jobContext1 == jobContext2); - } - - @Test - public void testInitialCreationSingleThreadUsingStepScope() throws Exception { - factoryBean.setBatchPropertyContext(propertyContext); - - StepSynchronizationManager.register(new StepExecution("step1", new JobExecution(5L))); - - JobContext jobContext = factoryBean.getObject(); - - assertEquals(5L, jobContext.getExecutionId()); - StepSynchronizationManager.close(); - } - - @Test(expected=FactoryBeanNotInitializedException.class) - public void testNoJobExecutionProvided() throws Exception { - factoryBean.getObject(); - } - - @Test - public void testOneJobContextPerThread() throws Exception { - List> jobContexts = new ArrayList<>(); - - AsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(); - - for(int i = 0; i < 4; i++) { - final long count = i; - jobContexts.add(executor.submit(new Callable() { - - @Override - public JobContext call() throws Exception { - try { - StepSynchronizationManager.register(new StepExecution("step" + count, new JobExecution(count))); - JobContext context = factoryBean.getObject(); - Thread.sleep(1000L); - return context; - } catch (Throwable ignore) { - return null; - }finally { - StepSynchronizationManager.release(); - } - } - })); - } - - Set contexts = new HashSet<>(); - for (Future future : jobContexts) { - contexts.add(future.get()); - } - - assertEquals(4, contexts.size()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobContextTests.java deleted file mode 100644 index 5f525abae..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobContextTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Properties; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; - -public class JsrJobContextTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private JsrJobContext context; - @Mock - private JobExecution execution; - @Mock - private JobInstance instance; - - @Before - public void setUp() throws Exception { - - Properties properties = new Properties(); - properties.put("jobLevelProperty1", "jobLevelValue1"); - - context = new JsrJobContext(); - context.setProperties(properties); - context.setJobExecution(execution); - - when(execution.getJobInstance()).thenReturn(instance); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - context = new JsrJobContext(); - context.setJobExecution(null); - } - - @Test - public void testGetJobName() { - when(instance.getJobName()).thenReturn("jobName"); - - assertEquals("jobName", context.getJobName()); - } - - @Test - public void testTransientUserData() { - context.setTransientUserData("This is my data"); - assertEquals("This is my data", context.getTransientUserData()); - } - - @Test - public void testGetInstanceId() { - when(instance.getId()).thenReturn(5L); - - assertEquals(5L, context.getInstanceId()); - } - - @Test - public void testGetExecutionId() { - when(execution.getId()).thenReturn(5L); - - assertEquals(5L, context.getExecutionId()); - } - - @Test - public void testJobParameters() { - JobParameters params = new JobParametersBuilder() - .addString("key1", "value1") - .toJobParameters(); - - when(execution.getJobParameters()).thenReturn(params); - - assertEquals("value1", execution.getJobParameters().getString("key1")); - } - - @Test - public void testJobProperties() { - assertEquals("jobLevelValue1", context.getProperties().get("jobLevelProperty1")); - } - - @Test - public void testGetBatchStatus() { - when(execution.getStatus()).thenReturn(BatchStatus.COMPLETED); - - assertEquals(jakarta.batch.runtime.BatchStatus.COMPLETED, context.getBatchStatus()); - } - - @Test - public void testExitStatus() { - context.setExitStatus("my exit status"); - verify(execution).setExitStatus(new ExitStatus("my exit status")); - - when(execution.getExitStatus()).thenReturn(new ExitStatus("exit")); - assertEquals("exit", context.getExitStatus()); - } - - @Test - public void testInitialNullExitStatus() { - when(execution.getExitStatus()).thenReturn(new ExitStatus("exit")); - assertEquals(null, context.getExitStatus()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobExecutionTests.java deleted file mode 100644 index 8f9f81941..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobExecutionTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - * 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.jsr; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import java.util.Date; -import java.util.Properties; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.converter.JobParametersConverterSupport; - -public class JsrJobExecutionTests { - - private JsrJobExecution adapter; - - @Before - public void setUp() throws Exception { - JobInstance instance = new JobInstance(2L, "job name"); - - JobParameters params = new JobParametersBuilder().addString("key1", "value1").toJobParameters(); - - org.springframework.batch.core.JobExecution execution = new org.springframework.batch.core.JobExecution(instance, params); - - execution.setId(5L); - execution.setCreateTime(new Date(0)); - execution.setEndTime(new Date(999999999L)); - execution.setExitStatus(new ExitStatus("exit status")); - execution.setLastUpdated(new Date(12345)); - execution.setStartTime(new Date(98765)); - execution.setStatus(BatchStatus.FAILED); - execution.setVersion(21); - - adapter = new JsrJobExecution(execution, new JobParametersConverterSupport()); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new JsrJobExecution(null, new JobParametersConverterSupport()); - } - - @Test - public void testGetBasicValues() { - assertEquals(jakarta.batch.runtime.BatchStatus.FAILED, adapter.getBatchStatus()); - assertEquals(new Date(0), adapter.getCreateTime()); - assertEquals(new Date(999999999L), adapter.getEndTime()); - assertEquals(5L, adapter.getExecutionId()); - assertEquals("exit status", adapter.getExitStatus()); - assertEquals("job name", adapter.getJobName()); - assertEquals(new Date(12345), adapter.getLastUpdatedTime()); - assertEquals(new Date(98765), adapter.getStartTime()); - - Properties props = adapter.getJobParameters(); - - assertEquals("value1", props.get("key1")); - assertNull(props.get(JsrJobParametersConverter.JOB_RUN_ID)); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobParametersConverterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobParametersConverterTests.java deleted file mode 100644 index 0961106f8..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrJobParametersConverterTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; - -import javax.sql.DataSource; - -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.PooledEmbeddedDataSource; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; - -public class JsrJobParametersConverterTests { - - private JsrJobParametersConverter converter; - private static DataSource dataSource; - - @BeforeClass - public static void setupDatabase() { - dataSource = new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder(). - addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql"). - addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql"). - build()); - } - - @Before - public void setUp() throws Exception { - converter = new JsrJobParametersConverter(dataSource); - converter.afterPropertiesSet(); - } - - @Test - public void testNullJobParameters() { - Properties props = converter.getProperties((JobParameters) null); - assertNotNull(props); - Set> properties = props.entrySet(); - assertEquals(1, properties.size()); - assertTrue(props.containsKey(JsrJobParametersConverter.JOB_RUN_ID)); - } - - @Test - public void testStringJobParameters() { - JobParameters parameters = new JobParametersBuilder().addString("key", "value", false).toJobParameters(); - Properties props = converter.getProperties(parameters); - assertNotNull(props); - Set> properties = props.entrySet(); - assertEquals(2, properties.size()); - assertTrue(props.containsKey(JsrJobParametersConverter.JOB_RUN_ID)); - assertEquals("value", props.getProperty("key")); - } - - @Test - public void testNonStringJobParameters() { - JobParameters parameters = new JobParametersBuilder().addLong("key", 5L, false).toJobParameters(); - Properties props = converter.getProperties(parameters); - assertNotNull(props); - Set> properties = props.entrySet(); - assertEquals(2, properties.size()); - assertTrue(props.containsKey(JsrJobParametersConverter.JOB_RUN_ID)); - assertEquals("5", props.getProperty("key")); - } - - @Test - public void testJobParametersWithRunId() { - JobParameters parameters = new JobParametersBuilder().addLong("key", 5L, false).addLong(JsrJobParametersConverter.JOB_RUN_ID, 2L).toJobParameters(); - Properties props = converter.getProperties(parameters); - assertNotNull(props); - Set> properties = props.entrySet(); - assertEquals(2, properties.size()); - assertEquals("2", props.getProperty(JsrJobParametersConverter.JOB_RUN_ID)); - assertEquals("5", props.getProperty("key")); - } - - @Test - public void testNullProperties() { - JobParameters parameters = converter.getJobParameters((Properties)null); - assertNotNull(parameters); - assertEquals(1, parameters.getParameters().size()); - assertTrue(parameters.getParameters().containsKey(JsrJobParametersConverter.JOB_RUN_ID)); - } - - @Test - public void testProperties() { - Properties properties = new Properties(); - properties.put("key", "value"); - JobParameters parameters = converter.getJobParameters(properties); - assertEquals(2, parameters.getParameters().size()); - assertEquals("value", parameters.getString("key")); - assertTrue(parameters.getParameters().containsKey(JsrJobParametersConverter.JOB_RUN_ID)); - } - - @Test - public void testPropertiesWithRunId() { - Properties properties = new Properties(); - properties.put("key", "value"); - properties.put(JsrJobParametersConverter.JOB_RUN_ID, "3"); - JobParameters parameters = converter.getJobParameters(properties); - assertEquals(2, parameters.getParameters().size()); - assertEquals("value", parameters.getString("key")); - assertEquals(Long.valueOf(3L), parameters.getLong(JsrJobParametersConverter.JOB_RUN_ID)); - assertTrue(parameters.getParameters().get(JsrJobParametersConverter.JOB_RUN_ID).isIdentifying()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepContextFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepContextFactoryBeanTests.java deleted file mode 100644 index f8f567179..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepContextFactoryBeanTests.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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. - * 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.jsr; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; - -import jakarta.batch.runtime.context.StepContext; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.beans.factory.FactoryBeanNotInitializedException; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; - -public class JsrStepContextFactoryBeanTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private JsrStepContextFactoryBean factory; - @Mock - private BatchPropertyContext propertyContext; - - /** - * Added to clean up left overs from other tests. - * @throws Exception - */ - @BeforeClass - public static void setUpClass() throws Exception { - StepSynchronizationManager.close(); - } - - @Before - public void setUp() throws Exception { - factory = new JsrStepContextFactoryBean(); - factory.setBatchPropertyContext(propertyContext); - } - - @After - public void tearDown() throws Exception { - StepSynchronizationManager.close(); - } - - @Test(expected=FactoryBeanNotInitializedException.class) - public void testNoStepExecutionRegistered() throws Exception { - factory.getObject(); - } - - @Test - public void getObjectSingleThread() throws Exception { - StepSynchronizationManager.register(new StepExecution("step1", new JobExecution(5L), 3L)); - - StepContext context1 = factory.getObject(); - StepContext context2 = factory.getObject(); - - assertTrue(context1 == context2); - assertEquals(3L, context1.getStepExecutionId()); - - StepSynchronizationManager.close(); - - StepSynchronizationManager.register(new StepExecution("step2", new JobExecution(5L), 2L)); - - StepContext context3 = factory.getObject(); - StepContext context4 = factory.getObject(); - - assertTrue(context3 == context4); - assertTrue(context3 != context2); - assertEquals(2L, context3.getStepExecutionId()); - - StepSynchronizationManager.close(); - } - - @Test - public void getObjectSingleThreadWithProperties() throws Exception { - Properties props = new Properties(); - props.put("key1", "value1"); - - when(propertyContext.getStepProperties("step3")).thenReturn(props); - - StepSynchronizationManager.register(new StepExecution("step3", new JobExecution(5L), 3L)); - - StepContext context1 = factory.getObject(); - StepContext context2 = factory.getObject(); - - assertTrue(context1 == context2); - assertEquals(3L, context1.getStepExecutionId()); - assertEquals("value1", context1.getProperties().get("key1")); - - StepSynchronizationManager.close(); - } - - @Test - public void getObjectMultiThread() throws Exception { - List> stepContexts = new ArrayList<>(); - - AsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(); - - for(int i = 0; i < 4; i++) { - final long count = i; - stepContexts.add(executor.submit(new Callable() { - - @Override - public StepContext call() throws Exception { - try { - StepSynchronizationManager.register(new StepExecution("step" + count, new JobExecution(count))); - StepContext context = factory.getObject(); - Thread.sleep(1000L); - return context; - } catch (Throwable ignore) { - return null; - }finally { - StepSynchronizationManager.close(); - } - } - })); - } - - Set contexts = new HashSet<>(); - for (Future future : stepContexts) { - contexts.add(future.get()); - } - - assertEquals(4, contexts.size()); - } - - @Test - public void getObjectMultiThreadWithProperties() throws Exception { - for(int i = 0; i < 4; i++) { - Properties props = new Properties(); - props.put("step" + i, "step" + i + "value"); - - when(propertyContext.getStepProperties("step" + i)).thenReturn(props); - } - - List> stepContexts = new ArrayList<>(); - - AsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(); - - for(int i = 0; i < 4; i++) { - final long count = i; - stepContexts.add(executor.submit(new Callable() { - - @Override - public StepContext call() throws Exception { - try { - StepSynchronizationManager.register(new StepExecution("step" + count, new JobExecution(count))); - StepContext context = factory.getObject(); - Thread.sleep(1000L); - return context; - } catch (Throwable ignore) { - return null; - }finally { - StepSynchronizationManager.close(); - } - } - })); - } - - Set contexts = new HashSet<>(); - for (Future future : stepContexts) { - contexts.add(future.get()); - } - - assertEquals(4, contexts.size()); - - for (StepContext stepContext : contexts) { - assertEquals(stepContext.getStepName() + "value", stepContext.getProperties().get(stepContext.getStepName())); - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepContextTests.java deleted file mode 100644 index 9be1b6a84..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepContextTests.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Properties; - -import jakarta.batch.runtime.Metric; -import jakarta.batch.runtime.context.StepContext; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.util.ExecutionContextUserSupport; -import org.springframework.util.ClassUtils; - -public class JsrStepContextTests { - - private StepExecution stepExecution; - private StepContext stepContext; - private ExecutionContext executionContext; - private ExecutionContextUserSupport executionContextUserSupport = new ExecutionContextUserSupport(ClassUtils.getShortName(JsrStepContext.class)); - - @Before - public void setUp() throws Exception { - JobExecution jobExecution = new JobExecution(1L, new JobParametersBuilder().addString("key", "value").toJobParameters()); - - stepExecution = new StepExecution("testStep", jobExecution); - stepExecution.setId(5L); - stepExecution.setStatus(BatchStatus.STARTED); - stepExecution.setExitStatus(new ExitStatus("customExitStatus")); - stepExecution.setCommitCount(1); - stepExecution.setFilterCount(2); - stepExecution.setProcessSkipCount(3); - stepExecution.setReadCount(4); - stepExecution.setReadSkipCount(5); - stepExecution.setRollbackCount(6); - stepExecution.setWriteCount(7); - stepExecution.setWriteSkipCount(8); - executionContext = new ExecutionContext(); - stepExecution.setExecutionContext(executionContext); - - Properties properties = new Properties(); - properties.put("key", "value"); - - stepContext = new JsrStepContext(stepExecution, properties); - stepContext.setTransientUserData("This is my transient data"); - } - - @Test - public void testBasicProperties() { - assertEquals(jakarta.batch.runtime.BatchStatus.STARTED, stepContext.getBatchStatus()); - assertEquals(null, stepContext.getExitStatus()); - stepContext.setExitStatus("customExitStatus"); - assertEquals("customExitStatus", stepContext.getExitStatus()); - assertEquals(5L, stepContext.getStepExecutionId()); - assertEquals("testStep", stepContext.getStepName()); - assertEquals("This is my transient data", stepContext.getTransientUserData()); - - Properties params = stepContext.getProperties(); - assertEquals("value", params.get("key")); - - Metric[] metrics = stepContext.getMetrics(); - - for (Metric metric : metrics) { - switch (metric.getType()) { - case COMMIT_COUNT: - assertEquals(1, metric.getValue()); - break; - case FILTER_COUNT: - assertEquals(2, metric.getValue()); - break; - case PROCESS_SKIP_COUNT: - assertEquals(3, metric.getValue()); - break; - case READ_COUNT: - assertEquals(4, metric.getValue()); - break; - case READ_SKIP_COUNT: - assertEquals(5, metric.getValue()); - break; - case ROLLBACK_COUNT: - assertEquals(6, metric.getValue()); - break; - case WRITE_COUNT: - assertEquals(7, metric.getValue()); - break; - case WRITE_SKIP_COUNT: - assertEquals(8, metric.getValue()); - break; - default: - fail("Invalid metric type"); - } - } - } - - @Test - public void testSetExitStatus() { - stepContext.setExitStatus("new Exit Status"); - assertEquals("new Exit Status", stepExecution.getExitStatus().getExitCode()); - } - - @Test - public void testPersistentUserData() { - String data = "saved data"; - stepContext.setPersistentUserData(data); - assertEquals(data, stepContext.getPersistentUserData()); - assertEquals(data, executionContext.get(executionContextUserSupport.getKey("batch_jsr_persistentUserData"))); - } - - @Test - public void testGetExceptionEmpty() { - assertNull(stepContext.getException()); - } - - @Test - public void testGetExceptionException() { - stepExecution.addFailureException(new Exception("expected")); - assertEquals("expected", stepContext.getException().getMessage()); - } - - @Test - public void testGetExceptionThrowable() { - stepExecution.addFailureException(new Throwable("expected")); - assertTrue(stepContext.getException().getMessage().endsWith("expected")); - } - - @Test - public void testGetExceptionMultiple() { - stepExecution.addFailureException(new Exception("not me")); - stepExecution.addFailureException(new Exception("not me either")); - stepExecution.addFailureException(new Exception("me")); - - assertEquals("me", stepContext.getException().getMessage()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepExecutionTests.java deleted file mode 100644 index c437e6af6..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/JsrStepExecutionTests.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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. - * 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.jsr; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -import java.util.Date; - -import jakarta.batch.runtime.Metric; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.item.util.ExecutionContextUserSupport; -import org.springframework.util.ClassUtils; - -public class JsrStepExecutionTests { - - private StepExecution stepExecution; - private jakarta.batch.runtime.StepExecution jsrStepExecution; - //The API that sets the persisted user data is on the JsrStepContext so the key within the ExecutionContext is JsrStepContext - private ExecutionContextUserSupport executionContextUserSupport = new ExecutionContextUserSupport(ClassUtils.getShortName(JsrStepContext.class)); - - @Before - public void setUp() throws Exception { - JobExecution jobExecution = new JobExecution(1L, new JobParametersBuilder().addString("key", "value").toJobParameters()); - - stepExecution = new StepExecution("testStep", jobExecution); - stepExecution.setId(5L); - stepExecution.setStatus(BatchStatus.STARTED); - stepExecution.setExitStatus(new ExitStatus("customExitStatus")); - stepExecution.setCommitCount(1); - stepExecution.setFilterCount(2); - stepExecution.setProcessSkipCount(3); - stepExecution.setReadCount(4); - stepExecution.setReadSkipCount(5); - stepExecution.setRollbackCount(6); - stepExecution.setWriteCount(7); - stepExecution.setWriteSkipCount(8); - stepExecution.setStartTime(new Date(0)); - stepExecution.setEndTime(new Date(10000000)); - stepExecution.getExecutionContext().put(executionContextUserSupport.getKey("batch_jsr_persistentUserData"), "persisted data"); - - jsrStepExecution = new JsrStepExecution(stepExecution); - } - - @Test(expected=IllegalArgumentException.class) - public void testWithNullStepExecution() { - new JsrStepExecution(null); - } - - @Test - public void testNullExitStatus() { - stepExecution.setExitStatus(null); - - assertNull(jsrStepExecution.getExitStatus()); - } - - @Test - public void testBaseValues() { - assertEquals(5L, jsrStepExecution.getStepExecutionId()); - assertEquals("testStep", jsrStepExecution.getStepName()); - assertEquals(jakarta.batch.runtime.BatchStatus.STARTED, jsrStepExecution.getBatchStatus()); - assertEquals(new Date(0), jsrStepExecution.getStartTime()); - assertEquals(new Date(10000000), jsrStepExecution.getEndTime()); - assertEquals("customExitStatus", jsrStepExecution.getExitStatus()); - assertEquals("persisted data", jsrStepExecution.getPersistentUserData()); - - Metric[] metrics = jsrStepExecution.getMetrics(); - - for (Metric metric : metrics) { - switch (metric.getType()) { - case COMMIT_COUNT: - assertEquals(1, metric.getValue()); - break; - case FILTER_COUNT: - assertEquals(2, metric.getValue()); - break; - case PROCESS_SKIP_COUNT: - assertEquals(3, metric.getValue()); - break; - case READ_COUNT: - assertEquals(4, metric.getValue()); - break; - case READ_SKIP_COUNT: - assertEquals(5, metric.getValue()); - break; - case ROLLBACK_COUNT: - assertEquals(6, metric.getValue()); - break; - case WRITE_COUNT: - assertEquals(7, metric.getValue()); - break; - case WRITE_SKIP_COUNT: - assertEquals(8, metric.getValue()); - break; - default: - fail("Invalid metric type"); - } - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/SimpleMetricTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/SimpleMetricTests.java deleted file mode 100644 index 2758e7199..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/SimpleMetricTests.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.junit.Assert.assertEquals; - -import jakarta.batch.runtime.Metric; -import jakarta.batch.runtime.Metric.MetricType; - -import org.junit.Test; - -public class SimpleMetricTests { - - @Test(expected=IllegalArgumentException.class) - public void testNullType() { - new SimpleMetric(null, 0); - } - - @Test - public void test() { - Metric metric = new SimpleMetric(MetricType.FILTER_COUNT, 3); - - assertEquals(3, metric.getValue()); - assertEquals(MetricType.FILTER_COUNT, metric.getType()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/StepListenerAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/StepListenerAdapterTests.java deleted file mode 100644 index 10666c9a6..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/StepListenerAdapterTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import jakarta.batch.api.listener.StepListener; -import jakarta.batch.operations.BatchRuntimeException; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.StepExecution; - -public class StepListenerAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private StepListenerAdapter adapter; - @Mock - private StepListener delegate; - @Mock - private StepExecution execution; - - @Before - public void setUp() throws Exception { - adapter = new StepListenerAdapter(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new StepListenerAdapter(null); - } - - @Test - public void testBeforeStep() throws Exception { - adapter.beforeStep(null); - - verify(delegate).beforeStep(); - } - - @Test(expected=BatchRuntimeException.class) - public void testBeforeStepException() throws Exception { - doThrow(new Exception("expected")).when(delegate).beforeStep(); - - adapter.beforeStep(null); - } - - @Test - public void testAfterStep() throws Exception { - ExitStatus exitStatus = new ExitStatus("complete"); - when(execution.getExitStatus()).thenReturn(exitStatus); - - assertEquals(exitStatus, adapter.afterStep(execution)); - - verify(delegate).afterStep(); - } - - @Test(expected=BatchRuntimeException.class) - public void testAfterStepException() throws Exception { - doThrow(new Exception("expected")).when(delegate).afterStep(); - - adapter.afterStep(null); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContextTests.java deleted file mode 100644 index 53aa50982..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContextTests.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.support; - -import static org.junit.Assert.assertEquals; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import org.junit.Before; -import org.junit.Test; - -/** - *

- * Test cases around {@link BatchPropertyContext}. - *

- * - * @author Chris Schaefer - */ -public class BatchPropertyContextTests { - private Properties jobProperties = new Properties(); - private Map stepProperties = new HashMap<>(); - private Map artifactProperties = new HashMap<>(); - private Map> partitionProperties = new HashMap<>(); - private Map> stepArtifactProperties = new HashMap<>(); - - @SuppressWarnings("serial") - @Before - public void setUp() { - Properties step1Properties = new Properties(); - step1Properties.setProperty("step1PropertyName1", "step1PropertyValue1"); - step1Properties.setProperty("step1PropertyName2", "step1PropertyValue2"); - this.stepProperties.put("step1", step1Properties); - - Properties step2Properties = new Properties(); - step2Properties.setProperty("step2PropertyName1", "step2PropertyValue1"); - step2Properties.setProperty("step2PropertyName2", "step2PropertyValue2"); - this.stepProperties.put("step2", step2Properties); - - Properties jobProperties = new Properties(); - jobProperties.setProperty("jobProperty1", "jobProperty1value"); - jobProperties.setProperty("jobProperty2", "jobProperty2value"); - this.jobProperties.putAll(jobProperties); - - Properties artifactProperties = new Properties(); - artifactProperties.setProperty("deciderProperty1", "deciderProperty1value"); - artifactProperties.setProperty("deciderProperty2", "deciderProperty2value"); - this.artifactProperties.put("decider1", artifactProperties); - - final Properties stepArtifactProperties = new Properties(); - stepArtifactProperties.setProperty("readerProperty1", "readerProperty1value"); - stepArtifactProperties.setProperty("readerProperty2", "readerProperty2value"); - - this.stepArtifactProperties.put("step1", Collections.singletonMap("reader", stepArtifactProperties)); - - final Properties partitionProperties = new Properties(); - partitionProperties.setProperty("writerProperty1", "writerProperty1valuePartition0"); - partitionProperties.setProperty("writerProperty2", "writerProperty2valuePartition0"); - - this.partitionProperties.put("step2:partition0", Collections.singletonMap("writer", partitionProperties)); - - final Properties partitionStepProperties = new Properties(); - partitionStepProperties.setProperty("writerProperty1Step", "writerProperty1"); - partitionStepProperties.setProperty("writerProperty2Step", "writerProperty2"); - - this.partitionProperties.put("step2", Collections.singletonMap("writer", partitionStepProperties)); - } - - @Test - public void testStepLevelProperties() { - BatchPropertyContext batchPropertyContext = new BatchPropertyContext(); - batchPropertyContext.setJobProperties(jobProperties); - batchPropertyContext.setStepProperties(stepProperties); - - Properties step1Properties = batchPropertyContext.getStepProperties("step1"); - assertEquals(2, step1Properties.size()); - assertEquals("step1PropertyValue1", step1Properties.getProperty("step1PropertyName1")); - assertEquals("step1PropertyValue2", step1Properties.getProperty("step1PropertyName2")); - - Properties step2Properties = batchPropertyContext.getStepProperties("step2"); - assertEquals(2, step2Properties.size()); - assertEquals("step2PropertyValue1", step2Properties.getProperty("step2PropertyName1")); - assertEquals("step2PropertyValue2", step2Properties.getProperty("step2PropertyName2")); - } - - @Test - public void testJobLevelProperties() { - BatchPropertyContext batchPropertyContext = new BatchPropertyContext(); - batchPropertyContext.setJobProperties(jobProperties); - - Properties jobProperties = batchPropertyContext.getJobProperties(); - assertEquals(2, jobProperties.size()); - assertEquals("jobProperty1value", jobProperties.getProperty("jobProperty1")); - assertEquals("jobProperty2value", jobProperties.getProperty("jobProperty2")); - } - - @Test - public void testAddPropertiesToExistingStep() { - BatchPropertyContext batchPropertyContext = new BatchPropertyContext(); - batchPropertyContext.setJobProperties(jobProperties); - batchPropertyContext.setStepProperties(stepProperties); - - Properties step1 = batchPropertyContext.getStepProperties("step1"); - assertEquals(2, step1.size()); - assertEquals("step1PropertyValue1", step1.getProperty("step1PropertyName1")); - assertEquals("step1PropertyValue2", step1.getProperty("step1PropertyName2")); - - Properties step1properties = new Properties(); - step1properties.setProperty("newStep1PropertyName", "newStep1PropertyValue"); - - batchPropertyContext.setStepProperties("step1", step1properties); - - Properties step1updated = batchPropertyContext.getStepProperties("step1"); - assertEquals(3, step1updated.size()); - assertEquals("step1PropertyValue1", step1updated.getProperty("step1PropertyName1")); - assertEquals("step1PropertyValue2", step1updated.getProperty("step1PropertyName2")); - assertEquals("newStep1PropertyValue", step1updated.getProperty("newStep1PropertyName")); - } - - @Test - public void testNonStepLevelArtifactProperties() { - BatchPropertyContext batchPropertyContext = new BatchPropertyContext(); - batchPropertyContext.setJobProperties(jobProperties); - batchPropertyContext.setArtifactProperties(artifactProperties); - batchPropertyContext.setStepProperties(stepProperties); - - Properties artifactProperties = batchPropertyContext.getArtifactProperties("decider1"); - assertEquals(2, artifactProperties.size()); - assertEquals("deciderProperty1value", artifactProperties.getProperty("deciderProperty1")); - assertEquals("deciderProperty2value", artifactProperties.getProperty("deciderProperty2")); - } - - @Test - public void testStepLevelArtifactProperties() { - BatchPropertyContext batchPropertyContext = new BatchPropertyContext(); - batchPropertyContext.setJobProperties(jobProperties); - batchPropertyContext.setArtifactProperties(artifactProperties); - batchPropertyContext.setStepProperties(stepProperties); - batchPropertyContext.setStepArtifactProperties(stepArtifactProperties); - - Properties artifactProperties = batchPropertyContext.getStepArtifactProperties("step1", "reader"); - assertEquals(4, artifactProperties.size()); - assertEquals("readerProperty1value", artifactProperties.getProperty("readerProperty1")); - assertEquals("readerProperty2value", artifactProperties.getProperty("readerProperty2")); - assertEquals("step1PropertyValue1", artifactProperties.getProperty("step1PropertyName1")); - assertEquals("step1PropertyValue2", artifactProperties.getProperty("step1PropertyName2")); - } - - @Test - public void testArtifactNonOverridingJobProperties() { - BatchPropertyContext batchPropertyContext = new BatchPropertyContext(); - batchPropertyContext.setJobProperties(jobProperties); - batchPropertyContext.setArtifactProperties(artifactProperties); - - Properties jobProperties = new Properties(); - jobProperties.setProperty("deciderProperty1", "decider1PropertyOverride"); - - batchPropertyContext.setJobProperties(jobProperties); - - Properties step1 = batchPropertyContext.getArtifactProperties("decider1"); - assertEquals(2, step1.size()); - assertEquals("deciderProperty1value", step1.getProperty("deciderProperty1")); - assertEquals("deciderProperty2value", step1.getProperty("deciderProperty2")); - - Properties job = batchPropertyContext.getJobProperties(); - assertEquals(3, job.size()); - assertEquals("decider1PropertyOverride", job.getProperty("deciderProperty1")); - assertEquals("jobProperty1value", job.getProperty("jobProperty1")); - assertEquals("jobProperty2value", job.getProperty("jobProperty2")); - } - - @Test - public void testPartitionProperties() { - BatchPropertyContext batchPropertyContext = new BatchPropertyContext(); - batchPropertyContext.setJobProperties(jobProperties); - batchPropertyContext.setArtifactProperties(artifactProperties); - batchPropertyContext.setStepProperties(stepProperties); - batchPropertyContext.setStepArtifactProperties(stepArtifactProperties); - batchPropertyContext.setStepArtifactProperties(partitionProperties); - - Properties artifactProperties = batchPropertyContext.getStepArtifactProperties("step2:partition0", "writer"); - assertEquals(6, artifactProperties.size()); - assertEquals("writerProperty1", artifactProperties.getProperty("writerProperty1Step")); - assertEquals("writerProperty2", artifactProperties.getProperty("writerProperty2Step")); - assertEquals("writerProperty1valuePartition0", artifactProperties.getProperty("writerProperty1")); - assertEquals("writerProperty2valuePartition0", artifactProperties.getProperty("writerProperty2")); - assertEquals("step2PropertyValue1", artifactProperties.getProperty("step2PropertyName1")); - assertEquals("step2PropertyValue2", artifactProperties.getProperty("step2PropertyName2")); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/BatchParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/BatchParserTests.java deleted file mode 100644 index 407d0c607..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/BatchParserTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 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.jsr.configuration.xml; - -import org.junit.Test; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.configuration.xml.DummyItemProcessor; -import org.springframework.batch.core.scope.StepScope; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; -import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class BatchParserTests { - - @Test - @SuppressWarnings("unchecked") - public void testRoseyScenario() throws Exception { - JsrXmlApplicationContext context = new JsrXmlApplicationContext(); - Resource batchXml = new ClassPathResource("/org/springframework/batch/core/jsr/configuration/xml/batch.xml"); - context.setValidating(false); - context.load(batchXml); - - GenericBeanDefinition stepScope = new GenericBeanDefinition(); - stepScope.setBeanClass(StepScope.class); - context.registerBeanDefinition("stepScope", stepScope); - - GenericBeanDefinition bd = new GenericBeanDefinition(); - bd.setBeanClass(AutowiredAnnotationBeanPostProcessor.class); - context.registerBeanDefinition("postProcessor", bd); - context.refresh(); - - ItemProcessor itemProcessor = context.getBean(ItemProcessor.class); - - assertNotNull(itemProcessor); - StepSynchronizationManager.register(new StepExecution("step1", new JobExecution(5l))); - assertEquals("Test", itemProcessor.process("Test")); - StepSynchronizationManager.close(); - - context.close(); - } - - @Test - @SuppressWarnings("unchecked") - public void testOverrideBeansFirst() throws Exception { - JsrXmlApplicationContext context = new JsrXmlApplicationContext(); - Resource overrideXml = new ClassPathResource("/org/springframework/batch/core/jsr/configuration/xml/override_batch.xml"); - Resource batchXml = new ClassPathResource("/org/springframework/batch/core/jsr/configuration/xml/batch.xml"); - - context.setValidating(false); - context.load(overrideXml, batchXml); - context.refresh(); - - ItemProcessor itemProcessor = context.getBean("itemProcessor", ItemProcessor.class); - - assertNotNull(itemProcessor); - StepSynchronizationManager.register(new StepExecution("step1", new JobExecution(5l))); - assertEquals("Test", itemProcessor.process("Test")); - StepSynchronizationManager.close(); - - context.close(); - } - - @Test - @SuppressWarnings({"resource", "rawtypes"}) - public void testOverrideBeansLast() { - JsrXmlApplicationContext context = new JsrXmlApplicationContext(); - Resource overrideXml = new ClassPathResource("/org/springframework/batch/core/jsr/configuration/xml/override_batch.xml"); - Resource batchXml = new ClassPathResource("/org/springframework/batch/core/jsr/configuration/xml/batch.xml"); - - context.setValidating(false); - context.load(batchXml, overrideXml); - context.refresh(); - - ItemProcessor processor = (ItemProcessor) context.getBean("itemProcessor"); - - assertNotNull(processor); - assertTrue(processor instanceof DummyItemProcessor); - context.close(); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ChunkListenerParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ChunkListenerParsingTests.java deleted file mode 100644 index 3165d1681..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ChunkListenerParsingTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import jakarta.batch.api.chunk.AbstractItemWriter; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class ChunkListenerParsingTests { - - @Autowired - public Job job; - - @Autowired - public JobLauncher jobLauncher; - - @Autowired - public SpringChunkListener springChunkListener; - - @Autowired - public JsrChunkListener jsrChunkListener; - - @Test - public void test() throws Exception { - JobExecution execution = jobLauncher.run(job, new JobParameters()); - assertEquals(BatchStatus.FAILED, execution.getStatus()); - assertEquals(3, execution.getStepExecutions().size()); - assertEquals(4, springChunkListener.beforeChunkCount); - assertEquals(3, springChunkListener.afterChunkCount); - assertEquals(4, jsrChunkListener.beforeChunkCount); - assertEquals(3, jsrChunkListener.afterChunkCount); - assertEquals(1, springChunkListener.afterChunkErrorCount); - assertEquals(1, jsrChunkListener.afterChunkErrorCount); - } - - public static class SpringChunkListener implements ChunkListener { - - protected int beforeChunkCount = 0; - protected int afterChunkCount = 0; - protected int afterChunkErrorCount = 0; - - @Override - public void beforeChunk(ChunkContext context) { - beforeChunkCount++; - } - - @Override - public void afterChunk(ChunkContext context) { - afterChunkCount++; - } - - @Override - public void afterChunkError(ChunkContext context) { - afterChunkErrorCount++; - } - } - - public static class JsrChunkListener implements jakarta.batch.api.chunk.listener.ChunkListener { - - protected int beforeChunkCount = 0; - protected int afterChunkCount = 0; - protected int afterChunkErrorCount = 0; - - @Override - public void beforeChunk() throws Exception { - beforeChunkCount++; - } - - @Override - public void onError(Exception ex) throws Exception { - afterChunkErrorCount++; - } - - @Override - public void afterChunk() throws Exception { - afterChunkCount++; - } - } - - public static class ErrorThrowingItemWriter extends AbstractItemWriter { - - @Override - public void writeItems(List items) throws Exception { - throw new Exception("This should cause the rollback"); - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/CountingItemProcessor.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/CountingItemProcessor.java deleted file mode 100644 index 1921160e1..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/CountingItemProcessor.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import jakarta.batch.api.chunk.ItemProcessor; - - -public class CountingItemProcessor implements ItemProcessor { - protected int count = 0; - - @Override - public Object processItem(Object item) throws Exception { - count++; - return item; - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/CustomWiredJsrJobOperatorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/CustomWiredJsrJobOperatorTests.java deleted file mode 100644 index 8da8c5e14..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/CustomWiredJsrJobOperatorTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - * 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.jsr.configuration.xml; - -import java.util.Date; -import java.util.Properties; -import java.util.concurrent.TimeoutException; - -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class CustomWiredJsrJobOperatorTests { - - @Autowired - JobOperator jobOperator; - - @Test - public void testRunningJobWithManuallyWiredJsrJobOperator() throws Exception { - Date startTime = new Date(); - long jobExecutionId = jobOperator.start("jsrJobOperatorTestJob", new Properties()); - - JobExecution jobExecution = jobOperator.getJobExecution(jobExecutionId); - - long timeout = startTime.getTime() + 10000; - - while(!jobExecution.getBatchStatus().equals(BatchStatus.COMPLETED)) { - Thread.sleep(500); - jobExecution = jobOperator.getJobExecution(jobExecutionId); - - if(new Date().getTime() > timeout) { - throw new TimeoutException("Job didn't finish within 10 seconds"); - } - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/DecisionStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/DecisionStepFactoryBeanTests.java deleted file mode 100644 index ca95920f2..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/DecisionStepFactoryBeanTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import jakarta.batch.api.Decider; -import jakarta.batch.runtime.StepExecution; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.jsr.step.DecisionStep; - -public class DecisionStepFactoryBeanTests { - - private DecisionStepFactoryBean factoryBean; - - @Before - public void setUp() throws Exception { - factoryBean = new DecisionStepFactoryBean(); - } - - @Test - public void testGetObjectType() { - assertEquals(DecisionStep.class, factoryBean.getObjectType()); - } - - @Test - public void testIsSingleton() { - assertTrue(factoryBean.isSingleton()); - } - - @Test(expected=IllegalArgumentException.class) - public void testNullDeciderAndName() throws Exception { - factoryBean.afterPropertiesSet(); - } - - @Test(expected=IllegalArgumentException.class) - public void testNullDecider() throws Exception{ - factoryBean.setName("state1"); - factoryBean.afterPropertiesSet(); - } - - @Test(expected=IllegalArgumentException.class) - public void testNullName() throws Exception { - factoryBean.setDecider(new DeciderSupport()); - factoryBean.afterPropertiesSet(); - } - - @Test - public void testDeciderDeciderState() throws Exception { - factoryBean.setDecider(new DeciderSupport()); - factoryBean.setName("IL"); - - factoryBean.afterPropertiesSet(); - - Step step = factoryBean.getObject(); - - assertEquals("IL", step.getName()); - assertEquals(DecisionStep.class, step.getClass()); - } - - public static class DeciderSupport implements Decider { - - @Override - public String decide(StepExecution[] executions) throws Exception { - return null; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ExceptionHandlingParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ExceptionHandlingParsingTests.java deleted file mode 100644 index b9f05ab73..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ExceptionHandlingParsingTests.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import org.junit.Test; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; - -import jakarta.batch.api.BatchProperty; -import jakarta.batch.api.chunk.ItemProcessor; -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.Metric; -import jakarta.batch.runtime.StepExecution; -import jakarta.inject.Inject; -import java.util.List; -import java.util.Properties; - -import static org.junit.Assert.assertEquals; - -public class ExceptionHandlingParsingTests extends AbstractJsrTestCase { - - @Test - public void testSkippable() throws Exception { - JobOperator jobOperator = BatchRuntime.getJobOperator(); - - Properties jobParameters = new Properties(); - jobParameters.setProperty("run", "1"); - JobExecution execution1 = runJob("ExceptionHandlingParsingTests-context", jobParameters, 10000l); - - List stepExecutions = jobOperator.getStepExecutions(execution1.getExecutionId()); - assertEquals(BatchStatus.FAILED, execution1.getBatchStatus()); - assertEquals(1, stepExecutions.size()); - assertEquals(1, getMetric(stepExecutions.get(0), Metric.MetricType.PROCESS_SKIP_COUNT).getValue()); - - jobParameters = new Properties(); - jobParameters.setProperty("run", "2"); - JobExecution execution2 = restartJob(execution1.getExecutionId(), jobParameters, 10000l); - stepExecutions = jobOperator.getStepExecutions(execution2.getExecutionId()); - assertEquals(BatchStatus.FAILED, execution2.getBatchStatus()); - assertEquals(2, stepExecutions.size()); - - jobParameters = new Properties(); - jobParameters.setProperty("run", "3"); - JobExecution execution3 = restartJob(execution2.getExecutionId(), jobParameters, 10000l); - stepExecutions = jobOperator.getStepExecutions(execution3.getExecutionId()); - assertEquals(BatchStatus.COMPLETED, execution3.getBatchStatus()); - assertEquals(2, stepExecutions.size()); - - assertEquals(0, getMetric(stepExecutions.get(1), Metric.MetricType.ROLLBACK_COUNT).getValue()); - - jobParameters = new Properties(); - jobParameters.setProperty("run", "4"); - JobExecution execution4 = runJob("ExceptionHandlingParsingTests-context", jobParameters, 10000l); - stepExecutions = jobOperator.getStepExecutions(execution4.getExecutionId()); - assertEquals(BatchStatus.COMPLETED, execution4.getBatchStatus()); - assertEquals(3, stepExecutions.size()); - } - - public static class ProblemProcessor implements ItemProcessor { - - @Inject - @BatchProperty - private String runId = "0"; - - private boolean hasRetried = false; - - private void throwException(Object item) throws Exception { - int runId = Integer.parseInt(this.runId); - - if(runId == 1) { - if(item.equals("One")) { - throw new Exception("skip me"); - } else if(item.equals("Two")){ - throw new RuntimeException("But don't skip me"); - } - } else if(runId == 2) { - if(item.equals("Three") && !hasRetried) { - hasRetried = true; - throw new Exception("retry me"); - } else if(item.equals("Four")){ - throw new RuntimeException("But don't retry me"); - } - } else if(runId == 3) { - if(item.equals("Five")) { - throw new Exception("Don't rollback on my account"); - } - } - } - - @Override - public Object processItem(Object item) throws Exception { - throwException(item); - return item; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/FlowParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/FlowParserTests.java deleted file mode 100644 index eb202deba..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/FlowParserTests.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import org.junit.Test; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; - -import jakarta.batch.api.AbstractBatchlet; -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.StepExecution; -import jakarta.batch.runtime.context.StepContext; -import jakarta.inject.Inject; -import java.util.List; -import java.util.Properties; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - *

- * Unit tests around {@link FlowParser}. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class FlowParserTests extends AbstractJsrTestCase { - @Test - public void testDuplicateTransitionPatternsAllowed() throws Exception { - JobExecution stoppedExecution = runJob("FlowParserTests-context", new Properties(), 10000L); - assertEquals(ExitStatus.STOPPED.getExitCode(), stoppedExecution.getExitStatus()); - - JobExecution endedExecution = restartJob(stoppedExecution.getExecutionId(), new Properties(), 10000L); - assertEquals(ExitStatus.COMPLETED.getExitCode(), endedExecution.getExitStatus()); - } - - @Test - public void testWildcardAddedLastWhenUsedWithNextAttrAndNoTransitionElements() throws Exception { - JobExecution jobExecution = runJob("FlowParserTestsWildcardAndNextAttrJob", new Properties(), 1000L); - assertEquals(ExitStatus.FAILED.getExitCode(), jobExecution.getExitStatus()); - - JobOperator jobOperator = BatchRuntime.getJobOperator(); - List stepExecutions = jobOperator.getStepExecutions(jobExecution.getExecutionId()); - assertEquals(1, stepExecutions.size()); - StepExecution failedStep = stepExecutions.get(0); - assertTrue("step1".equals(failedStep.getStepName())); - } - - @Test - public void testStepGetsFailedTransitionWhenNextAttributePresent() throws Exception { - JobExecution jobExecution = runJob("FlowParserTestsStepGetsFailedTransitionWhenNextAttributePresent", new Properties(), 10000L); - assertEquals(ExitStatus.FAILED.getExitCode(), jobExecution.getExitStatus()); - - JobOperator jobOperator = BatchRuntime.getJobOperator(); - List stepExecutions = jobOperator.getStepExecutions(jobExecution.getExecutionId()); - assertEquals(1, stepExecutions.size()); - StepExecution failedStep = stepExecutions.get(0); - assertTrue("failedExitStatusStep".equals(failedStep.getStepName())); - assertTrue("FAILED".equals(failedStep.getExitStatus())); - } - - @Test - public void testStepNoOverrideWhenNextAndFailedTransitionElementExists() throws Exception { - JobExecution jobExecution = runJob("FlowParserTestsStepNoOverrideWhenNextAndFailedTransitionElementExists", new Properties(), 10000L); - assertEquals(ExitStatus.FAILED.getExitCode(), jobExecution.getExitStatus()); - - JobOperator jobOperator = BatchRuntime.getJobOperator(); - List stepExecutions = jobOperator.getStepExecutions(jobExecution.getExecutionId()); - assertEquals(1, stepExecutions.size()); - StepExecution failedStep = stepExecutions.get(0); - assertTrue("failedExitStatusStepDontOverride".equals(failedStep.getStepName())); - assertTrue("CUSTOM_FAIL".equals(failedStep.getExitStatus())); - } - - public static class TestBatchlet extends AbstractBatchlet { - private static int CNT; - - @Inject - private StepContext stepContext; - - @Override - public String process() throws Exception { - String exitCode = "DISTINCT"; - - if("step3".equals(stepContext.getStepName())) { - exitCode = CNT % 2 == 0 ? "DISTINCT" : "RESTART"; - CNT++; - } - - if("failedExitStatusStep".equals(stepContext.getStepName())) { - exitCode = "FAILED"; - } - - if("failedExitStatusStepDontOverride".equals(stepContext.getStepName())) { - exitCode = "CUSTOM_FAIL"; - } - - return exitCode; - } - } - - public static class FailingTestBatchlet extends AbstractBatchlet { - @Override - public String process() throws Exception { - throw new RuntimeException("blah"); - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ItemListenerParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ItemListenerParsingTests.java deleted file mode 100644 index 646436e56..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ItemListenerParsingTests.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ItemProcessListener; -import org.springframework.batch.core.ItemReadListener; -import org.springframework.batch.core.ItemWriteListener; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.lang.Nullable; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class ItemListenerParsingTests { - - @Autowired - public Job job; - - @Autowired - public JobLauncher jobLauncher; - - @Autowired - public SpringItemListener springListener; - - @Autowired - public JsrItemListener jsrListener; - - @Test - public void test() throws Exception { - JobExecution execution = jobLauncher.run(job, new JobParameters()); - assertEquals(BatchStatus.COMPLETED, execution.getStatus()); - assertEquals(3, execution.getStepExecutions().size()); - assertEquals(6, springListener.beforeReadCount); - assertEquals(4, springListener.afterReadCount); - assertEquals(4, springListener.beforeProcessCount); - assertEquals(4, springListener.afterProcessCount); - assertEquals(2, springListener.beforeWriteCount); - assertEquals(2, springListener.afterWriteCount); - assertEquals(6, jsrListener.beforeReadCount); - assertEquals(4, jsrListener.afterReadCount); - assertEquals(4, jsrListener.beforeProcessCount); - assertEquals(4, jsrListener.afterProcessCount); - assertEquals(2, jsrListener.beforeWriteCount); - assertEquals(2, jsrListener.afterWriteCount); - } - - public static class SpringItemListener implements ItemReadListener, ItemProcessListener, ItemWriteListener { - - protected int beforeReadCount = 0; - protected int afterReadCount = 0; - protected int onReadErrorCount = 0; - protected int beforeProcessCount = 0; - protected int afterProcessCount = 0; - protected int onProcessErrorCount = 0; - protected int beforeWriteCount = 0; - protected int afterWriteCount = 0; - protected int onWriteErrorCount = 0; - - @Override - public void beforeRead() { - beforeReadCount++; - } - - @Override - public void afterRead(Object item) { - afterReadCount++; - } - - @Override - public void onReadError(Exception ex) { - onReadErrorCount++; - } - - @Override - public void beforeWrite(List items) { - beforeWriteCount++; - } - - @Override - public void afterWrite(List items) { - afterWriteCount++; - } - - @Override - public void onWriteError(Exception exception, List items) { - onWriteErrorCount++; - } - - @Override - public void beforeProcess(Object item) { - beforeProcessCount++; - } - - @Override - public void afterProcess(Object item, @Nullable Object result) { - afterProcessCount++; - } - - @Override - public void onProcessError(Object item, Exception e) { - onProcessErrorCount++; - } - } - - public static class JsrItemListener implements jakarta.batch.api.chunk.listener.ItemReadListener, jakarta.batch.api.chunk.listener.ItemProcessListener, jakarta.batch.api.chunk.listener.ItemWriteListener { - - protected int beforeReadCount = 0; - protected int afterReadCount = 0; - protected int onReadErrorCount = 0; - protected int beforeProcessCount = 0; - protected int afterProcessCount = 0; - protected int onProcessErrorCount = 0; - protected int beforeWriteCount = 0; - protected int afterWriteCount = 0; - protected int onWriteErrorCount = 0; - - @Override - public void beforeWrite(List items) throws Exception { - beforeWriteCount++; - } - - @Override - public void afterWrite(List items) throws Exception { - afterWriteCount++; - } - - @Override - public void onWriteError(List items, Exception ex) - throws Exception { - onWriteErrorCount++; - } - - @Override - public void beforeProcess(Object item) throws Exception { - beforeProcessCount++; - } - - @Override - public void afterProcess(Object item, Object result) throws Exception { - afterProcessCount++; - } - - @Override - public void onProcessError(Object item, Exception ex) throws Exception { - onProcessErrorCount++; - } - - @Override - public void beforeRead() throws Exception { - beforeReadCount++; - } - - @Override - public void afterRead(Object item) throws Exception { - afterReadCount++; - } - - @Override - public void onReadError(Exception ex) throws Exception { - onReadErrorCount++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ItemSkipParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ItemSkipParsingTests.java deleted file mode 100644 index bac1380ae..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ItemSkipParsingTests.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import org.junit.Test; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.lang.Nullable; - -import jakarta.batch.api.chunk.listener.SkipProcessListener; -import jakarta.batch.api.chunk.listener.SkipReadListener; -import jakarta.batch.api.chunk.listener.SkipWriteListener; -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.Metric; -import jakarta.batch.runtime.StepExecution; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import static org.junit.Assert.assertEquals; - -public class ItemSkipParsingTests extends AbstractJsrTestCase { - - @Test - public void test() throws Exception { - jakarta.batch.runtime.JobExecution execution = runJob("ItemSkipParsingTests-context", new Properties(), 10000l); - JobOperator jobOperator = BatchRuntime.getJobOperator(); - - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - List stepExecutions = jobOperator.getStepExecutions(execution.getExecutionId()); - assertEquals(1, getMetric(stepExecutions.get(0), Metric.MetricType.READ_SKIP_COUNT).getValue()); - assertEquals(1, TestSkipListener.readSkips); - assertEquals(0, TestSkipListener.processSkips); - assertEquals(0, TestSkipListener.writeSkips); - - // Process skip and fail - execution = restartJob(execution.getExecutionId(), new Properties(), 10000l); - - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - stepExecutions = jobOperator.getStepExecutions(execution.getExecutionId()); - assertEquals(1, getMetric(stepExecutions.get(0), Metric.MetricType.PROCESS_SKIP_COUNT).getValue()); - assertEquals(0, TestSkipListener.readSkips); - assertEquals(1, TestSkipListener.processSkips); - assertEquals(0, TestSkipListener.writeSkips); - - // Write skip and fail - execution = restartJob(execution.getExecutionId(), new Properties(), 10000l); - - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - stepExecutions = jobOperator.getStepExecutions(execution.getExecutionId()); - assertEquals(1, getMetric(stepExecutions.get(0), Metric.MetricType.WRITE_SKIP_COUNT).getValue()); - assertEquals(0, TestSkipListener.readSkips); - assertEquals(0, TestSkipListener.processSkips); - assertEquals(1, TestSkipListener.writeSkips); - - // Complete - execution = restartJob(execution.getExecutionId(), new Properties(), 10000l); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - stepExecutions = jobOperator.getStepExecutions(execution.getExecutionId()); - assertEquals(0, getMetric(stepExecutions.get(0), Metric.MetricType.WRITE_SKIP_COUNT).getValue()); - assertEquals(0, TestSkipListener.readSkips); - assertEquals(0, TestSkipListener.processSkips); - assertEquals(0, TestSkipListener.writeSkips); - } - - public static class SkipErrorGeneratingReader implements ItemReader { - private static int count = 0; - - @Nullable - @Override - public String read() throws Exception { - count++; - - if(count == 1) { - throw new Exception("read skip me"); - } else if (count == 2) { - return "item" + count; - } else if(count == 3) { - throw new RuntimeException("read fail because of me"); - } else if(count < 15) { - return "item" + count; - } else { - return null; - } - } - } - - public static class SkipErrorGeneratingProcessor implements ItemProcessor { - private static int count = 0; - - @Nullable - @Override - public String process(String item) throws Exception { - count++; - - if(count == 4) { - throw new Exception("process skip me"); - } else if(count == 5) { - return item; - } else if(count == 6) { - throw new RuntimeException("process fail because of me"); - } else { - return item; - } - } - } - - public static class SkipErrorGeneratingWriter implements ItemWriter { - private static int count = 0; - protected List writtenItems = new ArrayList<>(); - private List skippedItems = new ArrayList<>(); - - @Override - public void write(List items) throws Exception { - if(items.size() > 0 && !skippedItems.contains(items.get(0))) { - count++; - } - - if(count == 7) { - skippedItems.addAll(items); - throw new Exception("write skip me"); - } else if(count == 9) { - skippedItems = new ArrayList<>(); - throw new RuntimeException("write fail because of me"); - } else { - writtenItems.addAll(items); - } - } - } - - public static class TestSkipListener implements SkipReadListener, SkipProcessListener, SkipWriteListener { - - protected static int readSkips = 0; - protected static int processSkips = 0; - protected static int writeSkips = 0; - - public TestSkipListener() { - readSkips = 0; - processSkips = 0; - writeSkips = 0; - } - - @Override - public void onSkipProcessItem(Object item, Exception ex) throws Exception { - processSkips++; - } - - @Override - public void onSkipReadItem(Exception ex) throws Exception { - readSkips++; - } - - @Override - public void onSkipWriteItem(List items, Exception ex) throws Exception { - writeSkips++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobListenerParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobListenerParsingTests.java deleted file mode 100644 index 12aa270fe..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobListenerParsingTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import jakarta.batch.api.listener.JobListener; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobExecutionListener; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class JobListenerParsingTests { - - @Autowired - public Job job; - - @Autowired - public JobLauncher jobLauncher; - - @Autowired - public SpringJobListener springListener; - - @Autowired - public JsrJobListener jsrListener; - - @Test - public void test() throws Exception { - assertNotNull(job); - assertEquals("job1", job.getName()); - - JobExecution execution = jobLauncher.run(job, new JobParameters()); - assertEquals(BatchStatus.COMPLETED, execution.getStatus()); - assertEquals(2, execution.getStepExecutions().size()); - assertEquals(1, springListener.countAfterJob); - assertEquals(1, springListener.countBeforeJob); - assertEquals(1, jsrListener.countAfterJob); - assertEquals(1, jsrListener.countBeforeJob); - } - - public static class SpringJobListener implements JobExecutionListener { - - protected int countBeforeJob = 0; - protected int countAfterJob = 0; - - @Override - public void beforeJob(JobExecution jobExecution) { - countBeforeJob++; - } - - @Override - public void afterJob(JobExecution jobExecution) { - countAfterJob++; - } - } - - public static class JsrJobListener implements JobListener { - - protected int countBeforeJob = 0; - protected int countAfterJob = 0; - - @Override - public void afterJob() throws Exception { - countBeforeJob++; - } - - @Override - public void beforeJob() throws Exception { - countAfterJob++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobPropertySubstitutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobPropertySubstitutionTests.java deleted file mode 100644 index fc20a989c..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobPropertySubstitutionTests.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.io.Serializable; -import java.util.List; -import jakarta.batch.api.BatchProperty; -import jakarta.batch.api.chunk.ItemProcessor; -import jakarta.batch.api.chunk.ItemReader; -import jakarta.batch.api.chunk.ItemWriter; -import jakarta.inject.Inject; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import static org.junit.Assert.assertEquals; - -/** - *

- * Test cases for JSR-352 job property substitution. - *

- * - * TODO: enhance test cases with more complex substitutions - * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class JobPropertySubstitutionTests { - @Autowired - private Job job; - - @Autowired - private JobLauncher jobLauncher; - - @Test - public void testPropertySubstitutionSimple() throws Exception { - JobExecution jobExecution = jobLauncher.run(job, - new JobParametersBuilder() - .addString("testParam", "testParamValue") - .addString("file.name.junit", "myfile2") - .toJobParameters()); - assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); - } - - public static final class TestItemReader implements ItemReader { - private int cnt; - - @Inject - @BatchProperty - String readerPropertyName1; - - @Override - public void open(Serializable serializable) throws Exception { - assertEquals(System.getProperty("file.separator"), readerPropertyName1); - } - - @Override - public void close() throws Exception { - } - - @Override - public Object readItem() throws Exception { - if (cnt == 0) { - cnt++; - return "blah"; - } - - return null; - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } - - public static final class TestItemWriter implements ItemWriter { - @Inject - @BatchProperty - String writerPropertyName1; - - @Override - public void open(Serializable serializable) throws Exception { - assertEquals("jobPropertyValue1", writerPropertyName1); - } - - @Override - public void close() throws Exception { - } - - @Override - public void writeItems(List objects) throws Exception { - System.out.println(objects); - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } - - public static final class TestItemProcessor implements ItemProcessor { - @Inject - @BatchProperty - String processorProperty1; - - @Inject - @BatchProperty - String processorProperty2; - - @Inject - @BatchProperty - String processorProperty3; - - @Override - public Object processItem(Object item) throws Exception { - assertEquals("testParamValue", processorProperty1); - assertEquals("myfile1.txt", processorProperty2); - assertEquals(System.getProperty("file.separator") + "myfile2.txt", processorProperty3); - - return item; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobPropertyTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobPropertyTests.java deleted file mode 100644 index 0df62768b..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JobPropertyTests.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.io.Serializable; -import java.util.List; -import java.util.Properties; -import jakarta.batch.api.BatchProperty; -import jakarta.batch.api.Batchlet; -import jakarta.batch.api.Decider; -import jakarta.batch.api.chunk.CheckpointAlgorithm; -import jakarta.batch.api.chunk.ItemProcessor; -import jakarta.batch.api.chunk.ItemReader; -import jakarta.batch.api.chunk.ItemWriter; -import jakarta.batch.api.listener.StepListener; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.context.JobContext; -import jakarta.inject.Inject; - -import org.junit.Test; - -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.batch.core.step.tasklet.Tasklet; -import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.lang.Nullable; - -import static org.junit.Assert.assertEquals; - -/** - *

- * Configuration test for parsing various <properties /> elements defined by JSR-352. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JobPropertyTests extends AbstractJsrTestCase { - @Test - public void testJobPropertyConfiguration() throws Exception { - Properties jobParameters = new Properties(); - jobParameters.setProperty("allow.start.if.complete", "true"); - jobParameters.setProperty("deciderName", "stepDecider"); - jobParameters.setProperty("deciderNumber", "1"); - - JobExecution jobExecution = runJob("jsrJobPropertyTestsContext", jobParameters, 5000L); - assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus()); - } - - public static final class TestItemReader implements ItemReader { - private int cnt; - - @Inject @BatchProperty String readerPropertyName1; - @Inject @BatchProperty String readerPropertyName2; - @Inject @BatchProperty String readerPropertyName3; - @Inject @BatchProperty(name = "annotationNamedReaderPropertyName") String annotationNamedProperty; - @Inject @BatchProperty String notDefinedProperty; - @Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty; - @Inject @BatchProperty String jobPropertyName1; - @Inject @BatchProperty String jobPropertyName2; - @Inject JobContext injectAnnotatedOnlyField; - @BatchProperty String batchAnnotatedOnlyField; - @Inject jakarta.batch.runtime.context.StepContext stepContext; - - @Override - public void open(Serializable serializable) throws Exception { - org.springframework.util.Assert.notNull(stepContext, "stepContext is not null"); - org.springframework.util.Assert.isNull(stepContext.getProperties().get("step2PropertyName1"), "step2PropertyName1 is not null"); - org.springframework.util.Assert.isNull(stepContext.getProperties().get("step2PropertyName2"), "step2PropertyName2 is not null"); - org.springframework.util.Assert.isTrue(stepContext.getProperties().get("step1PropertyName1").equals("step1PropertyValue1"), "The value of step2PropertyName1 does not equal step2PropertyName1"); - org.springframework.util.Assert.isTrue(stepContext.getProperties().get("step1PropertyName2").equals("step1PropertyValue2"), "The value of step2PropertyName2 does not equal step2PropertyName2"); - org.springframework.util.Assert.isNull(stepContext.getProperties().get("jobPropertyName1"), "jobPropertyName1 is not null"); - org.springframework.util.Assert.isNull(stepContext.getProperties().get("jobPropertyName2") == null, "jobPropertyName2 is not null"); - org.springframework.util.Assert.isTrue("readerPropertyValue1".equals(readerPropertyName1), "The value of readerPropertyValue1 does not equal readerPropertyValue1"); - org.springframework.util.Assert.isTrue("readerPropertyValue2".equals(readerPropertyName2), "The value of readerPropertyValue2 does not equal readerPropertyValue2"); - org.springframework.util.Assert.isTrue("annotationNamedReaderPropertyValue".equals(annotationNamedProperty), "The value of annotationNamedReaderPropertyValue does not equal annotationNamedReaderPropertyValue"); - org.springframework.util.Assert.isNull(notDefinedProperty, "notDefinedProperty is not null"); - org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty, "notDefinedAnnotationNamedProperty is not null"); - org.springframework.util.Assert.isNull(batchAnnotatedOnlyField, "batchAnnotatedOnlyField is not null"); - org.springframework.util.Assert.notNull(injectAnnotatedOnlyField, "injectAnnotatedOnlyField is not null"); - org.springframework.util.Assert.isTrue("job1".equals(injectAnnotatedOnlyField.getJobName()), "injectAnnotatedOnlyField does not equal job1"); - org.springframework.util.Assert.isNull(readerPropertyName3, "readerPropertyName3 is not null"); - - Properties jobProperties = injectAnnotatedOnlyField.getProperties(); - org.springframework.util.Assert.isTrue(jobProperties.size() == 5, "jobProperties has the wrong number of values. Expected 5, got " + jobProperties.size()); - org.springframework.util.Assert.isTrue(jobProperties.get("jobPropertyName1").equals("jobPropertyValue1"), "The value of jobPropertyName1 does not equal jobPropertyName1"); - org.springframework.util.Assert.isTrue(jobProperties.get("jobPropertyName2").equals("jobPropertyValue2"), "The value of jobPropertyName2 does not equal jobPropertyName2"); - org.springframework.util.Assert.isTrue(jobProperties.get("step2name").equals("step2"), "The value of step2name does note equal step2"); - org.springframework.util.Assert.isTrue(jobProperties.get("filestem").equals("postings"), "The value of filestem does not equal postings"); - org.springframework.util.Assert.isTrue(jobProperties.get("x").equals("xVal"), "The value of x does not equal xVal"); - } - - @Override - public void close() throws Exception { - } - - @Override - public Object readItem() throws Exception { - if (cnt == 0) { - cnt++; - return "blah"; - } - - return null; - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } - - public static final class TestItemProcessor implements ItemProcessor { - @Inject @BatchProperty String processorPropertyName1; - @Inject @BatchProperty String processorPropertyName2; - @Inject @BatchProperty(name = "annotationNamedProcessorPropertyName") String annotationNamedProperty; - @Inject @BatchProperty String notDefinedProperty; - @Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty; - - @Override - public Object processItem(Object o) throws Exception { - org.springframework.util.Assert.isTrue("processorPropertyValue1".equals(processorPropertyName1), "The value of processorPropertyValue1 does not equal processorPropertyValue1"); - org.springframework.util.Assert.isTrue("processorPropertyValue2".equals(processorPropertyName2), "The value of processorPropertyValue2 does not equal processorPropertyValue2"); - org.springframework.util.Assert.isTrue("annotationNamedProcessorPropertyValue".equals(annotationNamedProperty), "The value of annotationNamedProcessorPropertyValue does not equal annotationNamedProcessorPropertyValue"); - org.springframework.util.Assert.isNull(notDefinedProperty, "The notDefinedProperty is not null"); - org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty, "The notDefinedNamedProperty is not null"); - - return o; - } - } - - public static final class TestItemWriter implements ItemWriter { - @Inject @BatchProperty String writerPropertyName1; - @Inject @BatchProperty String writerPropertyName2; - @Inject @BatchProperty(name = "annotationNamedWriterPropertyName") String annotationNamedProperty; - @Inject @BatchProperty String notDefinedProperty; - @Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty; - - @Override - public void open(Serializable serializable) throws Exception { - org.springframework.util.Assert.isTrue("writerPropertyValue1".equals(writerPropertyName1), "The value of writerPropertyValue1 does not equal writerPropertyValue1"); - org.springframework.util.Assert.isTrue("writerPropertyValue2".equals(writerPropertyName2), "The value of writerPropertyValue2 does not equal writerPropertyValue2"); - org.springframework.util.Assert.isTrue("annotationNamedWriterPropertyValue".equals(annotationNamedProperty), "The value of annotationNamedWriterPropertyValue does not equal annotationNamedWriterPropertyValue"); - org.springframework.util.Assert.isNull(notDefinedProperty, "notDefinedProperty is not null"); - org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty, "notDefinedAnnotationNamedProperty is not null"); - } - - @Override - public void close() throws Exception { - } - - @Override - public void writeItems(List objects) throws Exception { - System.out.println(objects); - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } - - public static final class TestCheckpointAlgorithm implements CheckpointAlgorithm { - @Inject @BatchProperty String algorithmPropertyName1; - @Inject @BatchProperty String algorithmPropertyName2; - @Inject @BatchProperty(name = "annotationNamedAlgorithmPropertyName") String annotationNamedProperty; - @Inject @BatchProperty String notDefinedProperty; - @Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty; - - @Override - public int checkpointTimeout() throws Exception { - return 0; - } - - @Override - public void beginCheckpoint() throws Exception { - org.springframework.util.Assert.isTrue("algorithmPropertyValue1".equals(algorithmPropertyName1), "The value of algorithmPropertyValue1 does not equal algorithmPropertyValue1"); - org.springframework.util.Assert.isTrue("algorithmPropertyValue2".equals(algorithmPropertyName2), "The value of algorithmPropertyValue2 does not equal algorithmPropertyValue2"); - org.springframework.util.Assert.isTrue("annotationNamedAlgorithmPropertyValue".equals(annotationNamedProperty), "The annotationNamedAlgorithmPropertyValue does not equal annotationNamedAlgorithmPropertyValue"); - org.springframework.util.Assert.isNull(notDefinedProperty, "notDefinedProperty is not null"); - org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty, "notDefinedAnnotationNamedProperty is not null"); - } - - @Override - public boolean isReadyToCheckpoint() throws Exception { - return true; - } - - @Override - public void endCheckpoint() throws Exception { - } - } - - public static class TestDecider implements Decider { - @Inject @BatchProperty String deciderPropertyName1; - @Inject @BatchProperty String deciderPropertyName2; - @Inject @BatchProperty(name = "annotationNamedDeciderPropertyName") String annotationNamedProperty; - @Inject @BatchProperty String notDefinedProperty; - @Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty; - - @Override - public String decide(jakarta.batch.runtime.StepExecution[] executions) throws Exception { - org.springframework.util.Assert.isTrue("deciderPropertyValue1".equals(deciderPropertyName1), "The value of deciderPropertyValue1 does not equal deciderPropertyValue1"); - org.springframework.util.Assert.isTrue("deciderPropertyValue2".equals(deciderPropertyName2), "The value of deciderPropertyValue2 does not equal deciderPropertyValue2"); - org.springframework.util.Assert.isTrue("annotationNamedDeciderPropertyValue".equals(annotationNamedProperty), "The value of annotationNamedDeciderPropertyValue does not equal annotationNamedDeciderPropertyValue"); - org.springframework.util.Assert.isNull(notDefinedProperty, "notDefinedProperty is not null"); - org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty, "notDefinedAnnotationNamedProperty is not null"); - - return "step2"; - } - } - - public static class TestStepListener implements StepListener { - @Inject @BatchProperty String stepListenerPropertyName1; - @Inject @BatchProperty String stepListenerPropertyName2; - @Inject @BatchProperty(name = "annotationNamedStepListenerPropertyName") String annotationNamedProperty; - @Inject @BatchProperty String notDefinedProperty; - @Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty; - - @Override - public void beforeStep() throws Exception { - org.springframework.util.Assert.isTrue("stepListenerPropertyValue1".equals(stepListenerPropertyName1), "The value of stepListenerPropertyValue1 does not equal stepListenerPropertyValue1"); - org.springframework.util.Assert.isTrue("stepListenerPropertyValue2".equals(stepListenerPropertyName2), "The value of stepListenerPropertyValue2 does not equal stepListenerPropertyValue2"); - org.springframework.util.Assert.isTrue("annotationNamedStepListenerPropertyValue".equals(annotationNamedProperty), "The value of annotationNamedStepListenerPropertyValue does note equal annotationNamedStepListenerPropertyValue"); - org.springframework.util.Assert.isNull(notDefinedProperty, "notDefinedProperty is not null"); - org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty, "notDefinedAnnotationNamedProperty is not null"); - } - - @Override - public void afterStep() throws Exception { - } - } - - public static class TestBatchlet implements Batchlet { - @Inject @BatchProperty String batchletPropertyName1; - @Inject @BatchProperty String batchletPropertyName2; - @Inject @BatchProperty(name = "annotationNamedBatchletPropertyName") String annotationNamedProperty; - @Inject @BatchProperty String notDefinedProperty; - @Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty; - @Inject jakarta.batch.runtime.context.StepContext stepContext; - @Inject @BatchProperty(name = "infile.name") String infile; - @Inject @BatchProperty(name = "y") String y; - @Inject @BatchProperty(name = "x") String x; - - @Override - public String process() throws Exception { - org.springframework.util.Assert.notNull(stepContext, "StepContext is not null"); - org.springframework.util.Assert.isNull(stepContext.getProperties().get("step1PropertyName1"), "The value of step1PropertyName1 is not null"); - org.springframework.util.Assert.isNull(stepContext.getProperties().get("step1PropertyName2"), "The value of step1PropertyName2 is not null"); - org.springframework.util.Assert.isTrue(stepContext.getProperties().get("step2PropertyName1").equals("step2PropertyValue1"), "The value of step2PropertyName1 does not equal step2PropertyName1"); - org.springframework.util.Assert.isTrue(stepContext.getProperties().get("step2PropertyName2").equals("step2PropertyValue2"), "The value of step2PropertyName2 does not equal step2PropertyName2"); - org.springframework.util.Assert.isTrue(stepContext.getProperties().get("jobPropertyName1") == null, "jobPropertyName1 is not null"); - org.springframework.util.Assert.isTrue(stepContext.getProperties().get("jobPropertyName2") == null, "jobPropertyName2 is not null"); - - org.springframework.util.Assert.isTrue("batchletPropertyValue1".equals(batchletPropertyName1), "batchletPropertyValue1 does not equal batchletPropertyValue1"); - org.springframework.util.Assert.isTrue("batchletPropertyValue2".equals(batchletPropertyName2), "batchletPropertyValue2 does not equal batchletPropertyValue2"); - org.springframework.util.Assert.isTrue("annotationNamedBatchletPropertyValue".equals(annotationNamedProperty), "annotationNamedBatchletPropertyValue does not equal annotationNamedBatchletPropertyValue"); - org.springframework.util.Assert.isTrue("postings.txt".equals(infile), "infile does not equal postings.txt"); - org.springframework.util.Assert.isTrue("xVal".equals(y), "y does not equal xVal"); - org.springframework.util.Assert.isNull(notDefinedProperty, "notDefinedProperty is not null"); - org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty, "notDefinedAnnotationNamedProperty is not null"); - org.springframework.util.Assert.isNull(x, "x is not null"); - - return null; - } - - @Override - public void stop() throws Exception { - } - } - - public static class TestTasklet implements Tasklet { - @Inject - @BatchProperty - private String p1; - - @Nullable - @Override - public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { - org.springframework.util.Assert.isTrue("p1val".equals(p1), "Expected p1val, got " + p1); - - return RepeatStatus.FINISHED; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReaderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReaderTests.java deleted file mode 100644 index 54c4e68a5..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReaderTests.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; -import jakarta.batch.api.Batchlet; -import jakarta.batch.runtime.JobExecution; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.w3c.dom.Document; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; - -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.xml.DefaultDocumentLoader; -import org.springframework.beans.factory.xml.DelegatingEntityResolver; -import org.springframework.beans.factory.xml.DocumentLoader; -import org.springframework.core.io.ClassPathResource; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.SimpleSaxErrorHandler; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - *

- * Test cases around {@link JsrBeanDefinitionDocumentReader}. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - */ -public class JsrBeanDefinitionDocumentReaderTests extends AbstractJsrTestCase { - private static final String JOB_PARAMETERS_BEAN_DEFINITION_NAME = "jsr_jobParameters"; - - private Log logger = LogFactory.getLog(getClass()); - private DocumentLoader documentLoader = new DefaultDocumentLoader(); - private ErrorHandler errorHandler = new SimpleSaxErrorHandler(logger); - - @Test - @SuppressWarnings("resource") - public void testGetJobParameters() { - Properties jobParameters = new Properties(); - jobParameters.setProperty("jobParameter1", "jobParameter1Value"); - jobParameters.setProperty("jobParameter2", "jobParameter2Value"); - - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters); - applicationContext.setValidating(false); - applicationContext.load(new ClassPathResource("jsrBaseContext.xml"), - new ClassPathResource("/META-INF/batch.xml"), - new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml")); - applicationContext.refresh(); - - BeanDefinition beanDefinition = applicationContext.getBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME); - - Properties processedJobParameters = (Properties) beanDefinition.getConstructorArgumentValues().getGenericArgumentValue(Properties.class).getValue(); - assertNotNull(processedJobParameters); - assertTrue("Wrong number of job parameters", processedJobParameters.size() == 2); - assertEquals("jobParameter1Value", processedJobParameters.getProperty("jobParameter1")); - assertEquals("jobParameter2Value", processedJobParameters.getProperty("jobParameter2")); - } - - @Test - public void testGetJobProperties() { - Document document = getDocument("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"); - - @SuppressWarnings("resource") - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(); - JsrBeanDefinitionDocumentReader documentReader = new JsrBeanDefinitionDocumentReader(applicationContext); - documentReader.initProperties(document.getDocumentElement()); - - Properties documentJobProperties = documentReader.getJobProperties(); - assertNotNull(documentJobProperties); - assertTrue("Wrong number of job properties", documentJobProperties.size() == 3); - assertEquals("jobProperty1Value", documentJobProperties.getProperty("jobProperty1")); - assertEquals("jobProperty1Value", documentJobProperties.getProperty("jobProperty2")); - assertEquals("", documentJobProperties.getProperty("jobProperty3")); - } - - @Test - public void testJobParametersResolution() { - Properties jobParameters = new Properties(); - jobParameters.setProperty("jobParameter1", "myfile.txt"); - jobParameters.setProperty("jobParameter2", "#{jobProperties['jobProperty2']}"); - jobParameters.setProperty("jobParameter3", "#{jobParameters['jobParameter1']}"); - - @SuppressWarnings("resource") - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters); - applicationContext.setValidating(false); - applicationContext.load(new ClassPathResource("jsrBaseContext.xml"), - new ClassPathResource("/META-INF/batch.xml"), - new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml")); - applicationContext.refresh(); - - Document document = getDocument("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"); - - JsrBeanDefinitionDocumentReader documentReader = new JsrBeanDefinitionDocumentReader(applicationContext); - documentReader.initProperties(document.getDocumentElement()); - - Properties resolvedParameters = documentReader.getJobParameters(); - - assertNotNull(resolvedParameters); - assertTrue("Wrong number of job parameters", resolvedParameters.size() == 3); - assertEquals("myfile.txt", resolvedParameters.getProperty("jobParameter1")); - assertEquals("jobProperty1Value", resolvedParameters.getProperty("jobParameter2")); - assertEquals("myfile.txt", resolvedParameters.getProperty("jobParameter3")); - } - - @Test - public void testJobPropertyResolution() { - Properties jobParameters = new Properties(); - jobParameters.setProperty("file.name", "myfile.txt"); - - @SuppressWarnings("resource") - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters); - applicationContext.setValidating(false); - applicationContext.load(new ClassPathResource("jsrBaseContext.xml"), - new ClassPathResource("/META-INF/batch.xml"), - new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml")); - applicationContext.refresh(); - - Document document = getDocument("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"); - - JsrBeanDefinitionDocumentReader documentReader = new JsrBeanDefinitionDocumentReader(applicationContext); - documentReader.initProperties(document.getDocumentElement()); - - Properties resolvedProperties = documentReader.getJobProperties(); - assertNotNull(resolvedProperties); - assertTrue("Wrong number of job properties", resolvedProperties.size() == 3); - assertEquals("jobProperty1Value", resolvedProperties.getProperty("jobProperty1")); - assertEquals("jobProperty1Value", resolvedProperties.getProperty("jobProperty2")); - assertEquals("myfile.txt", resolvedProperties.getProperty("jobProperty3")); - } - - @SuppressWarnings("resource") - @Test - public void testGenerationOfBeanDefinitionsForMultipleReferences() throws Exception { - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(new Properties()); - applicationContext.setValidating(false); - applicationContext.load(new ClassPathResource("jsrBaseContext.xml"), - new ClassPathResource("/META-INF/batch.xml"), - new ClassPathResource("/META-INF/batch-jobs/jsrUniqueInstanceTests.xml")); - applicationContext.refresh(); - - assertTrue("exitStatusSettingStepListener bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener")); - assertTrue("exitStatusSettingStepListener1 bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener1")); - assertTrue("exitStatusSettingStepListener2 bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener2")); - assertTrue("exitStatusSettingStepListener3 bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener3")); - assertTrue("exitStatusSettingStepListenerClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener")); - assertTrue("exitStatusSettingStepListener1ClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener1")); - assertTrue("exitStatusSettingStepListener2ClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener2")); - assertTrue("exitStatusSettingStepListener3ClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener3")); - assertTrue("testBatchlet bean definition not found", applicationContext.containsBeanDefinition("testBatchlet")); - assertTrue("testBatchlet1 bean definition not found", applicationContext.containsBeanDefinition("testBatchlet1")); - } - - @Test - public void testArtifactUniqueness() throws Exception { - JobExecution jobExecution = runJob("jsrUniqueInstanceTests", new Properties(), 10000L); - String exitStatus = jobExecution.getExitStatus(); - - assertTrue("Exit status must contain listener3", exitStatus.contains("listener3")); - exitStatus = exitStatus.replace("listener3", ""); - - assertTrue("Exit status must contain listener2", exitStatus.contains("listener2")); - exitStatus = exitStatus.replace("listener2", ""); - - assertTrue("Exit status must contain listener1", exitStatus.contains("listener1")); - exitStatus = exitStatus.replace("listener1", ""); - - assertTrue("Exit status must contain listener0", exitStatus.contains("listener0")); - exitStatus = exitStatus.replace("listener0", ""); - - assertTrue("Exit status must contain listener7", exitStatus.contains("listener7")); - exitStatus = exitStatus.replace("listener7", ""); - - assertTrue("Exit status must contain listener6", exitStatus.contains("listener6")); - exitStatus = exitStatus.replace("listener6", ""); - - assertTrue("Exit status must contain listener5", exitStatus.contains("listener5")); - exitStatus = exitStatus.replace("listener5", ""); - - assertTrue("Exit status must contain listener4", exitStatus.contains("listener4")); - exitStatus = exitStatus.replace("listener4", ""); - - assertTrue("exitStatus must be empty", "".equals(exitStatus)); - } - - @Test - @SuppressWarnings("resource") - public void testGenerationOfSpringBeanDefinitionsForMultipleReferences() { - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(new Properties()); - applicationContext.setValidating(false); - applicationContext.load(new ClassPathResource("jsrBaseContext.xml"), - new ClassPathResource("/META-INF/batch-jobs/jsrSpringInstanceTests.xml")); - - applicationContext.refresh(); - - assertTrue("exitStatusSettingStepListener bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener")); - assertTrue("scopedTarget.exitStatusSettingStepListener bean definition not found", applicationContext.containsBeanDefinition("scopedTarget.exitStatusSettingStepListener")); - - BeanDefinition exitStatusSettingStepListenerBeanDefinition = applicationContext.getBeanDefinition("scopedTarget.exitStatusSettingStepListener"); - assertTrue("step".equals(exitStatusSettingStepListenerBeanDefinition.getScope())); - - assertTrue("Should not contain bean definition for exitStatusSettingStepListener1", !applicationContext.containsBeanDefinition("exitStatusSettingStepListener1")); - assertTrue("Should not contain bean definition for exitStatusSettingStepListener2", !applicationContext.containsBeanDefinition("exitStatusSettingStepListener2")); - assertTrue("Should not contain bean definition for exitStatusSettingStepListener3", !applicationContext.containsBeanDefinition("exitStatusSettingStepListener3")); - - assertTrue("Should not contain bean definition for testBatchlet1", !applicationContext.containsBeanDefinition("testBatchlet1")); - assertTrue("Should not contain bean definition for testBatchlet2", !applicationContext.containsBeanDefinition("testBatchlet2")); - - assertTrue("testBatchlet bean definition not found", applicationContext.containsBeanDefinition("testBatchlet")); - - BeanDefinition testBatchletBeanDefinition = applicationContext.getBeanDefinition("testBatchlet"); - assertTrue("singleton".equals(testBatchletBeanDefinition.getScope())); - } - - @Test - public void testSpringArtifactUniqueness() throws Exception { - JobExecution jobExecution = runJob("jsrSpringInstanceTests", new Properties(), 10000L); - String exitStatus = jobExecution.getExitStatus(); - - assertTrue("Exit status must contain listener1", exitStatus.contains("listener1")); - assertTrue("exitStatus must contain 2 listener1 values", StringUtils.countOccurrencesOf(exitStatus, "listener1") == 2); - - exitStatus = exitStatus.replace("listener1", ""); - - assertTrue("Exit status must contain listener4", exitStatus.contains("listener4")); - assertTrue("exitStatus must contain 2 listener4 values", StringUtils.countOccurrencesOf(exitStatus, "listener4") == 2); - exitStatus = exitStatus.replace("listener4", ""); - - assertTrue("exitStatus must be empty", "".equals(exitStatus)); - } - - private Document getDocument(String location) { - InputStream inputStream = this.getClass().getResourceAsStream(location); - - try { - return documentLoader.loadDocument(new InputSource(inputStream), - new DelegatingEntityResolver(getClass().getClassLoader()), errorHandler, 0, true); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - try { - inputStream.close(); - } catch (IOException e) { } - } - } - - public static class TestBatchlet implements Batchlet { - @Override - public String process() throws Exception { - return null; - } - - @Override - public void stop() throws Exception { - - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParsingTests.java deleted file mode 100644 index bb3804433..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParsingTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; - -import jakarta.batch.api.Decider; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class JsrDecisionParsingTests { - - @Autowired - public Job job; - - @Autowired - public JobLauncher jobLauncher; - - @Test - public void test() throws Exception { - JobExecution execution = jobLauncher.run(job, new JobParameters()); - assertEquals(BatchStatus.COMPLETED, execution.getStatus()); - assertEquals(3, execution.getStepExecutions().size()); - } - - public static class JsrDecider implements Decider { - - @Override - public String decide(jakarta.batch.runtime.StepExecution[] executions) - throws Exception { - return "next"; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrSplitParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrSplitParsingTests.java deleted file mode 100644 index 436148b02..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrSplitParsingTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import org.junit.Assert; -import org.junit.Test; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.core.task.SimpleAsyncTaskExecutor; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -public class JsrSplitParsingTests extends AbstractJsrTestCase { - - @Test - public void testOneFlowInSplit() { - try { - new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/invalid-split-context.xml"); - } catch (BeanDefinitionParsingException bdpe) { - assertTrue(bdpe.getMessage().contains("A must contain at least two 'flow' elements.")); - return; - } - - fail("Expected exception was not thrown"); - } - - @Test - public void testUserSpecifiedTaskExecutor() { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/user-specified-split-task-executor-context.xml"); - BeanDefinitionRegistry registry = (BeanDefinitionRegistry) context.getBeanFactory(); - PropertyValue propertyValue = new JsrSplitParser(null).getSplitTaskExecutorPropertyValue(registry); - - RuntimeBeanReference runtimeBeanReferenceValue = (RuntimeBeanReference) propertyValue.getValue(); - - Assert.assertTrue("RuntimeBeanReference should have a name of jsr352splitTaskExecutor" , "jsr352splitTaskExecutor".equals(runtimeBeanReferenceValue.getBeanName())); - context.close(); - } - - @Test - public void testDefaultTaskExecutor() { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/default-split-task-executor-context.xml"); - BeanDefinitionRegistry registry = (BeanDefinitionRegistry) context.getBeanFactory(); - PropertyValue propertyValue = new JsrSplitParser(null).getSplitTaskExecutorPropertyValue(registry); - Assert.assertTrue("Task executor not an instance of SimpleAsyncTaskExecutor" , (propertyValue.getValue() instanceof SimpleAsyncTaskExecutor)); - context.close(); - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrXmlApplicationContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrXmlApplicationContextTests.java deleted file mode 100644 index e6770c050..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrXmlApplicationContextTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.Properties; - -import org.junit.Test; -import org.springframework.beans.factory.config.BeanDefinition; - -/** - *

- * Test cases around {@link JsrXmlApplicationContext}. - *

- * - * @author Chris Schaefer - */ -public class JsrXmlApplicationContextTests { - private static final String JOB_PARAMETERS_BEAN_DEFINITION_NAME = "jsr_jobParameters"; - - @Test - @SuppressWarnings("resource") - public void testNullProperties() { - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(null); - - BeanDefinition beanDefinition = applicationContext.getBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME); - Properties properties = (Properties) beanDefinition.getConstructorArgumentValues().getGenericArgumentValue(Properties.class).getValue(); - - assertNotNull("Properties should not be null", properties); - assertTrue("Properties should be empty", properties.isEmpty()); - } - - @Test - @SuppressWarnings("resource") - public void testWithProperties() { - Properties properties = new Properties(); - properties.put("prop1key", "prop1val"); - - JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(properties); - - BeanDefinition beanDefinition = applicationContext.getBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME); - Properties storedProperties = (Properties) beanDefinition.getConstructorArgumentValues().getGenericArgumentValue(Properties.class).getValue(); - - assertNotNull("Properties should not be null", storedProperties); - assertFalse("Properties not be empty", storedProperties.isEmpty()); - assertEquals("prop1val", storedProperties.getProperty("prop1key")); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ListenerParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ListenerParserTests.java deleted file mode 100644 index 331a4cd02..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ListenerParserTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2014 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.jsr.configuration.xml; - -import org.junit.Test; -import org.springframework.batch.core.listener.StepListenerFactoryBean; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.context.support.GenericApplicationContext; -import static org.junit.Assert.assertEquals; - -/** - *

- * Test cases around scoping of job/step listeners when building their bean definitions. - *

- * - * @author Chris Schaefer - */ -public class ListenerParserTests { - @Test - public void testStepListenerStepScoped() { - @SuppressWarnings("resource") - GenericApplicationContext applicationContext = new GenericApplicationContext(); - - AbstractBeanDefinition newBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition("stepListener").getBeanDefinition(); - newBeanDefinition.setScope("step"); - - applicationContext.registerBeanDefinition("stepListener", newBeanDefinition); - - ListenerParser listenerParser = new ListenerParser(StepListenerFactoryBean.class, "listeners"); - listenerParser.applyListenerScope("stepListener", applicationContext); - - BeanDefinition beanDefinition = applicationContext.getBeanDefinition("stepListener"); - assertEquals("step", beanDefinition.getScope()); - } - - @Test - public void testJobListenerSingletonScoped() { - @SuppressWarnings("resource") - GenericApplicationContext applicationContext = new GenericApplicationContext(); - - AbstractBeanDefinition newBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition("jobListener").getBeanDefinition(); - newBeanDefinition.setScope("step"); - - applicationContext.registerBeanDefinition("jobListener", newBeanDefinition); - - ListenerParser listenerParser = new ListenerParser(JsrJobListenerFactoryBean.class, "jobExecutionListeners"); - listenerParser.applyListenerScope("jobListener", applicationContext); - - BeanDefinition beanDefinition = applicationContext.getBeanDefinition("jobListener"); - assertEquals("job", beanDefinition.getScope()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParserTests.java deleted file mode 100644 index 5ccdfab6e..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParserTests.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import jakarta.batch.api.BatchProperty; -import jakarta.batch.api.Batchlet; -import jakarta.batch.api.chunk.AbstractItemReader; -import jakarta.batch.api.chunk.AbstractItemWriter; -import jakarta.batch.api.partition.PartitionPlan; -import jakarta.batch.api.partition.PartitionPlanImpl; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.context.JobContext; -import jakarta.batch.runtime.context.StepContext; -import jakarta.inject.Inject; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.util.Assert; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class PartitionParserTests extends AbstractJsrTestCase { - private Pattern caPattern = Pattern.compile("ca"); - private Pattern asPattern = Pattern.compile("AS"); - private static final long TIMEOUT = 10000L; - - @Before - public void before() { - MyBatchlet.processed = new AtomicInteger(0); - MyBatchlet.threadNames = Collections.synchronizedSet(new HashSet<>()); - MyBatchlet.artifactNames = Collections.synchronizedSet(new HashSet<>()); - PartitionCollector.artifactNames = Collections.synchronizedSet(new HashSet<>()); - } - - @Test - public void testBatchletNoProperties() throws Exception { - BatchStatus curBatchStatus = runJob("partitionParserTestsBatchlet", new Properties(), TIMEOUT).getBatchStatus(); - - assertEquals(BatchStatus.COMPLETED, curBatchStatus); - assertEquals(10, MyBatchlet.processed.get()); - assertEquals(10, MyBatchlet.threadNames.size()); - } - - @Test - public void testChunkNoProperties() throws Exception { - JobExecution execution = runJob("partitionParserTestsChunk", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - assertEquals(30, ItemReader.processedItems.size()); - assertEquals(10, ItemReader.threadNames.size()); - assertEquals(30, ItemWriter.processedItems.size()); - assertEquals(10, ItemWriter.threadNames.size()); - } - - @Test - public void testFullPartitionConfiguration() throws Exception { - JobExecution execution = runJob("fullPartitionParserTests", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - assertTrue(execution.getExitStatus().startsWith("BPS_")); - assertTrue(execution.getExitStatus().endsWith("BPSC_APSC")); - assertEquals(3, countMatches(execution.getExitStatus(), caPattern)); - assertEquals(3, countMatches(execution.getExitStatus(), asPattern)); - assertEquals(3, MyBatchlet.processed.get()); - assertEquals(3, MyBatchlet.threadNames.size()); - } - - @Test - public void testFullPartitionConfigurationWithProperties() throws Exception { - JobExecution execution = runJob("fullPartitionParserWithPropertiesTests", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - assertTrue(execution.getExitStatus().startsWith("BPS_")); - assertTrue(execution.getExitStatus().endsWith("BPSC_APSC")); - assertEquals(3, countMatches(execution.getExitStatus(), caPattern)); - assertEquals(3, countMatches(execution.getExitStatus(), asPattern)); - assertEquals(3, MyBatchlet.processed.get()); - assertEquals(3, MyBatchlet.threadNames.size()); - assertEquals(MyBatchlet.artifactNames.iterator().next(), "batchlet"); - assertEquals(PartitionMapper.name, "mapper"); - assertEquals(PartitionAnalyzer.name, "analyzer"); - assertEquals(PartitionReducer.name, "reducer"); - assertEquals(PartitionCollector.artifactNames.size(), 1); - assertTrue(PartitionCollector.artifactNames.contains("collector")); - } - - @Test - public void testFullPartitionConfigurationWithMapperSuppliedProperties() throws Exception { - JobExecution execution = runJob("fullPartitionParserWithMapperPropertiesTests", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - assertTrue(execution.getExitStatus().startsWith("BPS_")); - assertTrue(execution.getExitStatus().endsWith("BPSC_APSC")); - assertEquals(3, countMatches(execution.getExitStatus(), caPattern)); - assertEquals(3, countMatches(execution.getExitStatus(), asPattern)); - assertEquals(3, MyBatchlet.processed.get()); - assertEquals(3, MyBatchlet.threadNames.size()); - - assertEquals(MyBatchlet.artifactNames.size(), 3); - assertTrue(MyBatchlet.artifactNames.contains("batchlet0")); - assertTrue(MyBatchlet.artifactNames.contains("batchlet1")); - assertTrue(MyBatchlet.artifactNames.contains("batchlet2")); - assertEquals(PartitionCollector.artifactNames.size(), 3); - assertTrue(PartitionCollector.artifactNames.contains("collector0")); - assertTrue(PartitionCollector.artifactNames.contains("collector1")); - assertTrue(PartitionCollector.artifactNames.contains("collector2")); - - assertEquals(PartitionAnalyzer.name, "analyzer"); - assertEquals(PartitionReducer.name, "reducer"); - } - - @Test - public void testFullPartitionConfigurationWithHardcodedProperties() throws Exception { - JobExecution execution = runJob("fullPartitionParserWithHardcodedPropertiesTests", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - assertTrue(execution.getExitStatus().startsWith("BPS_")); - assertTrue(execution.getExitStatus().endsWith("BPSC_APSC")); - assertEquals(3, countMatches(execution.getExitStatus(), caPattern)); - assertEquals(3, countMatches(execution.getExitStatus(), asPattern)); - assertEquals(3, MyBatchlet.processed.get()); - assertEquals(3, MyBatchlet.threadNames.size()); - - assertEquals(MyBatchlet.artifactNames.size(), 3); - assertTrue(MyBatchlet.artifactNames.contains("batchlet0")); - assertTrue(MyBatchlet.artifactNames.contains("batchlet1")); - assertTrue(MyBatchlet.artifactNames.contains("batchlet2")); - assertEquals(PartitionCollector.artifactNames.size(), 3); - assertTrue(PartitionCollector.artifactNames.contains("collector0")); - assertTrue(PartitionCollector.artifactNames.contains("collector1")); - assertTrue(PartitionCollector.artifactNames.contains("collector2")); - - assertEquals(PartitionMapper.name, "mapper"); - assertEquals(PartitionAnalyzer.name, "analyzer"); - assertEquals(PartitionReducer.name, "reducer"); - } - - private int countMatches(String string, Pattern pattern) { - Matcher matcher = pattern.matcher(string); - - int count = 0; - while(matcher.find()) { - count++; - } - - return count; - } - - public static class PartitionReducer implements jakarta.batch.api.partition.PartitionReducer { - - public static String name; - - @Inject - @BatchProperty - String artifactName; - - @Inject - protected JobContext jobContext; - - @Override - public void beginPartitionedStep() throws Exception { - name = artifactName; - jobContext.setExitStatus("BPS_"); - } - - @Override - public void beforePartitionedStepCompletion() throws Exception { - jobContext.setExitStatus(jobContext.getExitStatus() + "BPSC_"); - } - - @Override - public void rollbackPartitionedStep() throws Exception { - jobContext.setExitStatus(jobContext.getExitStatus() + "RPS"); - } - - @Override - public void afterPartitionedStepCompletion(PartitionStatus status) - throws Exception { - jobContext.setExitStatus(jobContext.getExitStatus() + "APSC"); - } - } - - public static class PartitionAnalyzer implements jakarta.batch.api.partition.PartitionAnalyzer { - - public static String name; - - @Inject - @BatchProperty - String artifactName; - - @Inject - protected JobContext jobContext; - - @Override - public void analyzeCollectorData(Serializable data) throws Exception { - name = artifactName; - - Assert.isTrue(data.equals("c"), "Expected c but was " + data); - jobContext.setExitStatus(jobContext.getExitStatus() + data + "a"); - } - - @Override - public void analyzeStatus(BatchStatus batchStatus, String exitStatus) - throws Exception { - Assert.isTrue(batchStatus.equals(BatchStatus.COMPLETED), String.format("expected %s but received %s", BatchStatus.COMPLETED, batchStatus)); - jobContext.setExitStatus(jobContext.getExitStatus() + "AS"); - } - } - - public static class PartitionCollector implements jakarta.batch.api.partition.PartitionCollector { - - protected static Set artifactNames = Collections.synchronizedSet(new HashSet<>()); - - @Inject - @BatchProperty - String artifactName; - - @Override - public Serializable collectPartitionData() throws Exception { - artifactNames.add(artifactName); - return "c"; - } - } - - public static class PropertyPartitionMapper implements jakarta.batch.api.partition.PartitionMapper { - - @Override - public PartitionPlan mapPartitions() throws Exception { - Properties[] props = new Properties[3]; - - for(int i = 0; i < props.length; i++) { - props[i] = new Properties(); - props[i].put("collectorName", "collector" + i); - props[i].put("batchletName", "batchlet" + i); - } - - PartitionPlan plan = new PartitionPlanImpl(); - plan.setPartitions(3); - plan.setThreads(3); - plan.setPartitionProperties(props); - - return plan; - } - } - - public static class PartitionMapper implements jakarta.batch.api.partition.PartitionMapper { - - public static String name; - - @Inject - @BatchProperty - public String artifactName; - - @Override - public PartitionPlan mapPartitions() throws Exception { - name = artifactName; - - PartitionPlan plan = new PartitionPlanImpl(); - plan.setPartitions(3); - plan.setThreads(3); - - return plan; - } - } - - public static class MyBatchlet implements Batchlet { - - protected static AtomicInteger processed = new AtomicInteger(0);; - protected static Set threadNames = Collections.synchronizedSet(new HashSet<>()); - protected static Set artifactNames = Collections.synchronizedSet(new HashSet<>()); - - @Inject - @BatchProperty - String artifactName; - - @Inject - StepContext stepContext; - - @Inject - JobContext jobContext; - - @Override - public String process() throws Exception { - artifactNames.add(artifactName); - threadNames.add(Thread.currentThread().getName()); - processed.incrementAndGet(); - - stepContext.setExitStatus("bad step exit status"); - jobContext.setExitStatus("bad job exit status"); - - return null; - } - - @Override - public void stop() throws Exception { - } - } - - public static class ItemReader extends AbstractItemReader { - - private List items; - protected static Vector processedItems = new Vector<>(); - protected static Set threadNames = Collections.synchronizedSet(new HashSet<>()); - - @Override - public void open(Serializable checkpoint) throws Exception { - items = new ArrayList<>(); - items.add(1); - items.add(2); - items.add(3); - } - - @Override - public Object readItem() throws Exception { - threadNames.add(Thread.currentThread().getName()); - if(items.size() > 0) { - Integer curItem = items.remove(0); - processedItems.add(curItem); - return curItem; - } else { - return null; - } - } - } - - public static class ItemWriter extends AbstractItemWriter { - - protected static Vector processedItems = new Vector<>(); - protected static Set threadNames = Collections.synchronizedSet(new HashSet<>()); - - @Override - public void writeItems(List items) throws Exception { - threadNames.add(Thread.currentThread().getName()); - for (Object object : items) { - processedItems.add((Integer) object); - } - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/RetryListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/RetryListenerTests.java deleted file mode 100644 index 685696cac..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/RetryListenerTests.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import java.io.Serializable; -import java.util.Collection; -import java.util.List; -import jakarta.batch.api.chunk.ItemProcessor; -import jakarta.batch.api.chunk.ItemReader; -import jakarta.batch.api.chunk.ItemWriter; -import jakarta.batch.api.chunk.listener.RetryProcessListener; -import jakarta.batch.api.chunk.listener.RetryReadListener; -import jakarta.batch.api.chunk.listener.RetryWriteListener; -import jakarta.batch.operations.BatchRuntimeException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.retry.RetryException; -import org.springframework.util.Assert; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - *

- * Test cases around JSR-352 retry listeners. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class RetryListenerTests { - private static final Log LOG = LogFactory.getLog(RetryListenerTests.class); - - @Test - @SuppressWarnings("resource") - public void testReadRetryExhausted() throws Exception { - ApplicationContext context = new ClassPathXmlApplicationContext("org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerExhausted.xml"); - - JobLauncher jobLauncher = context.getBean(JobLauncher.class); - JobExecution jobExecution = jobLauncher.run(context.getBean(Job.class), new JobParameters()); - - List failureExceptions = jobExecution.getAllFailureExceptions(); - assertTrue("Expected 1 failure exceptions", failureExceptions.size() == 1); - assertTrue("Failure exception must be of type RetryException", (failureExceptions.get(0) instanceof RetryException)); - assertTrue("Exception cause must be of type IllegalArgumentException", (failureExceptions.get(0).getCause() instanceof IllegalArgumentException)); - - assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus()); - } - - @Test - @SuppressWarnings("resource") - public void testReadRetryOnce() throws Exception { - ApplicationContext context = new ClassPathXmlApplicationContext("org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerRetryOnce.xml"); - - JobLauncher jobLauncher = context.getBean(JobLauncher.class); - JobExecution jobExecution = jobLauncher.run(context.getBean(Job.class), new JobParameters()); - - Collection stepExecutions = jobExecution.getStepExecutions(); - assertEquals(1, stepExecutions.size()); - - StepExecution stepExecution = stepExecutions.iterator().next(); - assertEquals(1, stepExecution.getCommitCount()); - assertEquals(2, stepExecution.getReadCount()); - - assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); - } - - @Test - @SuppressWarnings("resource") - public void testReadRetryExceptionInListener() throws Exception { - ApplicationContext context = new ClassPathXmlApplicationContext("org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerListenerException.xml"); - - JobLauncher jobLauncher = context.getBean(JobLauncher.class); - JobExecution jobExecution = jobLauncher.run(context.getBean(Job.class), new JobParameters()); - - List failureExceptions = jobExecution.getAllFailureExceptions(); - assertTrue("Failure exceptions must equal one", failureExceptions.size() == 1); - assertTrue("Failure exception must be of type RetryException", (failureExceptions.get(0) instanceof RetryException)); - assertTrue("Exception cause must be of type BatchRuntimeException", (failureExceptions.get(0).getCause() instanceof BatchRuntimeException)); - - assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus()); - } - - public static class ExceptionThrowingRetryReadListener implements RetryReadListener { - @Override - public void onRetryReadException(Exception ex) throws Exception { - Assert.isInstanceOf(IllegalArgumentException.class, ex); - throw new IllegalStateException(); - } - } - - public static class TestRetryReadListener implements RetryReadListener { - @Override - public void onRetryReadException(Exception ex) throws Exception { - Assert.isInstanceOf(IllegalArgumentException.class, ex); - } - } - - public static class TestRetryProcessListener implements RetryProcessListener { - @Override - public void onRetryProcessException(Object item, Exception ex) throws Exception { - Assert.isInstanceOf(String.class, item); - - String currentItem = (String) item; - - Assert.isTrue("three".equals(currentItem), "currentItem was expected to be three but was not " + currentItem); - Assert.isInstanceOf(IllegalArgumentException.class, ex); - } - } - - public static class TestRetryWriteListener implements RetryWriteListener { - @Override - public void onRetryWriteException(List items, Exception ex) throws Exception { - Assert.isTrue(items.size() == 2, "Must be two items to write"); - Assert.isTrue(items.contains("three"), "Items must contain the string 'three'"); - Assert.isTrue(items.contains("one"), "Items must contain the string 'one'"); - Assert.isInstanceOf(IllegalArgumentException.class, ex); - } - } - - public static class AlwaysFailItemReader implements ItemReader { - @Override - public void open(Serializable checkpoint) throws Exception { - } - - @Override - public void close() throws Exception { - } - - @Override - public Object readItem() throws Exception { - throw new IllegalArgumentException(); - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } - - public static class FailOnceItemReader implements ItemReader { - private int cnt; - - @Override - public void open(Serializable checkpoint) throws Exception { - } - - @Override - public void close() throws Exception { - } - - @Override - public Object readItem() throws Exception { - if(cnt == 0) { - cnt++; - return "one"; - } else if (cnt == 1) { - cnt++; - throw new IllegalArgumentException(); - } else if (cnt == 2) { - cnt++; - return "three"; - } - - return null; - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } - - public static class FailOnceItemProcessor implements ItemProcessor { - private int cnt; - - @Override - public Object processItem(Object item) throws Exception { - if(cnt == 0) { - cnt++; - return "one"; - } else if (cnt == 1) { - cnt++; - throw new IllegalArgumentException(); - } else if (cnt == 2) { - cnt++; - return "three"; - } - - return null; - } - } - - public static class FailOnceItemWriter implements ItemWriter { - private int cnt; - - @Override - public void open(Serializable checkpoint) throws Exception { - } - - @Override - public void close() throws Exception { - } - - @Override - public void writeItems(List items) throws Exception { - for(@SuppressWarnings("unused") Object item : items) { - if(cnt == 0) { - cnt++; - LOG.info("one"); - } else if (cnt == 1) { - cnt++; - throw new IllegalArgumentException(); - } else if (cnt == 2) { - cnt++; - LOG.info("three"); - } - } - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/SimpleItemBasedJobParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/SimpleItemBasedJobParsingTests.java deleted file mode 100644 index b81a04e5b..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/SimpleItemBasedJobParsingTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; - -import java.io.Serializable; -import java.util.List; - -import jakarta.batch.api.chunk.CheckpointAlgorithm; -import jakarta.batch.api.chunk.ItemWriter; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class SimpleItemBasedJobParsingTests { - - @Autowired - public Job job; - - @Autowired - public Step step1; - - @Autowired - public CountingItemProcessor processor; - - @Autowired - public CountingCompletionPolicy policy; - - @Autowired - public CountingItemWriter writer; - - @Autowired - public JobLauncher jobLauncher; - - @Test - public void test() throws Exception { - JobExecution execution = jobLauncher.run(job, new JobParameters()); - assertEquals(BatchStatus.COMPLETED, execution.getStatus()); - assertEquals(4, execution.getStepExecutions().size()); - assertEquals(27, processor.count); - assertEquals(1, policy.checkpointCount); - assertEquals(7, writer.writeCount); - assertEquals(27, writer.itemCount); - } - - public static class CountingItemWriter implements ItemWriter { - - protected int writeCount = 0; - protected int itemCount = 0; - - @Override - public void open(Serializable checkpoint) throws Exception { - } - - @Override - public void close() throws Exception { - } - - @Override - public void writeItems(List items) throws Exception { - System.err.println("Items to be written: " + items); - writeCount++; - itemCount += items.size(); - } - - @Override - public Serializable checkpointInfo() throws Exception { - return null; - } - } - - public static class CountingCompletionPolicy implements CheckpointAlgorithm { - - protected int itemCount = 0; - protected int checkpointCount = 0; - - @Override - public int checkpointTimeout() throws Exception { - return 0; - } - - @Override - public void beginCheckpoint() throws Exception { - } - - @Override - public boolean isReadyToCheckpoint() throws Exception { - itemCount++; - return itemCount % 3 == 0; - } - - @Override - public void endCheckpoint() throws Exception { - checkpointCount++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/SimpleJobParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/SimpleJobParsingTests.java deleted file mode 100644 index 7e598e1e5..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/SimpleJobParsingTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import jakarta.batch.api.Batchlet; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class SimpleJobParsingTests { - - @Autowired - public Job job; - - @Autowired - @Qualifier("step1") - public Step step1; - - @Autowired - @Qualifier("step2") - public Step step2; - - @Autowired - @Qualifier("step3") - public Step step3; - - @Autowired - public JobLauncher jobLauncher; - - @Autowired - public Batchlet batchlet; - - @Test - public void test() throws Exception { - assertNotNull(job); - assertEquals("job1", job.getName()); - assertNotNull(step1); - assertEquals("step1", step1.getName()); - assertNotNull(step2); - assertEquals("step2", step2.getName()); - assertNotNull(step3); - assertEquals("step3", step3.getName()); - assertNotNull(batchlet); - - JobExecution execution = jobLauncher.run(job, new JobParameters()); - assertEquals(BatchStatus.COMPLETED, execution.getStatus()); - assertEquals(3, execution.getStepExecutions().size()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/StepListenerParsingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/StepListenerParsingTests.java deleted file mode 100644 index 9aefe8a33..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/StepListenerParsingTests.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import static org.junit.Assert.assertEquals; - -import jakarta.batch.api.listener.StepListener; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.StepExecutionListener; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.lang.Nullable; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class StepListenerParsingTests { - - @Autowired - public Job job; - - @Autowired - public JobLauncher jobLauncher; - - @Autowired - public SpringStepListener springStepListener; - - @Autowired - public JsrStepListener jsrStepListener; - - @Test - public void test() throws Exception { - JobExecution execution = jobLauncher.run(job, new JobParameters()); - assertEquals(BatchStatus.COMPLETED, execution.getStatus()); - assertEquals(3, execution.getStepExecutions().size()); - assertEquals(2, springStepListener.countBeforeStep); - assertEquals(2, springStepListener.countAfterStep); - assertEquals(2, jsrStepListener.countBeforeStep); - assertEquals(2, jsrStepListener.countAfterStep); - } - - public static class SpringStepListener implements StepExecutionListener { - protected int countBeforeStep = 0; - protected int countAfterStep = 0; - - @Override - public void beforeStep(StepExecution stepExecution) { - countBeforeStep++; - } - - @Nullable - @Override - public ExitStatus afterStep(StepExecution stepExecution) { - countAfterStep++; - return null; - } - } - - public static class JsrStepListener implements StepListener { - protected int countBeforeStep = 0; - protected int countAfterStep = 0; - - @Override - public void beforeStep() throws Exception { - countBeforeStep++; - } - - @Override - public void afterStep() throws Exception { - countAfterStep++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ThreadLocalClassloaderBeanPostProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ThreadLocalClassloaderBeanPostProcessorTests.java deleted file mode 100644 index 2f2d01c9a..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ThreadLocalClassloaderBeanPostProcessorTests.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import org.junit.Test; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; - -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; - -import static org.junit.Assert.assertEquals; - -public class ThreadLocalClassloaderBeanPostProcessorTests extends AbstractJsrTestCase { - - @Test - public void test() throws Exception { - JobExecution execution = runJob("threadLocalClassloaderBeanPostProcessorTestsJob", null, 10000); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ThreadLocalClassloaderBeanPostProcessorTestsBatchlet.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ThreadLocalClassloaderBeanPostProcessorTestsBatchlet.java deleted file mode 100644 index 587008b32..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/ThreadLocalClassloaderBeanPostProcessorTestsBatchlet.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.configuration.xml; - -import jakarta.batch.api.BatchProperty; -import jakarta.batch.api.Batchlet; -import jakarta.batch.runtime.context.JobContext; -import jakarta.batch.runtime.context.StepContext; -import jakarta.inject.Inject; - -import org.springframework.util.Assert; - -public class ThreadLocalClassloaderBeanPostProcessorTestsBatchlet implements Batchlet { - @Inject - @BatchProperty - public String jobParam1; - - @Inject - public JobContext jobContext; - - @Inject - public StepContext stepContext; - - @Override - public String process() throws Exception { - Assert.isTrue("someParameter".equals(jobParam1), jobParam1 + " does not equal someParameter"); - Assert.isTrue("threadLocalClassloaderBeanPostProcessorTestsJob".equals(jobContext.getJobName()), - "jobName does not equal threadLocalClassloaderBeanPostProcessorTestsJob"); - Assert.isTrue("step1".equals(stepContext.getStepName()), "stepName does not equal step1"); - - return null; - } - - @Override - public void stop() throws Exception { - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/JsrFlowJobTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/JsrFlowJobTests.java deleted file mode 100644 index 996084fcd..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/JsrFlowJobTests.java +++ /dev/null @@ -1,770 +0,0 @@ -/* - * 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. - * 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.jsr.job.flow; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobInterruptedException; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.explore.support.JobExplorerFactoryBean; -import org.springframework.batch.core.job.flow.Flow; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.job.flow.FlowExecutor; -import org.springframework.batch.core.job.flow.JobExecutionDecider; -import org.springframework.batch.core.job.flow.State; -import org.springframework.batch.core.job.flow.StateSupport; -import org.springframework.batch.core.job.flow.support.SimpleFlow; -import org.springframework.batch.core.job.flow.support.StateTransition; -import org.springframework.batch.core.job.flow.support.state.DecisionState; -import org.springframework.batch.core.job.flow.support.state.EndState; -import org.springframework.batch.core.job.flow.support.state.FlowState; -import org.springframework.batch.core.job.flow.support.state.SplitState; -import org.springframework.batch.core.job.flow.support.state.StepState; -import org.springframework.batch.core.jsr.JsrStepExecution; -import org.springframework.batch.core.jsr.job.flow.support.JsrFlow; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.batch.core.step.StepSupport; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.lang.Nullable; - -import jakarta.batch.api.Decider; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -/** - * @author Dave Syer - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -public class JsrFlowJobTests { - - private JsrFlowJob job; - - private JobExecution jobExecution; - - private JobRepository jobRepository; - - private JobExplorer jobExplorer; - - private boolean fail = false; - - @Before - public void setUp() throws Exception { - job = new JsrFlowJob(); - EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder() - .addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql") - .addScript("/org/springframework/batch/core/schema-hsqldb.sql") - .build(); - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(embeddedDatabase); - factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase)); - factory.afterPropertiesSet(); - jobRepository = factory.getObject(); - job.setJobRepository(jobRepository); - jobExecution = jobRepository.createJobExecution("job", new JobParameters()); - - JobExplorerFactoryBean jobExplorerFactory = new JobExplorerFactoryBean(); - jobExplorerFactory.setDataSource(embeddedDatabase); - jobExplorerFactory.afterPropertiesSet(); - jobExplorer = jobExplorerFactory.getObject(); - job.setJobExplorer(jobExplorer); - } - - @Test - public void testGetSteps() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - assertEquals(2, job.getStepNames().size()); - } - - @Test - public void testTwoSteps() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); - StepState step2 = new StepState(new StubStep("step2")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - job.doExecute(jobExecution); - StepExecution stepExecution = getStepExecution(jobExecution, "step2"); - assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus()); - assertEquals(2, jobExecution.getStepExecutions().size()); - } - - @Test - public void testFailedStep() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StateSupport("step1", FlowExecutionStatus.FAILED), - "step2")); - StepState step2 = new StepState(new StubStep("step2")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - job.doExecute(jobExecution); - StepExecution stepExecution = getStepExecution(jobExecution, "step2"); - assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus()); - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(2, jobExecution.getStepExecutions().size()); - } - - @Test - public void testFailedStepRestarted() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); - State step2State = new StateSupport("step2") { - @Override - public FlowExecutionStatus handle(FlowExecutor executor) throws Exception { - JobExecution jobExecution = executor.getJobExecution(); - StepExecution stepExecution = jobExecution.createStepExecution(getName()); - jobRepository.add(stepExecution); - if (fail) { - return FlowExecutionStatus.FAILED; - } - else { - return FlowExecutionStatus.COMPLETED; - } - } - }; - transitions.add(StateTransition.createStateTransition(step2State, ExitStatus.COMPLETED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2State, ExitStatus.FAILED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - fail = true; - job.execute(jobExecution); - assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus()); - assertEquals(2, jobExecution.getStepExecutions().size()); - jobRepository.update(jobExecution); - jobExecution = jobRepository.createJobExecution("job", new JobParameters()); - fail = false; - job.execute(jobExecution); - assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); - assertEquals(1, jobExecution.getStepExecutions().size()); - } - - @Test - public void testStoppingStep() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); - State state2 = new StateSupport("step2", FlowExecutionStatus.FAILED); - transitions.add(StateTransition.createStateTransition(state2, ExitStatus.FAILED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(state2, ExitStatus.COMPLETED.getExitCode(), "end1")); - transitions.add(StateTransition.createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end0"), - "step3")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1"))); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step3")), "end2")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end2"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - job.doExecute(jobExecution); - assertEquals(2, jobExecution.getStepExecutions().size()); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - } - - @Test - public void testInterrupted() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") { - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - stepExecution.setStatus(BatchStatus.STOPPING); - jobRepository.update(stepExecution); - } - }), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - job.execute(jobExecution); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED); - assertEquals(1, jobExecution.getAllFailureExceptions().size()); - assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass()); - } - - @Test - public void testUnknownStatusStopsJob() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") { - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - stepExecution.setStatus(BatchStatus.UNKNOWN); - stepExecution.setTerminateOnly(); - jobRepository.update(stepExecution); - } - }), "step2")); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - job.execute(jobExecution); - assertEquals(BatchStatus.UNKNOWN, jobExecution.getStatus()); - checkRepository(BatchStatus.UNKNOWN, ExitStatus.STOPPED); - assertEquals(1, jobExecution.getAllFailureExceptions().size()); - assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass()); - } - - @Test - public void testInterruptedSplit() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - SimpleFlow flow1 = new JsrFlow("flow1"); - SimpleFlow flow2 = new JsrFlow("flow2"); - - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") { - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - if (!stepExecution.getJobExecution().getExecutionContext().containsKey("STOPPED")) { - stepExecution.getJobExecution().getExecutionContext().put("STOPPED", true); - stepExecution.setStatus(BatchStatus.STOPPED); - jobRepository.update(stepExecution); - } - else { - fail("The Job should have stopped by now"); - } - } - }), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow1.setStateTransitions(new ArrayList<>(transitions)); - flow1.afterPropertiesSet(); - flow2.setStateTransitions(new ArrayList<>(transitions)); - flow2.afterPropertiesSet(); - - transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new SplitState(Arrays. asList(flow1, flow2), - "split"), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - - job.setFlow(flow); - job.afterPropertiesSet(); - job.execute(jobExecution); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED); - assertEquals(1, jobExecution.getAllFailureExceptions().size()); - assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass()); - assertEquals(1, jobExecution.getStepExecutions().size()); - for (StepExecution stepExecution : jobExecution.getStepExecutions()) { - assertEquals(BatchStatus.STOPPED, stepExecution.getStatus()); - } - } - - @Test - public void testInterruptedException() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") { - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - throw new JobInterruptedException("Stopped"); - } - }), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - job.execute(jobExecution); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED); - assertEquals(1, jobExecution.getAllFailureExceptions().size()); - assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass()); - } - - @Test - public void testInterruptedSplitException() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - SimpleFlow flow1 = new JsrFlow("flow1"); - SimpleFlow flow2 = new JsrFlow("flow2"); - - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") { - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - throw new JobInterruptedException("Stopped"); - } - }), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow1.setStateTransitions(new ArrayList<>(transitions)); - flow1.afterPropertiesSet(); - flow2.setStateTransitions(new ArrayList<>(transitions)); - flow2.afterPropertiesSet(); - - transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new SplitState(Arrays. asList(flow1, flow2), - "split"), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - - job.setFlow(flow); - job.afterPropertiesSet(); - job.execute(jobExecution); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED); - assertEquals(1, jobExecution.getAllFailureExceptions().size()); - assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass()); - } - - @Test - public void testEndStateStopped() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end")); - transitions.add(StateTransition - .createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end"), "step2")); - StepState step2 = new StepState(new StubStep("step2")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - job.doExecute(jobExecution); - assertEquals(1, jobExecution.getStepExecutions().size()); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - } - - public void testEndStateFailed() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end")); - transitions - .add(StateTransition.createStateTransition(new EndState(FlowExecutionStatus.FAILED, "end"), "step2")); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED - .getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), - ExitStatus.COMPLETED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - job.doExecute(jobExecution); - assertEquals(BatchStatus.FAILED, jobExecution.getStatus()); - assertEquals(1, jobExecution.getStepExecutions().size()); - } - - @Test - public void testEndStateStoppedWithRestart() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end")); - transitions.add(StateTransition - .createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end"), "step2")); - StepState step2 = new StepState(new StubStep("step2")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - - // To test a restart we have to use the AbstractJob.execute()... - job.execute(jobExecution); - assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); - assertEquals(1, jobExecution.getStepExecutions().size()); - - jobExecution = jobRepository.createJobExecution("job", new JobParameters()); - job.execute(jobExecution); - assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); - assertEquals(1, jobExecution.getStepExecutions().size()); - - } - - @Test - public void testBranching() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - StepState step1 = new StepState(new StubStep("step1")); - transitions.add(StateTransition.createStateTransition(step1, "step2")); - transitions.add(StateTransition.createStateTransition(step1, "COMPLETED", "step3")); - StepState step2 = new StepState(new StubStep("step2")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1"))); - StepState step3 = new StepState(new StubStep("step3")); - transitions.add(StateTransition.createStateTransition(step3, ExitStatus.FAILED.getExitCode(), "end2")); - transitions.add(StateTransition.createStateTransition(step3, ExitStatus.COMPLETED.getExitCode(), "end3")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.afterPropertiesSet(); - job.doExecute(jobExecution); - StepExecution stepExecution = getStepExecution(jobExecution, "step2"); - assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus()); - assertEquals(2, jobExecution.getStepExecutions().size()); - } - - @Test - public void testBasicFlow() throws Throwable { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - job.setFlow(flow); - job.execute(jobExecution); - if (!jobExecution.getAllFailureExceptions().isEmpty()) { - throw jobExecution.getAllFailureExceptions().get(0); - } - assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); - } - - @Test - public void testDecisionFlow() throws Throwable { - - SimpleFlow flow = new JsrFlow("job"); - Decider decider = new Decider() { - - @Override - public String decide(jakarta.batch.runtime.StepExecution[] executions) - throws Exception { - assertNotNull(executions); - return "SWITCH"; - } - }; - - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "decision")); - StepState decision = new StepState(new StubDecisionStep("decision", decider)); - transitions.add(StateTransition.createStateTransition(decision, "SWITCH", "step3")); - transitions.add(StateTransition.createStateTransition(decision, "step2")); - StepState step2 = new StepState(new StubStep("step2")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1"))); - StepState step3 = new StepState(new StubStep("step3")); - transitions.add(StateTransition.createStateTransition(step3, ExitStatus.FAILED.getExitCode(), "end2")); - transitions.add(StateTransition.createStateTransition(step3, ExitStatus.COMPLETED.getExitCode(), "end3")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3"))); - flow.setStateTransitions(transitions); - - job.setFlow(flow); - job.doExecute(jobExecution); - - StepExecution stepExecution = getStepExecution(jobExecution, "step3"); - if (!jobExecution.getAllFailureExceptions().isEmpty()) { - throw jobExecution.getAllFailureExceptions().get(0); - } - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(3, jobExecution.getStepExecutions().size()); - - } - - @Test - public void testDecisionFlowWithExceptionInDecider() throws Throwable { - - SimpleFlow flow = new JsrFlow("job"); - JobExecutionDecider decider = new JobExecutionDecider() { - @Override - public FlowExecutionStatus decide(JobExecution jobExecution, @Nullable StepExecution stepExecution) { - assertNotNull(stepExecution); - throw new RuntimeException("Foo"); - } - }; - - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "decision")); - DecisionState decision = new DecisionState(decider, "decision"); - transitions.add(StateTransition.createStateTransition(decision, "step2")); - transitions.add(StateTransition.createStateTransition(decision, "SWITCH", "step3")); - StepState step2 = new StepState(new StubStep("step2")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0")); - transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1"))); - StepState step3 = new StepState(new StubStep("step3")); - transitions.add(StateTransition.createStateTransition(step3, ExitStatus.FAILED.getExitCode(), "end2")); - transitions.add(StateTransition.createStateTransition(step3, ExitStatus.COMPLETED.getExitCode(), "end3")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2"))); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3"))); - flow.setStateTransitions(transitions); - - job.setFlow(flow); - try { - job.execute(jobExecution); - } - finally { - - assertEquals(BatchStatus.FAILED, jobExecution.getStatus()); - assertEquals(1, jobExecution.getStepExecutions().size()); - - assertEquals(1, jobExecution.getAllFailureExceptions().size()); - assertEquals("Foo", jobExecution.getAllFailureExceptions().get(0).getCause().getCause().getMessage()); - - } - } - - @Test - public void testGetStepExists() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - - Step step = job.getStep("step2"); - assertNotNull(step); - assertEquals("step2", step.getName()); - } - - @Test - public void testGetStepExistsWithPrefix() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState("job.step", new StubStep("step")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.setName(flow.getName()); - job.afterPropertiesSet(); - - Step step = job.getStep("step"); - assertNotNull(step); - assertEquals("step", step.getName()); - } - - @Test - public void testGetStepNamesWithPrefix() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState("job.step", new StubStep("step")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.setName(flow.getName()); - job.afterPropertiesSet(); - - assertEquals("[step]", job.getStepNames().toString()); - } - - @Test - public void testGetStepNotExists() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - - Step step = job.getStep("foo"); - assertNull(step); - } - - @Test - public void testGetStepNotStepState() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - - Step step = job.getStep("end0"); - assertNull(step); - } - - @Test - public void testGetStepNestedFlow() throws Exception { - SimpleFlow nested = new JsrFlow("nested"); - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1"))); - nested.setStateTransitions(transitions); - nested.afterPropertiesSet(); - - SimpleFlow flow = new JsrFlow("job"); - transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "nested")); - transitions.add(StateTransition.createStateTransition(new FlowState(nested, "nested"), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - job.setFlow(flow); - job.afterPropertiesSet(); - - List names = new ArrayList<>(job.getStepNames()); - Collections.sort(names); - assertEquals("[step1, step2]", names.toString()); - } - - @Test - public void testGetStepSplitFlow() throws Exception { - SimpleFlow flow = new JsrFlow("job"); - SimpleFlow flow1 = new JsrFlow("flow1"); - SimpleFlow flow2 = new JsrFlow("flow2"); - - List transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end0")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0"))); - flow1.setStateTransitions(new ArrayList<>(transitions)); - flow1.afterPropertiesSet(); - transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end1")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1"))); - flow2.setStateTransitions(new ArrayList<>(transitions)); - flow2.afterPropertiesSet(); - - transitions = new ArrayList<>(); - transitions.add(StateTransition.createStateTransition(new SplitState(Arrays. asList(flow1, flow2), - "split"), "end2")); - transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end2"))); - flow.setStateTransitions(transitions); - flow.afterPropertiesSet(); - - job.setFlow(flow); - job.afterPropertiesSet(); - List names = new ArrayList<>(job.getStepNames()); - Collections.sort(names); - assertEquals("[step1, step2]", names.toString()); - } - - /** - * @author Dave Syer - * - */ - private class StubStep extends StepSupport { - - private StubStep(String name) { - super(name); - } - - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - stepExecution.setStatus(BatchStatus.COMPLETED); - stepExecution.setExitStatus(ExitStatus.COMPLETED); - jobRepository.update(stepExecution); - } - - } - - /** - * @author Michael Minella - * - */ - private class StubDecisionStep extends StepSupport { - - private Decider decider; - - private StubDecisionStep(String name, Decider decider) { - super(name); - this.decider = decider; - } - - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - stepExecution.setStatus(BatchStatus.COMPLETED); - try { - stepExecution.setExitStatus(new ExitStatus(decider.decide(new jakarta.batch.runtime.StepExecution [] {new JsrStepExecution(stepExecution)}))); - } catch (Exception e) { - throw new RuntimeException(e); - } - - jobRepository.update(stepExecution); - } - } - - /** - * @param jobExecution - * @param stepName - * @return the StepExecution corresponding to the specified step - */ - private StepExecution getStepExecution(JobExecution jobExecution, String stepName) { - for (StepExecution stepExecution : jobExecution.getStepExecutions()) { - if (stepExecution.getStepName().equals(stepName)) { - return stepExecution; - } - } - fail("No stepExecution found with name: [" + stepName + "]"); - return null; - } - - private void checkRepository(BatchStatus status, ExitStatus exitStatus) { - JobInstance jobInstance = jobExecution.getJobInstance(); - JobExecution other = jobExplorer.getJobExecutions(jobInstance).get(0); - assertEquals(jobInstance.getId(), other.getJobId()); - assertEquals(status, other.getStatus()); - if (exitStatus != null) { - assertEquals(exitStatus.getExitCode(), other.getExitStatus().getExitCode()); - } - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/support/JsrFlowTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/support/JsrFlowTests.java deleted file mode 100644 index 621abf291..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/support/JsrFlowTests.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2013-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.core.jsr.job.flow.support; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.job.flow.FlowExecution; -import org.springframework.batch.core.job.flow.FlowExecutionStatus; -import org.springframework.batch.core.job.flow.State; -import org.springframework.batch.core.job.flow.StateSupport; -import org.springframework.batch.core.job.flow.support.JobFlowExecutorSupport; -import org.springframework.batch.core.job.flow.support.SimpleFlowTests; -import org.springframework.batch.core.job.flow.support.StateTransition; -import org.springframework.lang.Nullable; - -public class JsrFlowTests extends SimpleFlowTests { - - @Override - @Before - public void setUp() { - flow = new JsrFlow("flow1"); - } - - @Test - public void testNextBasedOnBatchStatus() throws Exception { - StepExecution stepExecution = new StepExecution("step1", new JobExecution(5L)); - stepExecution.setExitStatus(new ExitStatus("unmapped exit code")); - stepExecution.setStatus(BatchStatus.FAILED); - executor = new FlowExecutor(stepExecution); - - State startState = new StateSupport("step1", new FlowExecutionStatus("unmapped exit code")); - State endState = new StateSupport("failed", FlowExecutionStatus.FAILED); - - StateTransition failureTransition = StateTransition.createStateTransition(startState, "FAILED", "failed"); - StateTransition endTransition = StateTransition.createEndStateTransition(endState); - flow.setStateTransitions(collect(failureTransition, endTransition)); - flow.afterPropertiesSet(); - FlowExecution execution = flow.start(executor); - assertEquals(FlowExecutionStatus.FAILED, execution.getStatus()); - assertEquals("failed", execution.getName()); - } - - public static class FlowExecutor extends JobFlowExecutorSupport { - - private StepExecution stepExecution; - - public FlowExecutor(StepExecution stepExecution) { - this.stepExecution = stepExecution; - } - - @Nullable - @Override - public StepExecution getStepExecution() { - return stepExecution; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrEndStateTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrEndStateTests.java deleted file mode 100644 index 27c720453..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/job/flow/support/state/JsrEndStateTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.job.flow.support.state; - -import static org.junit.Assert.assertEquals; - -import jakarta.batch.api.AbstractBatchlet; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; - -import org.junit.Test; - -import org.springframework.batch.core.jsr.AbstractJsrTestCase; - -/** - * Tests for the JSR-352 version of {@link JsrEndState} - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -public class JsrEndStateTests extends AbstractJsrTestCase { - - @Test - public void test() throws Exception { - JobExecution jobExecution = runJob("jobWithEndTransition", null, 10000L); - - assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus()); - assertEquals("SUCCESS", jobExecution.getExitStatus()); - assertEquals(1, operator.getStepExecutions(jobExecution.getExecutionId()).size()); - } - - public static class EndStateBatchlet extends AbstractBatchlet { - - @Override - public String process() throws Exception { - return "GOOD"; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/launch/JsrJobOperatorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/launch/JsrJobOperatorTests.java deleted file mode 100644 index 3034764cd..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/launch/JsrJobOperatorTests.java +++ /dev/null @@ -1,688 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.launch; - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import jakarta.batch.api.AbstractBatchlet; -import jakarta.batch.api.Batchlet; -import jakarta.batch.operations.JobExecutionIsRunningException; -import jakarta.batch.operations.JobOperator; -import jakarta.batch.operations.JobRestartException; -import jakarta.batch.operations.JobStartException; -import jakarta.batch.operations.NoSuchJobException; -import jakarta.batch.operations.NoSuchJobExecutionException; -import jakarta.batch.operations.NoSuchJobInstanceException; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import javax.sql.DataSource; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.configuration.annotation.DataSourceConfiguration; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.converter.JobParametersConverter; -import org.springframework.batch.core.converter.JobParametersConverterSupport; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.explore.support.SimpleJobExplorer; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.batch.core.jsr.JsrJobParametersConverter; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.step.JobRepositorySupport; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SyncTaskExecutor; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.transaction.PlatformTransactionManager; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link JsrJobOperator}. - */ -public class JsrJobOperatorTests extends AbstractJsrTestCase { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private JobOperator jsrJobOperator; - @Mock - private JobExplorer jobExplorer; - @Mock - private JobRepository jobRepository; - private JobParametersConverter parameterConverter; - private static final long TIMEOUT = 10000L; - - @Before - public void setup() throws Exception { - - parameterConverter = new JobParametersConverterSupport(); - jsrJobOperator = new JsrJobOperator(jobExplorer, jobRepository, parameterConverter, new ResourcelessTransactionManager()); - } - - @Test - public void testLoadingWithBatchRuntime() { - jsrJobOperator = BatchRuntime.getJobOperator(); - assertNotNull(jsrJobOperator); - } - - @Test - public void testNullsInConstructor() { - try { - new JsrJobOperator(null, new JobRepositorySupport(), parameterConverter, null); - fail("JobExplorer should be required"); - } catch (IllegalArgumentException correct) { - } - - try { - new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), null, parameterConverter, null); - fail("JobRepository should be required"); - } catch (IllegalArgumentException correct) { - } - - try { - new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), new JobRepositorySupport(), null, null); - fail("ParameterConverter should be required"); - } catch (IllegalArgumentException correct) { - } - - try { - new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), new JobRepositorySupport(), parameterConverter, null); - } - catch (IllegalArgumentException correct) { - } - - new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), new JobRepositorySupport(), parameterConverter, new ResourcelessTransactionManager()); - } - - @Test - public void testCustomBaseContextJsrCompliant() throws Exception { - System.setProperty("JSR-352-BASE-CONTEXT", "META-INF/alternativeJsrBaseContext.xml"); - - ReflectionTestUtils.setField(JsrJobOperator.BaseContextHolder.class, "instance", null); - - JobOperator jobOperator = BatchRuntime.getJobOperator(); - - Object transactionManager = ReflectionTestUtils.getField(jobOperator, "transactionManager"); - assertTrue(transactionManager instanceof ResourcelessTransactionManager); - - long executionId = jobOperator.start("longRunningJob", null); - // Give the job a chance to get started - Thread.sleep(1000L); - jobOperator.stop(executionId); - // Give the job the chance to finish stopping - Thread.sleep(1000L); - - assertEquals(BatchStatus.STOPPED, jobOperator.getJobExecution(executionId).getBatchStatus()); - - System.getProperties().remove("JSR-352-BASE-CONTEXT"); - } - - @Test - public void testCustomBaseContextCustomWired() throws Exception { - - GenericApplicationContext context = new AnnotationConfigApplicationContext(BatchConfgiuration.class); - - JobOperator jobOperator = (JobOperator) context.getBean("jobOperator"); - - assertEquals(context, ReflectionTestUtils.getField(jobOperator, "baseContext")); - - long executionId = jobOperator.start("longRunningJob", null); - // Give the job a chance to get started - Thread.sleep(1000L); - jobOperator.stop(executionId); - // Give the job the chance to finish stopping - Thread.sleep(1000L); - - assertEquals(BatchStatus.STOPPED, jobOperator.getJobExecution(executionId).getBatchStatus()); - - System.getProperties().remove("JSR-352-BASE-CONTEXT"); - } - - @Test - public void testDefaultTaskExecutor() throws Exception { - JsrJobOperator jsrJobOperatorImpl = (JsrJobOperator) jsrJobOperator; - jsrJobOperatorImpl.afterPropertiesSet(); - assertNotNull(jsrJobOperatorImpl.getTaskExecutor()); - assertTrue((jsrJobOperatorImpl.getTaskExecutor() instanceof AsyncTaskExecutor)); - } - - @Test - public void testCustomTaskExecutor() throws Exception { - JsrJobOperator jsrJobOperatorImpl = (JsrJobOperator) jsrJobOperator; - jsrJobOperatorImpl.setTaskExecutor(new SyncTaskExecutor()); - jsrJobOperatorImpl.afterPropertiesSet(); - assertNotNull(jsrJobOperatorImpl.getTaskExecutor()); - assertTrue((jsrJobOperatorImpl.getTaskExecutor() instanceof SyncTaskExecutor)); - } - - @Test - public void testAbandonRoseyScenario() throws Exception { - JobExecution jobExecution = new JobExecution(5L); - jobExecution.setEndTime(new Date()); - when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution); - - jsrJobOperator.abandon(5L); - - ArgumentCaptor executionCaptor = ArgumentCaptor.forClass(JobExecution.class); - verify(jobRepository).update(executionCaptor.capture()); - assertEquals(org.springframework.batch.core.BatchStatus.ABANDONED, executionCaptor.getValue().getStatus()); - - } - - @Test(expected=NoSuchJobExecutionException.class) - public void testAbandonNoSuchJob() throws Exception { - jsrJobOperator.abandon(5L); - } - - @Test(expected=JobExecutionIsRunningException.class) - public void testAbandonJobRunning() throws Exception { - JobExecution jobExecution = new JobExecution(5L); - jobExecution.setStartTime(new Date(1L)); - - when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution); - - jsrJobOperator.abandon(5L); - } - - @Test - public void testGetJobExecutionRoseyScenario() { - when(jobExplorer.getJobExecution(5L)).thenReturn(new JobExecution(5L)); - - assertEquals(5L, jsrJobOperator.getJobExecution(5L).getExecutionId()); - } - - @Test(expected=NoSuchJobExecutionException.class) - public void testGetJobExecutionNoExecutionFound() { - jsrJobOperator.getJobExecution(5L); - } - - @Test - public void testGetJobExecutionsRoseyScenario() { - org.springframework.batch.core.JobInstance jobInstance = new org.springframework.batch.core.JobInstance(5L, "my job"); - List executions = new ArrayList<>(); - executions.add(new JobExecution(2L)); - - when(jobExplorer.getJobExecutions(jobInstance)).thenReturn(executions); - - List jobExecutions = jsrJobOperator.getJobExecutions(jobInstance); - assertEquals(1, jobExecutions.size()); - assertEquals(2L, executions.get(0).getId().longValue()); - } - - @Test(expected=NoSuchJobInstanceException.class) - public void testGetJobExecutionsNullJobInstance() { - jsrJobOperator.getJobExecutions(null); - } - - @Test(expected=NoSuchJobInstanceException.class) - public void testGetJobExecutionsNullReturned() { - org.springframework.batch.core.JobInstance jobInstance = new org.springframework.batch.core.JobInstance(5L, "my job"); - - jsrJobOperator.getJobExecutions(jobInstance); - } - - @Test(expected=NoSuchJobInstanceException.class) - public void testGetJobExecutionsNoneReturned() { - org.springframework.batch.core.JobInstance jobInstance = new org.springframework.batch.core.JobInstance(5L, "my job"); - List executions = new ArrayList<>(); - - when(jobExplorer.getJobExecutions(jobInstance)).thenReturn(executions); - - jsrJobOperator.getJobExecutions(jobInstance); - } - - @Test - public void testGetJobInstanceRoseyScenario() { - JobInstance instance = new JobInstance(1L, "my job"); - JobExecution execution = new JobExecution(5L); - execution.setJobInstance(instance); - - when(jobExplorer.getJobExecution(5L)).thenReturn(execution); - when(jobExplorer.getJobInstance(1L)).thenReturn(instance); - - jakarta.batch.runtime.JobInstance jobInstance = jsrJobOperator.getJobInstance(5L); - - assertEquals(1L, jobInstance.getInstanceId()); - assertEquals("my job", jobInstance.getJobName()); - } - - @Test(expected=NoSuchJobExecutionException.class) - public void testGetJobInstanceNoExecution() { - JobInstance instance = new JobInstance(1L, "my job"); - JobExecution execution = new JobExecution(5L); - execution.setJobInstance(instance); - - jsrJobOperator.getJobInstance(5L); - } - - @Test - public void testGetJobInstanceCount() throws Exception { - when(jobExplorer.getJobInstanceCount("myJob")).thenReturn(4); - - assertEquals(4, jsrJobOperator.getJobInstanceCount("myJob")); - } - - @Test(expected=NoSuchJobException.class) - public void testGetJobInstanceCountNoSuchJob() throws Exception { - when(jobExplorer.getJobInstanceCount("myJob")).thenThrow(new org.springframework.batch.core.launch.NoSuchJobException("expected")); - - jsrJobOperator.getJobInstanceCount("myJob"); - } - - @Test(expected=NoSuchJobException.class) - public void testGetJobInstanceCountZeroInstancesReturned() throws Exception { - when(jobExplorer.getJobInstanceCount("myJob")).thenReturn(0); - - jsrJobOperator.getJobInstanceCount("myJob"); - } - - @Test - public void testGetJobInstancesRoseyScenario() { - List instances = new ArrayList<>(); - instances.add(new JobInstance(1L, "myJob")); - instances.add(new JobInstance(2L, "myJob")); - instances.add(new JobInstance(3L, "myJob")); - - when(jobExplorer.getJobInstances("myJob", 0, 3)).thenReturn(instances); - - List jobInstances = jsrJobOperator.getJobInstances("myJob", 0, 3); - - assertEquals(3, jobInstances.size()); - assertEquals(1L, jobInstances.get(0).getInstanceId()); - assertEquals(2L, jobInstances.get(1).getInstanceId()); - assertEquals(3L, jobInstances.get(2).getInstanceId()); - } - - @Test(expected=NoSuchJobException.class) - public void testGetJobInstancesNullInstancesReturned() { - jsrJobOperator.getJobInstances("myJob", 0, 3); - } - - @Test(expected=NoSuchJobException.class) - public void testGetJobInstancesZeroInstancesReturned() { - List instances = new ArrayList<>(); - - when(jobExplorer.getJobInstances("myJob", 0, 3)).thenReturn(instances); - - jsrJobOperator.getJobInstances("myJob", 0, 3); - } - - @Test - public void testGetJobNames() { - List jobNames = new ArrayList<>(); - jobNames.add("job1"); - jobNames.add("job2"); - - when(jobExplorer.getJobNames()).thenReturn(jobNames); - - Set result = jsrJobOperator.getJobNames(); - - assertEquals(2, result.size()); - assertTrue(result.contains("job1")); - assertTrue(result.contains("job2")); - } - - @Test - public void testGetParametersRoseyScenario() { - JobExecution jobExecution = new JobExecution(5L, new JobParametersBuilder().addString("key1", "value1").addLong(JsrJobParametersConverter.JOB_RUN_ID, 5L).toJobParameters()); - - when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution); - - Properties params = jsrJobOperator.getParameters(5L); - - assertEquals("value1", params.get("key1")); - assertNull(params.get(JsrJobParametersConverter.JOB_RUN_ID)); - } - - @Test(expected=NoSuchJobExecutionException.class) - public void testGetParametersNoExecution() { - jsrJobOperator.getParameters(5L); - } - - @Test(expected=NoSuchJobException.class) - public void testGetNoRunningExecutions() { - Set executions = new HashSet<>(); - - when(jobExplorer.findRunningJobExecutions("myJob")).thenReturn(executions); - - jsrJobOperator.getRunningExecutions("myJob"); - } - - @Test - public void testGetRunningExecutions() { - Set executions = new HashSet<>(); - executions.add(new JobExecution(5L)); - - when(jobExplorer.findRunningJobExecutions("myJob")).thenReturn(executions); - - assertEquals(5L, jsrJobOperator.getRunningExecutions("myJob").get(0).longValue()); - } - - @Test - public void testGetStepExecutionsRoseyScenario() { - JobExecution jobExecution = new JobExecution(5L); - List stepExecutions = new ArrayList<>(); - stepExecutions.add(new StepExecution("step1", jobExecution, 1L)); - stepExecutions.add(new StepExecution("step2", jobExecution, 2L)); - jobExecution.addStepExecutions(stepExecutions); - - when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution); - when(jobExplorer.getStepExecution(5L, 1L)).thenReturn(new StepExecution("step1", jobExecution, 1L)); - when(jobExplorer.getStepExecution(5L, 2L)).thenReturn(new StepExecution("step2", jobExecution, 2L)); - - List results = jsrJobOperator.getStepExecutions(5L); - - assertEquals("step1", results.get(0).getStepName()); - assertEquals("step2", results.get(1).getStepName()); - } - - @Test(expected=NoSuchJobException.class) - public void testGetStepExecutionsNoExecutionReturned() { - jsrJobOperator.getStepExecutions(5L); - } - - @Test - public void testGetStepExecutionsPartitionedStepScenario() { - JobExecution jobExecution = new JobExecution(5L); - List stepExecutions = new ArrayList<>(); - stepExecutions.add(new StepExecution("step1", jobExecution, 1L)); - stepExecutions.add(new StepExecution("step2", jobExecution, 2L)); - stepExecutions.add(new StepExecution("step2:partition0", jobExecution, 2L)); - stepExecutions.add(new StepExecution("step2:partition1", jobExecution, 2L)); - stepExecutions.add(new StepExecution("step2:partition2", jobExecution, 2L)); - jobExecution.addStepExecutions(stepExecutions); - - when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution); - when(jobExplorer.getStepExecution(5L, 1L)).thenReturn(new StepExecution("step1", jobExecution, 1L)); - when(jobExplorer.getStepExecution(5L, 2L)).thenReturn(new StepExecution("step2", jobExecution, 2L)); - - List results = jsrJobOperator.getStepExecutions(5L); - - assertEquals("step1", results.get(0).getStepName()); - assertEquals("step2", results.get(1).getStepName()); - } - - @Test - public void testGetStepExecutionsNoStepExecutions() { - JobExecution jobExecution = new JobExecution(5L); - - when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution); - - List results = jsrJobOperator.getStepExecutions(5L); - - assertEquals(0, results.size()); - } - - @Test - public void testStartRoseyScenario() throws Exception { - jakarta.batch.runtime.JobExecution execution = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - } - - @Test - public void testStartMultipleTimesSameParameters() throws Exception { - jsrJobOperator = BatchRuntime.getJobOperator(); - - int jobInstanceCountBefore = 0; - - try { - jobInstanceCountBefore = jsrJobOperator.getJobInstanceCount("myJob3"); - } catch (NoSuchJobException ignore) { - } - - jakarta.batch.runtime.JobExecution execution1 = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT); - jakarta.batch.runtime.JobExecution execution2 = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT); - jakarta.batch.runtime.JobExecution execution3 = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution1.getBatchStatus()); - assertEquals(BatchStatus.COMPLETED, execution2.getBatchStatus()); - assertEquals(BatchStatus.COMPLETED, execution3.getBatchStatus()); - - int jobInstanceCountAfter = jsrJobOperator.getJobInstanceCount("myJob3"); - - assertTrue((jobInstanceCountAfter - jobInstanceCountBefore) == 3); - } - - @Test - public void testRestartRoseyScenario() throws Exception { - jakarta.batch.runtime.JobExecution execution = runJob("jsrJobOperatorTestRestartJob", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - - execution = restartJob(execution.getExecutionId(), null, TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - } - - @Test(expected = JobRestartException.class) - public void testNonRestartableJob() throws Exception { - jakarta.batch.runtime.JobExecution jobExecutionStart = runJob("jsrJobOperatorTestNonRestartableJob", new Properties(), TIMEOUT); - assertEquals(BatchStatus.FAILED, jobExecutionStart.getBatchStatus()); - - restartJob(jobExecutionStart.getExecutionId(), null, TIMEOUT); - } - - @Test(expected = JobRestartException.class) - public void testRestartAbandoned() throws Exception { - jsrJobOperator = BatchRuntime.getJobOperator(); - jakarta.batch.runtime.JobExecution execution = runJob("jsrJobOperatorTestRestartAbandonJob", null, TIMEOUT); - - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - - jsrJobOperator.abandon(execution.getExecutionId()); - jsrJobOperator.restart(execution.getExecutionId(), null); - } - - @Test - public void testGetNoRestartJobParameters() { - JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator; - Properties properties = jobOperator.getJobRestartProperties(null, null); - assertTrue(properties.isEmpty()); - } - - @Test - public void testGetRestartJobParameters() { - JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator; - - JobExecution jobExecution = new JobExecution(1L, - new JobParametersBuilder().addString("prevKey1", "prevVal1").toJobParameters()); - - Properties userProperties = new Properties(); - userProperties.put("userKey1", "userVal1"); - - Properties properties = jobOperator.getJobRestartProperties(userProperties, jobExecution); - - assertTrue(properties.size() == 2); - assertTrue(properties.getProperty("prevKey1").equals("prevVal1")); - assertTrue(properties.getProperty("userKey1").equals("userVal1")); - } - - @Test - public void testGetRestartJobParametersWithDefaults() { - JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator; - - JobExecution jobExecution = new JobExecution(1L, - new JobParametersBuilder().addString("prevKey1", "prevVal1").addString("prevKey2", "prevVal2").toJobParameters()); - - Properties defaultProperties = new Properties(); - defaultProperties.setProperty("prevKey2", "not value 2"); - Properties userProperties = new Properties(defaultProperties); - - Properties properties = jobOperator.getJobRestartProperties(userProperties, jobExecution); - - assertTrue(properties.size() == 2); - assertTrue(properties.getProperty("prevKey1").equals("prevVal1")); - assertTrue("prevKey2 = " + properties.getProperty("prevKey2"), properties.getProperty("prevKey2").equals("not value 2")); - } - - @Test - public void testNewJobParametersOverridePreviousRestartParameters() { - JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator; - - JobExecution jobExecution = new JobExecution(1L, - new JobParametersBuilder() - .addString("prevKey1", "prevVal1") - .addString("overrideTest", "jobExecution") - .toJobParameters()); - - Properties userProperties = new Properties(); - userProperties.put("userKey1", "userVal1"); - userProperties.put("overrideTest", "userProperties"); - - Properties properties = jobOperator.getJobRestartProperties(userProperties, jobExecution); - - assertTrue(properties.size() == 3); - assertTrue(properties.getProperty("prevKey1").equals("prevVal1")); - assertTrue(properties.getProperty("userKey1").equals("userVal1")); - assertTrue(properties.getProperty("overrideTest").equals("userProperties")); - } - - @Test(expected = JobStartException.class) - public void testBeanCreationExceptionOnStart() throws Exception { - jsrJobOperator = BatchRuntime.getJobOperator(); - - try { - jsrJobOperator.start("jsrJobOperatorTestBeanCreationException", null); - } catch (JobStartException e) { - assertTrue(e.getCause() instanceof BeanCreationException); - throw e; - } - - fail("Should have failed"); - } - - @SuppressWarnings("unchecked") - @Test(expected=JobStartException.class) - public void testStartUnableToCreateJobExecution() throws Exception { - when(jobRepository.createJobExecution("myJob", null)).thenThrow(RuntimeException.class); - - jsrJobOperator.start("myJob", null); - } - - @Test - public void testJobStopRoseyScenario() throws Exception { - jsrJobOperator = BatchRuntime.getJobOperator(); - long executionId = jsrJobOperator.start("longRunningJob", null); - // Give the job a chance to get started - Thread.sleep(1000L); - jsrJobOperator.stop(executionId); - // Give the job the chance to finish stopping - Thread.sleep(1000L); - - assertEquals(BatchStatus.STOPPED, jsrJobOperator.getJobExecution(executionId).getBatchStatus()); - - } - - @Test - public void testApplicationContextClosingAfterJobSuccessful() throws Exception { - for(int i = 0; i < 3; i++) { - jakarta.batch.runtime.JobExecution execution = runJob("contextClosingTests", new Properties(), TIMEOUT); - - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - - // Added to allow time for the context to finish closing before running the job again - Thread.sleep(1000l); - } - } - - public static class LongRunningBatchlet implements Batchlet { - - private boolean stopped = false; - - @Override - public String process() throws Exception { - while(!stopped) { - Thread.sleep(250); - } - return null; - } - - @Override - public void stop() throws Exception { - stopped = true; - } - } - - public static class FailingBatchlet extends AbstractBatchlet { - @Override - public String process() throws Exception { - throw new RuntimeException("blah"); - } - } - - public static class MustBeClosedBatchlet extends AbstractBatchlet { - - public static boolean closed = true; - - public MustBeClosedBatchlet() { - if(!closed) { - throw new RuntimeException("Batchlet wasn't closed last time"); - } - } - - public void close() { - closed = true; - } - - @Override - public String process() throws Exception { - closed = false; - return null; - } - } - - @Configuration - @Import(DataSourceConfiguration.class) - @EnableBatchProcessing - public static class BatchConfgiuration { - - @Bean - public JsrJobOperator jobOperator(JobExplorer jobExplorer, JobRepository jobrepository, DataSource dataSource, - PlatformTransactionManager transactionManager) throws Exception{ - - JsrJobParametersConverter jobParametersConverter = new JsrJobParametersConverter(dataSource); - jobParametersConverter.afterPropertiesSet(); - return new JsrJobOperator(jobExplorer, jobrepository, jobParametersConverter, transactionManager); - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandlerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandlerTests.java deleted file mode 100644 index e24019254..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandlerTests.java +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.partition; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobInterruptedException; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.step.batchlet.BatchletSupport; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.batch.core.step.StepSupport; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.util.StopWatch; - -import jakarta.batch.api.BatchProperty; -import jakarta.batch.api.partition.PartitionAnalyzer; -import jakarta.batch.api.partition.PartitionCollector; -import jakarta.batch.api.partition.PartitionMapper; -import jakarta.batch.api.partition.PartitionPlan; -import jakarta.batch.api.partition.PartitionPlanImpl; -import jakarta.batch.api.partition.PartitionReducer; -import jakarta.batch.runtime.BatchStatus; -import jakarta.inject.Inject; -import java.io.Serializable; -import java.util.Collection; -import java.util.Properties; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -@Ignore // FIXME https://github.com/spring-projects/spring-batch/issues/3850 -public class JsrPartitionHandlerTests extends AbstractJsrTestCase { - - private JsrPartitionHandler handler; - private JobRepository repository; - private StepExecution stepExecution; - private AtomicInteger count; - private BatchPropertyContext propertyContext; - private JsrStepExecutionSplitter stepSplitter; - - @Before - public void setUp() throws Exception { - JobExecution jobExecution = new JobExecution(1L); - jobExecution.setJobInstance(new JobInstance(1L, "job")); - stepExecution = new StepExecution("step1", jobExecution); - stepSplitter = new JsrStepExecutionSplitter(repository, false, "step1", true); - Analyzer.collectorData = ""; - Analyzer.status = ""; - count = new AtomicInteger(0); - handler = new JsrPartitionHandler(); - handler.setStep(new StepSupport() { - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - count.incrementAndGet(); - stepExecution.setStatus(org.springframework.batch.core.BatchStatus.COMPLETED); - stepExecution.setExitStatus(new ExitStatus("done")); - } - }); - propertyContext = new BatchPropertyContext(); - handler.setPropertyContext(propertyContext); - EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder() - .addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql") - .addScript("/org/springframework/batch/core/schema-hsqldb.sql") - .build(); - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(embeddedDatabase); - factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase)); - factory.afterPropertiesSet(); - repository = factory.getObject(); - handler.setJobRepository(repository); - MyPartitionReducer.reset(); - CountingPartitionCollector.reset(); - } - - @Test - public void testAfterPropertiesSet() throws Exception { - handler = new JsrPartitionHandler(); - - try { - handler.afterPropertiesSet(); - fail("PropertyContext was not checked for"); - } catch(IllegalArgumentException iae) { - assertEquals("A BatchPropertyContext is required", iae.getMessage()); - } - - handler.setPropertyContext(new BatchPropertyContext()); - - try { - handler.afterPropertiesSet(); - fail("Threads or mapper was not checked for"); - } catch(IllegalArgumentException iae) { - assertEquals("Either a mapper implementation or the number of partitions/threads is required", iae.getMessage()); - } - - handler.setThreads(3); - - try { - handler.afterPropertiesSet(); - fail("JobRepository was not checked for"); - } catch(IllegalArgumentException iae) { - assertEquals("A JobRepository is required", iae.getMessage()); - } - - handler.setJobRepository(repository); - handler.afterPropertiesSet(); - - handler.setPollingInterval(-1); - try { - handler.afterPropertiesSet(); - fail("Polling interval was not checked for"); - } catch(IllegalArgumentException iae) { - assertEquals("The polling interval must be positive", iae.getMessage()); - } - } - - @Test - public void testHardcodedNumberOfPartitions() throws Exception { - handler.setThreads(3); - handler.setPartitions(3); - handler.afterPropertiesSet(); - - Collection executions = handler.handle(stepSplitter, stepExecution); - - assertEquals(3, executions.size()); - assertEquals(3, count.get()); - } - - @Test - public void testPollingPartitionsCompletion() throws Exception { - handler.setThreads(3); - handler.setPartitions(3); - handler.setPollingInterval(1000); - handler.afterPropertiesSet(); - - StopWatch stopWatch = new StopWatch(); - stopWatch.start(); - Collection executions = handler.handle(stepSplitter, stepExecution); - stopWatch.stop(); - - assertEquals(3, executions.size()); - assertEquals(3, count.get()); - assertTrue(stopWatch.getLastTaskTimeMillis() >= 1000); - } - - @Test - public void testMapperProvidesPartitions() throws Exception { - handler.setPartitionMapper(new PartitionMapper() { - - @Override - public PartitionPlan mapPartitions() throws Exception { - PartitionPlan plan = new PartitionPlanImpl(); - plan.setPartitions(3); - plan.setThreads(0); - return plan; - } - }); - - handler.afterPropertiesSet(); - - Collection executions = handler.handle(new JsrStepExecutionSplitter(repository, false, "step1", true), stepExecution); - - assertEquals(3, executions.size()); - assertEquals(3, count.get()); - } - - @Test - public void testMapperProvidesPartitionsAndThreads() throws Exception { - handler.setPartitionMapper(new PartitionMapper() { - - @Override - public PartitionPlan mapPartitions() throws Exception { - PartitionPlan plan = new PartitionPlanImpl(); - plan.setPartitions(3); - plan.setThreads(1); - return plan; - } - }); - - handler.afterPropertiesSet(); - - Collection executions = handler.handle(new JsrStepExecutionSplitter(repository, false, "step1", true), stepExecution); - - assertEquals(3, executions.size()); - assertEquals(3, count.get()); - } - - @Test - public void testMapperWithProperties() throws Exception { - handler.setPartitionMapper(new PartitionMapper() { - - @Override - public PartitionPlan mapPartitions() throws Exception { - PartitionPlan plan = new PartitionPlanImpl(); - Properties [] props = new Properties[2]; - props[0] = new Properties(); - props[0].put("key1", "value1"); - props[1] = new Properties(); - props[1].put("key1", "value2"); - plan.setPartitionProperties(props); - plan.setPartitions(3); - plan.setThreads(1); - return plan; - } - }); - - handler.afterPropertiesSet(); - - Collection executions = handler.handle(new JsrStepExecutionSplitter(repository, false, "step1", true), stepExecution); - - assertEquals(3, executions.size()); - assertEquals(3, count.get()); - assertEquals("value1", propertyContext.getStepProperties("step1:partition0").get("key1")); - assertEquals("value2", propertyContext.getStepProperties("step1:partition1").get("key1")); - } - - @Test - public void testAnalyzer() throws Exception { - Queue queue = new ConcurrentLinkedQueue<>(); - queue.add("foo"); - queue.add("bar"); - - handler.setPartitionDataQueue(queue); - handler.setThreads(2); - handler.setPartitions(2); - handler.setPartitionAnalyzer(new Analyzer()); - handler.afterPropertiesSet(); - - Collection executions = handler.handle(new JsrStepExecutionSplitter(repository, false, "step1", true), stepExecution); - - assertEquals(2, executions.size()); - assertEquals(2, count.get()); - assertEquals("foobar", Analyzer.collectorData); - assertEquals("COMPLETEDdone", Analyzer.status); - } - - @Test - public void testRestartNoOverride() throws Exception { - jakarta.batch.runtime.JobExecution execution1 = runJob("jsrPartitionHandlerRestartWithOverrideJob", null, 1000000L); - assertEquals(BatchStatus.FAILED, execution1.getBatchStatus()); - assertEquals(1, MyPartitionReducer.beginCount); - assertEquals(0, MyPartitionReducer.beforeCount); - assertEquals(1, MyPartitionReducer.rollbackCount); - assertEquals(1, MyPartitionReducer.afterCount); - assertEquals(3, CountingPartitionCollector.collected); - - MyPartitionReducer.reset(); - CountingPartitionCollector.reset(); - - jakarta.batch.runtime.JobExecution execution2 = restartJob(execution1.getExecutionId(), null, 1000000L); - assertEquals(BatchStatus.COMPLETED, execution2.getBatchStatus()); - assertEquals(1, MyPartitionReducer.beginCount); - assertEquals(1, MyPartitionReducer.beforeCount); - assertEquals(0, MyPartitionReducer.rollbackCount); - assertEquals(1, MyPartitionReducer.afterCount); - assertEquals(1, CountingPartitionCollector.collected); - } - - - @Test - public void testRestartOverride() throws Exception { - Properties jobParameters = new Properties(); - jobParameters.put("mapper.override", "true"); - - jakarta.batch.runtime.JobExecution execution1 = runJob("jsrPartitionHandlerRestartWithOverrideJob", jobParameters, 1000000L); - assertEquals(BatchStatus.FAILED, execution1.getBatchStatus()); - assertEquals(1, MyPartitionReducer.beginCount); - assertEquals(0, MyPartitionReducer.beforeCount); - assertEquals(1, MyPartitionReducer.rollbackCount); - assertEquals(1, MyPartitionReducer.afterCount); - assertEquals(3, CountingPartitionCollector.collected); - - MyPartitionReducer.reset(); - CountingPartitionCollector.reset(); - - jakarta.batch.runtime.JobExecution execution2 = restartJob(execution1.getExecutionId(), jobParameters, 1000000L); - assertEquals(BatchStatus.COMPLETED, execution2.getBatchStatus()); - assertEquals(1, MyPartitionReducer.beginCount); - assertEquals(1, MyPartitionReducer.beforeCount); - assertEquals(0, MyPartitionReducer.rollbackCount); - assertEquals(1, MyPartitionReducer.afterCount); - assertEquals(5, CountingPartitionCollector.collected); - } - - public static class CountingPartitionCollector implements PartitionCollector { - - public static int collected = 0; - - public static void reset() { - collected = 0; - } - - @Override - public Serializable collectPartitionData() throws Exception { - collected++; - - return null; - } - } - - public static class MyPartitionReducer implements PartitionReducer { - - public static int beginCount = 0; - public static int beforeCount = 0; - public static int rollbackCount = 0; - public static int afterCount = 0; - - public static void reset() { - beginCount = 0; - beforeCount = 0; - rollbackCount = 0; - afterCount = 0; - } - - @Override - public void beginPartitionedStep() throws Exception { - beginCount++; - } - - @Override - public void beforePartitionedStepCompletion() throws Exception { - beforeCount++; - } - - @Override - public void rollbackPartitionedStep() throws Exception { - rollbackCount++; - } - - @Override - public void afterPartitionedStepCompletion(PartitionStatus status) - throws Exception { - afterCount++; - } - } - - public static class MyPartitionMapper implements PartitionMapper { - - private static int count = 0; - - @Inject - @BatchProperty - String overrideString = "false"; - - @Override - public PartitionPlan mapPartitions() throws Exception { - count++; - - PartitionPlan plan = new PartitionPlanImpl(); - - if(count % 2 == 1) { - plan.setPartitions(3); - plan.setThreads(3); - } else { - plan.setPartitions(5); - plan.setThreads(5); - } - - plan.setPartitionsOverride(Boolean.valueOf(overrideString)); - - Properties[] props = new Properties[3]; - props[0] = new Properties(); - props[1] = new Properties(); - props[2] = new Properties(); - - if(count % 2 == 1) { - props[1].put("fail", "true"); - } - - plan.setPartitionProperties(props); - return plan; - } - } - - public static class MyBatchlet extends BatchletSupport { - @Inject - @BatchProperty - String fail; - - @Override - public String process() { - if("true".equalsIgnoreCase(fail)) { - throw new RuntimeException("Expected"); - } - - return null; - } - } - - public static class Analyzer implements PartitionAnalyzer { - - public static String collectorData; - public static String status; - - @Override - public void analyzeCollectorData(Serializable data) throws Exception { - collectorData = collectorData + data; - } - - @Override - public void analyzeStatus(BatchStatus batchStatus, String exitStatus) - throws Exception { - status = batchStatus + exitStatus; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/JsrStepExecutionSplitterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/JsrStepExecutionSplitterTests.java deleted file mode 100644 index 646d4eed7..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/JsrStepExecutionSplitterTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 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.jsr.partition; - -import static org.junit.Assert.assertEquals; - -import java.util.Iterator; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.step.JobRepositorySupport; - -public class JsrStepExecutionSplitterTests { - - private JsrStepExecutionSplitter splitter; - - @Before - public void setUp() throws Exception { - splitter = new JsrStepExecutionSplitter(new JobRepositorySupport(), false, "step1", true); - } - - @Test - public void test() throws Exception { - Set executions = splitter.split(new StepExecution("step1", new JobExecution(5L)), 3); - - assertEquals(3, executions.size()); - - Iterator stepExecutions = executions.iterator(); - - int count = 0; - while(stepExecutions.hasNext()) { - StepExecution curExecution = stepExecutions.next(); - assertEquals("step1:partition" + count, curExecution.getStepName()); - count++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/PartitionCollectorAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/PartitionCollectorAdapterTests.java deleted file mode 100644 index 438f2efab..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/partition/PartitionCollectorAdapterTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.partition; - -import static org.junit.Assert.assertEquals; - -import java.io.Serializable; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.locks.ReentrantLock; - -import jakarta.batch.api.partition.PartitionCollector; - -import org.junit.Test; -import org.springframework.batch.core.scope.context.ChunkContext; - -public class PartitionCollectorAdapterTests { - - private PartitionCollectorAdapter adapter; - - @Test - public void testAfterChunkSuccessful() throws Exception { - Queue dataQueue = new ConcurrentLinkedQueue<>(); - - adapter = new PartitionCollectorAdapter(dataQueue, new PartitionCollector() { - - private int count = 0; - - @Override - public Serializable collectPartitionData() throws Exception { - return String.valueOf(count++); - } - }); - - adapter.setPartitionLock(new ReentrantLock()); - - ChunkContext context = new ChunkContext(null); - context.setComplete(); - - adapter.afterChunk(context); - adapter.afterChunkError(context); - adapter.afterChunk(context); - - assertEquals(3, dataQueue.size()); - assertEquals("0", dataQueue.remove()); - assertEquals("1", dataQueue.remove()); - assertEquals("2", dataQueue.remove()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/DecisionStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/DecisionStepTests.java deleted file mode 100644 index f8e28203e..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/DecisionStepTests.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step; - -import java.util.List; -import java.util.Properties; - -import jakarta.batch.api.Decider; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.StepExecution; - -import org.junit.Test; - -import org.springframework.batch.core.jsr.AbstractJsrTestCase; -import org.springframework.util.Assert; - -import static org.junit.Assert.assertEquals; - -public class DecisionStepTests extends AbstractJsrTestCase { - - @Test - public void testDecisionAsFirstStepOfJob() throws Exception { - JobExecution execution = runJob("DecisionStepTests-decisionAsFirstStep-context", new Properties(), 10000L); - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - assertEquals(0, BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()).size()); - } - - @Test - public void testDecisionThrowsException() throws Exception { - JobExecution execution = runJob("DecisionStepTests-decisionThrowsException-context", new Properties(), 10000L); - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - assertEquals(2, BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()).size()); - } - - @Test - public void testDecisionValidExitStatus() throws Exception { - JobExecution execution = runJob("DecisionStepTests-decisionValidExitStatus-context", new Properties(), 10000L); - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - assertEquals(3, BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()).size()); - } - - @Test - public void testDecisionUnmappedExitStatus() throws Exception { - JobExecution execution = runJob("DecisionStepTests-decisionInvalidExitStatus-context", new Properties(), 10000L); - assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); - List stepExecutions = BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()); - assertEquals(2, stepExecutions.size()); - - for (StepExecution curExecution : stepExecutions) { - assertEquals(BatchStatus.COMPLETED, curExecution.getBatchStatus()); - } - } - - @Test - public void testDecisionCustomExitStatus() throws Exception { - JobExecution execution = runJob("DecisionStepTests-decisionCustomExitStatus-context", new Properties(), 10000L); - assertEquals(BatchStatus.FAILED, execution.getBatchStatus()); - assertEquals(2, BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()).size()); - assertEquals("CustomFail", execution.getExitStatus()); - } - - @Test - public void testDecisionAfterFlow() throws Exception { - JobExecution execution = runJob("DecisionStepTests-decisionAfterFlow-context", new Properties(), 10000L); - assertEquals(execution.getExitStatus(), BatchStatus.COMPLETED, execution.getBatchStatus()); - assertEquals(3, BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()).size()); - } - - @Test - public void testDecisionRestart() throws Exception { - JobExecution execution = runJob("DecisionStepTests-restart-context", new Properties(), 10000L); - assertEquals(BatchStatus.STOPPED, execution.getBatchStatus()); - - List stepExecutions = BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()); - assertEquals(2, stepExecutions.size()); - - assertEquals("step1", stepExecutions.get(0).getStepName()); - assertEquals("decision1", stepExecutions.get(1).getStepName()); - - JobExecution execution2 = restartJob(execution.getExecutionId(), new Properties(), 10000L); - assertEquals(BatchStatus.COMPLETED, execution2.getBatchStatus()); - - List stepExecutions2 = BatchRuntime.getJobOperator().getStepExecutions(execution2.getExecutionId()); - assertEquals(2, stepExecutions2.size()); - - assertEquals("decision1", stepExecutions2.get(0).getStepName()); - assertEquals("step2", stepExecutions2.get(1).getStepName()); - } - - public static class RestartDecider implements Decider { - - private static int runs = 0; - - @Override - public String decide(StepExecution[] executions) throws Exception { - Assert.isTrue(executions.length == 1, "Invalid array length"); - Assert.isTrue(executions[0].getStepName().equals("step1"), "Incorrect step name"); - - if(runs == 0) { - runs++; - return "STOP_HERE"; - } else { - return "CONTINUE"; - } - } - } - - public static class NextDecider implements Decider { - - @Override - public String decide(StepExecution[] executions) throws Exception { - for(StepExecution stepExecution : executions) { - if ("customFailTest".equals(stepExecution.getStepName())) { - return "CustomFail"; - } - } - - return "next"; - } - } - - public static class FailureDecider implements Decider { - - @Override - public String decide(StepExecution[] executions) throws Exception { - throw new RuntimeException("Expected"); - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/SplitTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/SplitTests.java deleted file mode 100644 index 8fe971e91..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/SplitTests.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2020-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step; - -import java.time.Duration; -import java.time.Instant; -import java.util.EnumSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import jakarta.batch.api.AbstractBatchlet; -import jakarta.batch.api.Decider; -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.StepExecution; -import jakarta.batch.runtime.context.JobContext; -import jakarta.inject.Inject; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -/** - * @author Mahmoud Ben Hassine - */ -public class SplitTests { - - private static final Set END_STATUSES = - EnumSet.of(BatchStatus.COMPLETED, BatchStatus.FAILED, BatchStatus.STOPPED); - private final JobOperator jobOperator = BatchRuntime.getJobOperator(); - - @Test - public void testSplit() { - // given - String jobXMLName = "SplitTests-testSplit-context"; - Properties jobParameters = new Properties(); - - // when - long executionId = jobOperator.start(jobXMLName, jobParameters); - waitFor(executionId, 10); - JobExecution jobExecution = jobOperator.getJobExecution(executionId); - List stepExecutions = jobOperator.getStepExecutions(executionId); - - // then - assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus()); - assertEquals("COMPLETED", jobExecution.getExitStatus()); - assertEquals(5, stepExecutions.size()); - } - - @Test - public void testDecisionAfterSplit() { - // given - String jobXMLName = "SplitTests-testDecisionAfterSplit-context"; - Properties jobParameters = new Properties(); - - // when - long executionId = jobOperator.start(jobXMLName, jobParameters); - waitFor(executionId, 10); - JobExecution jobExecution = jobOperator.getJobExecution(executionId); - - // then - assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus()); - assertEquals(4, jobOperator.getStepExecutions(executionId).size()); - assertEquals(2, StepExecutionCountingDecider.previousStepCount); - } - - private void waitFor(long executionId, int timeoutInSeconds) { - Instant startTime = Instant.now(); - while (!END_STATUSES.contains(jobOperator.getJobExecution(executionId).getBatchStatus())) { - if ((Duration.between(Instant.now(), startTime).getSeconds() > timeoutInSeconds)) { - fail("Job processing did not complete in time"); - } - } - } - - public static class StepExecutionCountingDecider implements Decider { - - static int previousStepCount = 0; - - @Override - public String decide(StepExecution[] executions) { - previousStepCount = executions.length; - return "next"; - } - } - - public static class ExitStatusSettingBatchlet extends AbstractBatchlet { - - @Inject - JobContext jobContext; - - @Override - public String process() throws Exception { - jobContext.setExitStatus("Should be ignored"); - return null; - } - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/BatchletAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/BatchletAdapterTests.java deleted file mode 100644 index 31de2ac5d..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/BatchletAdapterTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.batchlet; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import jakarta.batch.api.Batchlet; -import jakarta.batch.operations.BatchRuntimeException; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.batch.repeat.RepeatStatus; - -public class BatchletAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private BatchletAdapter adapter; - @Mock - private Batchlet delegate; - @Mock - private StepContribution contribution; - - @Before - public void setUp() throws Exception { - adapter = new BatchletAdapter(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new BatchletAdapter(null); - } - - @Test - public void testExecuteNoExitStatus() throws Exception { - assertEquals(RepeatStatus.FINISHED, adapter.execute(contribution, new ChunkContext(null))); - - verify(delegate).process(); - } - - @Test - public void testExecuteWithExitStatus() throws Exception { - when(delegate.process()).thenReturn("my exit status"); - - assertEquals(RepeatStatus.FINISHED, adapter.execute(contribution, new ChunkContext(null))); - - verify(delegate).process(); - verify(contribution).setExitStatus(new ExitStatus("my exit status")); - } - - @Test - public void testStop() throws Exception{ - adapter.stop(); - verify(delegate).stop(); - } - - @Test(expected=BatchRuntimeException.class) - public void testStopException() throws Exception{ - doThrow(new Exception("expected")).when(delegate).stop(); - adapter.stop(); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/BatchletSupport.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/BatchletSupport.java deleted file mode 100644 index 7f7ccf341..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/BatchletSupport.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.batchlet; - -import jakarta.batch.api.Batchlet; - -public class BatchletSupport implements Batchlet { - - @Override - public String process() throws Exception { - return null; - } - - @Override - public void stop() throws Exception { - // no-op - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/FailingBatchlet.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/FailingBatchlet.java deleted file mode 100644 index 0cdf88109..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/FailingBatchlet.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.batchlet; - -import jakarta.batch.api.Batchlet; - -/** - *

- * Test batchlet that always fails. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - */ -public class FailingBatchlet implements Batchlet { - @Override - public String process() throws Exception { - throw new RuntimeException("process failed"); - } - - @Override - public void stop() throws Exception { - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/RestartBatchlet.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/RestartBatchlet.java deleted file mode 100644 index f2d60a145..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/batchlet/RestartBatchlet.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.batchlet; - -import jakarta.batch.api.Batchlet; - -public class RestartBatchlet implements Batchlet { - - private static int runCount = 0; - - @Override - public String process() throws Exception { - runCount++; - - if(runCount == 1) { - throw new RuntimeException("This is expected"); - } - - return null; - } - - @Override - public void stop() throws Exception { - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrChunkProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrChunkProcessorTests.java deleted file mode 100644 index 194f16423..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrChunkProcessorTests.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.item; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ItemProcessListener; -import org.springframework.batch.core.ItemReadListener; -import org.springframework.batch.core.ItemWriteListener; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobInterruptedException; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.step.builder.JsrSimpleStepBuilder; -import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; -import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.JobRestartException; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.support.ListItemReader; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.lang.Nullable; - -public class JsrChunkProcessorTests { - - private FailingListItemReader reader; - private FailingCountingItemProcessor processor; - private StoringItemWriter writer; - private CountingListener readListener; - private JsrSimpleStepBuilder builder; - private JobRepository repository; - private StepExecution stepExecution; - - @Before - public void setUp() throws Exception { - - List items = new ArrayList<>(); - - for (int i = 0; i < 25; i++) { - items.add("item " + i); - } - - reader = new FailingListItemReader(items); - processor = new FailingCountingItemProcessor(); - writer = new StoringItemWriter(); - readListener = new CountingListener(); - - builder = new JsrSimpleStepBuilder<>(new StepBuilder("step1")); - builder.setBatchPropertyContext(new BatchPropertyContext()); - EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder() - .addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql") - .addScript("/org/springframework/batch/core/schema-hsqldb.sql") - .build(); - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(embeddedDatabase); - factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase)); - factory.afterPropertiesSet(); - repository = factory.getObject(); - builder.repository(repository); - builder.transactionManager(new ResourcelessTransactionManager()); - stepExecution = null; - } - - @Test - public void testNoInputNoListeners() throws Exception{ - reader = new FailingListItemReader(new ArrayList<>()); - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) readListener).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, processor.count); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(0, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - } - - @Test - public void testSimpleScenarioNoListeners() throws Exception{ - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, writer.results.size()); - assertEquals(25, processor.count); - - int count = 0; - for (String curItem : writer.results) { - assertEquals("item " + count, curItem); - count++; - } - } - - @Test - public void testSimpleScenarioNoProcessor() throws Exception{ - Step step = builder.chunk(25).reader(reader).writer(writer).listener((ItemReadListener) readListener).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(0, readListener.afterProcess); - assertEquals(25, readListener.afterRead); - assertEquals(1, readListener.afterWrite); - assertEquals(0, readListener.beforeProcess); - assertEquals(26, readListener.beforeRead); - assertEquals(1, readListener.beforeWriteCount); - assertEquals(0, readListener.onProcessError); - assertEquals(0, readListener.onReadError); - assertEquals(0, readListener.onWriteError); - assertEquals(0, processor.count); - - int count = 0; - for (String curItem : writer.results) { - assertEquals("item " + count, curItem); - count++; - } - } - - @Test - public void testProcessorFilteringNoListeners() throws Exception{ - processor.filter = true; - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) readListener).build(); - - runStep(step); - - int count = 0; - for (String curItem : writer.results) { - assertEquals("item " + count, curItem); - count += 2; - } - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(13, stepExecution.getWriteCount()); - assertEquals(12, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, processor.count); - } - - @Test - public void testReadError() throws Exception{ - reader.failCount = 10; - - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) readListener).build(); - - runStep(step); - - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(9, processor.count); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(9, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(1, stepExecution.getFailureExceptions().size()); - assertEquals("expected at read index 10", stepExecution.getFailureExceptions().get(0).getMessage()); - assertEquals(9, readListener.afterProcess); - assertEquals(9, readListener.afterRead); - assertEquals(0, readListener.afterWrite); - assertEquals(9, readListener.beforeProcess); - assertEquals(10, readListener.beforeRead); - assertEquals(0, readListener.beforeWriteCount); - assertEquals(0, readListener.onProcessError); - assertEquals(1, readListener.onReadError); - assertEquals(0, readListener.onWriteError); - } - - @Test - public void testProcessError() throws Exception{ - processor.failCount = 10; - - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) readListener).build(); - - runStep(step); - - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(10, processor.count); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(10, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals("expected at process index 10", stepExecution.getFailureExceptions().get(0).getMessage()); - assertEquals(9, readListener.afterProcess); - assertEquals(10, readListener.afterRead); - assertEquals(0, readListener.afterWrite); - assertEquals(10, readListener.beforeProcess); - assertEquals(10, readListener.beforeRead); - assertEquals(0, readListener.beforeWriteCount); - assertEquals(1, readListener.onProcessError); - assertEquals(0, readListener.onReadError); - assertEquals(0, readListener.onWriteError); - } - - @Test - public void testWriteError() throws Exception{ - writer.fail = true; - - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) readListener).build(); - - runStep(step); - - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(25, processor.count); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals("expected in write", stepExecution.getFailureExceptions().get(0).getMessage()); - assertEquals(25, readListener.afterProcess); - assertEquals(25, readListener.afterRead); - assertEquals(0, readListener.afterWrite); - assertEquals(25, readListener.beforeProcess); - assertEquals(25, readListener.beforeRead); - assertEquals(1, readListener.beforeWriteCount); - assertEquals(0, readListener.onProcessError); - assertEquals(0, readListener.onReadError); - assertEquals(1, readListener.onWriteError); - } - - @Test - public void testMultipleChunks() throws Exception{ - - Step step = builder.chunk(10).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) readListener).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(25, processor.count); - assertEquals(25, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, readListener.afterProcess); - assertEquals(25, readListener.afterRead); - assertEquals(3, readListener.afterWrite); - assertEquals(25, readListener.beforeProcess); - assertEquals(26, readListener.beforeRead); - assertEquals(3, readListener.beforeWriteCount); - assertEquals(0, readListener.onProcessError); - assertEquals(0, readListener.onReadError); - assertEquals(0, readListener.onWriteError); - } - - protected void runStep(Step step) - throws JobExecutionAlreadyRunningException, JobRestartException, - JobInstanceAlreadyCompleteException, JobInterruptedException { - JobExecution jobExecution = repository.createJobExecution("job1", new JobParameters()); - stepExecution = new StepExecution("step1", jobExecution); - repository.add(stepExecution); - - step.execute(stepExecution); - } - - public static class FailingListItemReader extends ListItemReader { - - protected int failCount = -1; - protected int count = 0; - - public FailingListItemReader(List list) { - super(list); - } - - @Nullable - @Override - public String read() { - count++; - - if(failCount == count) { - throw new RuntimeException("expected at read index " + failCount); - } else { - return super.read(); - } - } - } - - public static class FailingCountingItemProcessor implements ItemProcessor{ - protected int count = 0; - protected int failCount = -1; - protected boolean filter = false; - - @Nullable - @Override - public String process(String item) throws Exception { - count++; - - if(filter && count % 2 == 0) { - return null; - } else if(count == failCount){ - throw new RuntimeException("expected at process index " + failCount); - } else { - return item; - } - } - } - - public static class StoringItemWriter implements ItemWriter{ - - protected List results = new ArrayList<>(); - protected boolean fail = false; - - @Override - public void write(List items) throws Exception { - if(fail) { - throw new RuntimeException("expected in write"); - } - - results.addAll(items); - } - } - - public static class CountingListener implements ItemReadListener, ItemProcessListener, ItemWriteListener { - - protected int beforeWriteCount = 0; - protected int afterWrite = 0; - protected int onWriteError = 0; - protected int beforeProcess = 0; - protected int afterProcess = 0; - protected int onProcessError = 0; - protected int beforeRead = 0; - protected int afterRead = 0; - protected int onReadError = 0; - - @Override - public void beforeWrite(List items) { - beforeWriteCount++; - } - - @Override - public void afterWrite(List items) { - afterWrite++; - } - - @Override - public void onWriteError(Exception exception, - List items) { - onWriteError++; - } - - @Override - public void beforeProcess(String item) { - beforeProcess++; - } - - @Override - public void afterProcess(String item, @Nullable String result) { - afterProcess++; - } - - @Override - public void onProcessError(String item, Exception e) { - onProcessError++; - } - - @Override - public void beforeRead() { - beforeRead++; - } - - @Override - public void afterRead(String item) { - afterRead++; - } - - @Override - public void onReadError(Exception ex) { - onReadError++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrChunkProviderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrChunkProviderTests.java deleted file mode 100644 index a76c12088..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrChunkProviderTests.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 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.jsr.step.item; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.step.item.Chunk; - -public class JsrChunkProviderTests { - - private JsrChunkProvider provider; - - @Before - public void setUp() throws Exception { - provider = new JsrChunkProvider<>(); - } - - @Test - public void test() throws Exception { - Chunk chunk = provider.provide(null); - assertNotNull(chunk); - assertEquals(0, chunk.getItems().size()); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrFaultTolerantChunkProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrFaultTolerantChunkProcessorTests.java deleted file mode 100644 index 375678c6e..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/item/JsrFaultTolerantChunkProcessorTests.java +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.core.jsr.step.item; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ItemProcessListener; -import org.springframework.batch.core.ItemReadListener; -import org.springframework.batch.core.ItemWriteListener; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobInterruptedException; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.SkipListener; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; -import org.springframework.batch.core.jsr.step.builder.JsrFaultTolerantStepBuilder; -import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; -import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.JobRestartException; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.support.ListItemReader; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.lang.Nullable; - -public class JsrFaultTolerantChunkProcessorTests { - - private FailingListItemReader reader; - private FailingCountingItemProcessor processor; - private StoringItemWriter writer; - private CountingListener listener; - private JsrFaultTolerantStepBuilder builder; - private JobRepository repository; - private StepExecution stepExecution; - - @Before - public void setUp() throws Exception { - - List items = new ArrayList<>(); - - for (int i = 0; i < 25; i++) { - items.add("item " + i); - } - - reader = new FailingListItemReader(items); - processor = new FailingCountingItemProcessor(); - writer = new StoringItemWriter(); - listener = new CountingListener(); - - builder = new JsrFaultTolerantStepBuilder<>(new StepBuilder("step1")); - builder.setBatchPropertyContext(new BatchPropertyContext()); - EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder() - .addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql") - .addScript("/org/springframework/batch/core/schema-hsqldb.sql") - .build(); - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(embeddedDatabase); - factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase)); - factory.afterPropertiesSet(); - repository = factory.getObject(); - builder.repository(repository); - builder.transactionManager(new ResourcelessTransactionManager()); - stepExecution = null; - } - - @Test - public void testNoInputNoListeners() throws Exception{ - reader = new FailingListItemReader(new ArrayList<>()); - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, processor.count); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(0, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - } - - @Test - public void testSimpleScenarioNoListeners() throws Exception{ - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, writer.results.size()); - assertEquals(25, processor.count); - - int count = 0; - for (String curItem : writer.results) { - assertEquals("item " + count, curItem); - count++; - } - } - - @Test - public void testSimpleScenarioNoProcessor() throws Exception{ - Step step = builder.chunk(25).reader(reader).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(0, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(1, listener.afterWrite); - assertEquals(0, listener.beforeProcess); - assertEquals(26, listener.beforeRead); - assertEquals(1, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(0, listener.onWriteError); - assertEquals(0, processor.count); - - int count = 0; - for (String curItem : writer.results) { - assertEquals("item " + count, curItem); - count++; - } - } - - @Test - public void testProcessorFilteringNoListeners() throws Exception{ - processor.filter = true; - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - int count = 0; - for (String curItem : writer.results) { - assertEquals("item " + count, curItem); - count += 2; - } - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(13, stepExecution.getWriteCount()); - assertEquals(12, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, processor.count); - } - - @Test - public void testSkipReadError() throws Exception{ - reader.failCount = 10; - - Step step = builder.faultTolerant().skip(RuntimeException.class).skipLimit(20).chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertNotNull(stepExecution); - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(25, processor.count); - assertEquals(25, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(1, stepExecution.getReadSkipCount()); - assertEquals(1, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(0, stepExecution.getFailureExceptions().size()); - assertEquals(25, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(1, listener.afterWrite); - assertEquals(25, listener.beforeProcess); - assertEquals(27, listener.beforeRead); - assertEquals(1, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(1, listener.onReadError); - assertEquals(0, listener.onWriteError); - } - - @Test - public void testRetryReadError() throws Exception{ - reader.failCount = 10; - - Step step = builder.faultTolerant().retry(RuntimeException.class).retryLimit(20).chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(25, processor.count); - assertEquals(25, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(0, stepExecution.getFailureExceptions().size()); - assertEquals(25, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(1, listener.afterWrite); - assertEquals(25, listener.beforeProcess); - assertEquals(27, listener.beforeRead); - assertEquals(1, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(1, listener.onReadError); - assertEquals(0, listener.onWriteError); - } - - @Test - public void testReadError() throws Exception{ - reader.failCount = 10; - - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertNotNull(stepExecution); - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(9, processor.count); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(9, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(1, stepExecution.getFailureExceptions().size()); - assertEquals("expected at read index 10", stepExecution.getFailureExceptions().get(0).getCause().getMessage()); - assertEquals(9, listener.afterProcess); - assertEquals(9, listener.afterRead); - assertEquals(0, listener.afterWrite); - assertEquals(9, listener.beforeProcess); - assertEquals(10, listener.beforeRead); - assertEquals(0, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(1, listener.onReadError); - assertEquals(0, listener.onWriteError); - } - - @Test - public void testProcessError() throws Exception{ - processor.failCount = 10; - - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(10, processor.count); - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(10, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals("expected at process index 10", stepExecution.getFailureExceptions().get(0).getCause().getMessage()); - assertEquals(9, listener.afterProcess); - assertEquals(10, listener.afterRead); - assertEquals(0, listener.afterWrite); - assertEquals(10, listener.beforeProcess); - assertEquals(10, listener.beforeRead); - assertEquals(0, listener.beforeWriteCount); - assertEquals(1, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(0, listener.onWriteError); - } - - @Test - public void testSkipProcessError() throws Exception{ - processor.failCount = 10; - - Step step = builder.faultTolerant().skip(RuntimeException.class).skipLimit(20).chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertNotNull(stepExecution); - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(25, processor.count); - assertEquals(24, writer.results.size()); - assertEquals(1, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(1, stepExecution.getSkipCount()); - assertEquals(24, stepExecution.getWriteCount()); - assertEquals(1, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(0, stepExecution.getFailureExceptions().size()); - assertEquals(24, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(1, listener.afterWrite); - assertEquals(25, listener.beforeProcess); - assertEquals(26, listener.beforeRead); - assertEquals(1, listener.beforeWriteCount); - assertEquals(1, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(0, listener.onWriteError); - } - - @Test - public void testRetryProcessError() throws Exception{ - processor.failCount = 10; - - Step step = builder.faultTolerant().retry(RuntimeException.class).retryLimit(20).chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertNotNull(stepExecution); - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(26, processor.count); - assertEquals(25, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(0, stepExecution.getFailureExceptions().size()); - assertEquals(25, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(1, listener.afterWrite); - assertEquals(26, listener.beforeProcess); - assertEquals(26, listener.beforeRead); - assertEquals(1, listener.beforeWriteCount); - assertEquals(1, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(0, listener.onWriteError); - } - - @Test - public void testWriteError() throws Exception{ - writer.fail = true; - - Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(25, processor.count); - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(0, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(0, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(0, listener.afterWrite); - assertEquals(25, listener.beforeProcess); - assertEquals(25, listener.beforeRead); - assertEquals(1, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(1, listener.onWriteError); - } - - @Test - public void testRetryWriteError() throws Exception{ - writer.fail = true; - - Step step = builder.faultTolerant().retry(RuntimeException.class).retryLimit(25).chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(25, processor.count); - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(25, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(1, listener.afterWrite); - assertEquals(25, listener.beforeProcess); - assertEquals(26, listener.beforeRead); - assertEquals(2, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(1, listener.onWriteError); - } - - @Test - public void testSkipWriteError() throws Exception{ - writer.fail = true; - - Step step = builder.faultTolerant().skip(RuntimeException.class).skipLimit(25).chunk(7).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(25, processor.count); - assertEquals(18, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(1, stepExecution.getSkipCount()); - assertEquals(18, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(1, stepExecution.getWriteSkipCount()); - assertEquals(25, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(3, listener.afterWrite); - assertEquals(25, listener.beforeProcess); - assertEquals(26, listener.beforeRead); - assertEquals(4, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(1, listener.onWriteError); - assertEquals(0, listener.onSkipInRead); - assertEquals(0, listener.onSkipInProcess); - assertEquals(1, listener.onSkipInWrite); - } - - @Test - public void testMultipleChunks() throws Exception{ - - Step step = builder.chunk(10).reader(reader).processor(processor).writer(writer).listener((ItemReadListener) listener).build(); - - runStep(step); - - assertEquals(25, processor.count); - assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); - assertEquals(25, writer.results.size()); - assertEquals(0, stepExecution.getProcessSkipCount()); - assertEquals(25, stepExecution.getReadCount()); - assertEquals(0, stepExecution.getReadSkipCount()); - assertEquals(0, stepExecution.getSkipCount()); - assertEquals(25, stepExecution.getWriteCount()); - assertEquals(0, stepExecution.getFilterCount()); - assertEquals(0, stepExecution.getWriteSkipCount()); - assertEquals(25, listener.afterProcess); - assertEquals(25, listener.afterRead); - assertEquals(3, listener.afterWrite); - assertEquals(25, listener.beforeProcess); - assertEquals(26, listener.beforeRead); - assertEquals(3, listener.beforeWriteCount); - assertEquals(0, listener.onProcessError); - assertEquals(0, listener.onReadError); - assertEquals(0, listener.onWriteError); - } - - protected void runStep(Step step) - throws JobExecutionAlreadyRunningException, JobRestartException, - JobInstanceAlreadyCompleteException, JobInterruptedException { - JobExecution jobExecution = repository.createJobExecution("job1", new JobParameters()); - stepExecution = new StepExecution("step1", jobExecution); - repository.add(stepExecution); - - step.execute(stepExecution); - } - - public static class FailingListItemReader extends ListItemReader { - - protected int failCount = -1; - protected int count = 0; - - public FailingListItemReader(List list) { - super(list); - } - - @Nullable - @Override - public String read() { - count++; - - if(failCount == count) { - throw new RuntimeException("expected at read index " + failCount); - } else { - return super.read(); - } - } - } - - public static class FailingCountingItemProcessor implements ItemProcessor{ - protected int count = 0; - protected int failCount = -1; - protected boolean filter = false; - - @Nullable - @Override - public String process(String item) throws Exception { - count++; - - if(filter && count % 2 == 0) { - return null; - } else if(count == failCount){ - throw new RuntimeException("expected at process index " + failCount); - } else { - return item; - } - } - } - - public static class StoringItemWriter implements ItemWriter{ - - protected List results = new ArrayList<>(); - protected boolean fail = false; - - @Override - public void write(List items) throws Exception { - if(fail) { - fail = false; - throw new RuntimeException("expected in write"); - } - - results.addAll(items); - } - } - - public static class CountingListener implements ItemReadListener, ItemProcessListener, ItemWriteListener, SkipListener> { - - protected int beforeWriteCount = 0; - protected int afterWrite = 0; - protected int onWriteError = 0; - protected int beforeProcess = 0; - protected int afterProcess = 0; - protected int onProcessError = 0; - protected int beforeRead = 0; - protected int afterRead = 0; - protected int onReadError = 0; - protected int onSkipInRead = 0; - protected int onSkipInProcess = 0; - protected int onSkipInWrite = 0; - - @Override - public void beforeWrite(List items) { - beforeWriteCount++; - } - - @Override - public void afterWrite(List items) { - afterWrite++; - } - - @Override - public void onWriteError(Exception exception, - List items) { - onWriteError++; - } - - @Override - public void beforeProcess(String item) { - beforeProcess++; - } - - @Override - public void afterProcess(String item, @Nullable String result) { - afterProcess++; - } - - @Override - public void onProcessError(String item, Exception e) { - onProcessError++; - } - - @Override - public void beforeRead() { - beforeRead++; - } - - @Override - public void afterRead(String item) { - afterRead++; - } - - @Override - public void onReadError(Exception ex) { - onReadError++; - } - - @Override - public void onSkipInRead(Throwable t) { - onSkipInRead++; - } - - @Override - public void onSkipInWrite(List items, Throwable t) { - onSkipInWrite++; - } - - @Override - public void onSkipInProcess(String item, Throwable t) { - onSkipInProcess++; - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/listener/ExitStatusSettingStepListener.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/listener/ExitStatusSettingStepListener.java deleted file mode 100644 index 12522900f..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/listener/ExitStatusSettingStepListener.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - * 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.jsr.step.listener; - -import jakarta.batch.api.BatchProperty; -import jakarta.batch.api.listener.StepListener; -import jakarta.batch.runtime.context.JobContext; -import jakarta.inject.Inject; - -/** - *

- * {@link StepListener} for testing. Sets or appends the value of the - * testProperty field to the {@link JobContext} exit status on afterStep. - *

- * - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class ExitStatusSettingStepListener implements StepListener { - @Inject - @BatchProperty - private String testProperty; - - @Inject - private JobContext jobContext; - - @Override - public void beforeStep() throws Exception { - - } - - @Override - public void afterStep() throws Exception { - String exitStatus = jobContext.getExitStatus(); - - if("".equals(exitStatus) || exitStatus == null) { - jobContext.setExitStatus(testProperty); - } else { - jobContext.setExitStatus(exitStatus + testProperty); - } - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/CommandLineJobRunnerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/CommandLineJobRunnerTests.java index 65bfccc1e..d1b77af39 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/CommandLineJobRunnerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/CommandLineJobRunnerTests.java @@ -76,7 +76,7 @@ public class CommandLineJobRunnerTests { @Before public void setUp() throws Exception { - JobExecution jobExecution = new JobExecution(null, 1L, null, null); + JobExecution jobExecution = new JobExecution(null, 1L, null); ExitStatus exitStatus = ExitStatus.COMPLETED; jobExecution.setExitStatus(exitStatus); StubJobLauncher.jobExecution = jobExecution; @@ -314,7 +314,7 @@ public class CommandLineJobRunnerTests { public void testRestartExecution() throws Throwable { String[] args = new String[] { jobPath, "-restart", "11" }; JobParameters jobParameters = new JobParametersBuilder().addString("foo", "bar").toJobParameters(); - JobExecution jobExecution = new JobExecution(new JobInstance(0L, jobName), 11L, jobParameters, null); + JobExecution jobExecution = new JobExecution(new JobInstance(0L, jobName), 11L, jobParameters); jobExecution.setStatus(BatchStatus.FAILED); StubJobExplorer.jobExecution = jobExecution; CommandLineJobRunner.main(args); @@ -326,7 +326,7 @@ public class CommandLineJobRunnerTests { public void testRestartExecutionNotFailed() throws Throwable { String[] args = new String[] { jobPath, "-restart", "11" }; JobParameters jobParameters = new JobParametersBuilder().addString("foo", "bar").toJobParameters(); - JobExecution jobExecution = new JobExecution(new JobInstance(0L, jobName), 11L, jobParameters, null); + JobExecution jobExecution = new JobExecution(new JobInstance(0L, jobName), 11L, jobParameters); jobExecution.setStatus(BatchStatus.COMPLETED); StubJobExplorer.jobExecution = jobExecution; CommandLineJobRunner.main(args); @@ -495,7 +495,7 @@ public class CommandLineJobRunnerTests { } private JobExecution createJobExecution(JobInstance jobInstance, BatchStatus status) { - JobExecution jobExecution = new JobExecution(jobInstance, 1L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 1L, jobParameters); jobExecution.setStatus(status); jobExecution.setStartTime(new Date()); if (status != BatchStatus.STARTED) { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java index 052ceeb79..888a74a72 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -111,7 +111,7 @@ public class SimpleJobOperatorTests { } }); - jobOperator.setJobLauncher((job, jobParameters) -> new JobExecution(new JobInstance(123L, job.getName()), 999L, jobParameters, null)); + jobOperator.setJobLauncher((job, jobParameters) -> new JobExecution(new JobInstance(123L, job.getName()), 999L, jobParameters)); jobExplorer = mock(JobExplorer.class); @@ -189,7 +189,7 @@ public class SimpleJobOperatorTests { @Test public void testResumeSunnyDay() throws Exception { jobParameters = new JobParameters(); - when(jobExplorer.getJobExecution(111L)).thenReturn(new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters, null)); + when(jobExplorer.getJobExecution(111L)).thenReturn(new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters)); jobExplorer.getJobExecution(111L); Long value = jobOperator.restart(111L); assertEquals(999, value.longValue()); @@ -198,7 +198,7 @@ public class SimpleJobOperatorTests { @Test public void testGetSummarySunnyDay() throws Exception { jobParameters = new JobParameters(); - JobExecution jobExecution = new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters); when(jobExplorer.getJobExecution(111L)).thenReturn(jobExecution); jobExplorer.getJobExecution(111L); String value = jobOperator.getSummary(111L); @@ -221,7 +221,7 @@ public class SimpleJobOperatorTests { public void testGetStepExecutionSummariesSunnyDay() throws Exception { jobParameters = new JobParameters(); - JobExecution jobExecution = new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters); jobExecution.createStepExecution("step1"); jobExecution.createStepExecution("step2"); jobExecution.getStepExecutions().iterator().next().setId(21L); @@ -245,7 +245,7 @@ public class SimpleJobOperatorTests { @Test public void testFindRunningExecutionsSunnyDay() throws Exception { jobParameters = new JobParameters(); - JobExecution jobExecution = new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters); when(jobExplorer.findRunningJobExecutions("foo")).thenReturn(Collections.singleton(jobExecution)); Set value = jobOperator.getRunningExecutions("foo"); assertEquals(111L, value.iterator().next().longValue()); @@ -267,7 +267,7 @@ public class SimpleJobOperatorTests { @Test public void testGetJobParametersSunnyDay() throws Exception { final JobParameters jobParameters = new JobParameters(); - when(jobExplorer.getJobExecution(111L)).thenReturn(new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters, null)); + when(jobExplorer.getJobExecution(111L)).thenReturn(new JobExecution(new JobInstance(123L, job.getName()), 111L, jobParameters)); String value = jobOperator.getParameters(111L); assertEquals("a=b", value); } @@ -318,7 +318,7 @@ public class SimpleJobOperatorTests { JobInstance jobInstance = new JobInstance(123L, job.getName()); when(jobExplorer.getJobInstance(123L)).thenReturn(jobInstance); - JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); when(jobExplorer.getJobExecutions(jobInstance)).thenReturn(Collections.singletonList(jobExecution)); List value = jobOperator.getExecutions(123L); assertEquals(111L, value.iterator().next().longValue()); @@ -339,7 +339,7 @@ public class SimpleJobOperatorTests { @Test public void testStop() throws Exception{ JobInstance jobInstance = new JobInstance(123L, job.getName()); - JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); when(jobExplorer.getJobExecution(111L)).thenReturn(jobExecution); jobExplorer.getJobExecution(111L); jobRepository.update(jobExecution); @@ -350,7 +350,7 @@ public class SimpleJobOperatorTests { @Test public void testStopTasklet() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); - JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); StoppableTasklet tasklet = mock(StoppableTasklet.class); TaskletStep taskletStep = new TaskletStep(); taskletStep.setTasklet(tasklet); @@ -375,7 +375,7 @@ public class SimpleJobOperatorTests { @Test public void testStopTaskletWhenJobNotRegistered() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); - JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); StoppableTasklet tasklet = mock(StoppableTasklet.class); JobRegistry jobRegistry = mock(JobRegistry.class); TaskletStep step = mock(TaskletStep.class); @@ -393,7 +393,7 @@ public class SimpleJobOperatorTests { @Test public void testStopTaskletException() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); - JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); StoppableTasklet tasklet = new StoppableTasklet() { @Nullable @@ -430,7 +430,7 @@ public class SimpleJobOperatorTests { @Test public void testAbort() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); - JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); jobExecution.setStatus(BatchStatus.STOPPING); when(jobExplorer.getJobExecution(123L)).thenReturn(jobExecution); jobRepository.update(jobExecution); @@ -442,7 +442,7 @@ public class SimpleJobOperatorTests { @Test(expected = JobExecutionAlreadyRunningException.class) public void testAbortNonStopping() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); - JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); jobExecution.setStatus(BatchStatus.STARTED); when(jobExplorer.getJobExecution(123L)).thenReturn(jobExecution); jobRepository.update(jobExecution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/partition/support/MultiResourcePartitionerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/partition/support/MultiResourcePartitionerTests.java index 19e99d8ca..abc939fc1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/partition/support/MultiResourcePartitionerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/partition/support/MultiResourcePartitionerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2017 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. @@ -36,7 +36,7 @@ public class MultiResourcePartitionerTests { @Before public void setUp() { ResourceArrayPropertyEditor editor = new ResourceArrayPropertyEditor(); - editor.setAsText("classpath:jsrBaseContext.xml"); + editor.setAsText("classpath:simple-job-launcher-context.xml"); partitioner.setResources((Resource[]) editor.getValue()); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobDaoTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobDaoTests.java index 18522d0c4..6f6b66594 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobDaoTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobDaoTests.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. @@ -42,6 +42,7 @@ import org.springframework.transaction.annotation.Transactional; /** * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public abstract class AbstractJobDaoTests { @@ -185,7 +186,7 @@ public abstract class AbstractJobDaoTests { public void testUpdateInvalidJobExecution() { // id is invalid - JobExecution execution = new JobExecution(jobInstance, (long) 29432, jobParameters, null); + JobExecution execution = new JobExecution(jobInstance, (long) 29432, jobParameters); execution.incrementVersion(); try { jobExecutionDao.updateJobExecution(execution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractStepExecutionDaoTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractStepExecutionDaoTests.java index 1a72196cc..5640a83a5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractStepExecutionDaoTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractStepExecutionDaoTests.java @@ -222,7 +222,7 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona @Transactional @Test public void testGetForNotExistingJobExecution() { - assertNull(dao.getStepExecution(new JobExecution(jobInstance, (long) 777, new JobParameters(), null), 11L)); + assertNull(dao.getStepExecution(new JobExecution(jobInstance, (long) 777, new JobParameters()), 11L)); } /** diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDaoTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDaoTests.java index 0a235d74d..31061ff95 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDaoTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDaoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2014 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. @@ -68,7 +68,7 @@ public class JdbcJobInstanceDaoTests extends AbstractJobInstanceDaoTests { JobParameters jobParameters = new JobParameters(); JobInstance jobInstance = dao.createJobInstance("testInstance", jobParameters); - JobExecution jobExecution = new JobExecution(jobInstance, 2L, jobParameters, null); + JobExecution jobExecution = new JobExecution(jobInstance, 2L, jobParameters); jobExecutionDao.saveJobExecution(jobExecution); JobInstance returnedInstance = dao.getJobInstance(jobExecution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java index 0609c43e7..327bf1e36 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.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. @@ -59,6 +59,7 @@ import org.springframework.batch.core.step.StepSupport; * @author Will Schipp * @author Dimitrios Liapis * @author Baris Cubukcuoglu + * @author Mahmoud Ben Hassine * */ public class SimpleJobRepositoryTests { @@ -126,7 +127,7 @@ public class SimpleJobRepositoryTests { steps.add(databaseStep1); steps.add(databaseStep2); - jobExecution = new JobExecution(new JobInstance(1L, job.getName()), 1L, jobParameters, null); + jobExecution = new JobExecution(new JobInstance(1L, job.getName()), 1L, jobParameters); } @Test @@ -146,7 +147,7 @@ public class SimpleJobRepositoryTests { @Test public void testUpdateValidJobExecution() throws Exception { - JobExecution jobExecution = new JobExecution(new JobInstance(1L, job.getName()), 1L, jobParameters, null); + JobExecution jobExecution = new JobExecution(new JobInstance(1L, job.getName()), 1L, jobParameters); // new execution - call update on job DAO jobExecutionDao.updateJobExecution(jobExecution); jobRepository.update(jobExecution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/ChunkContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/ChunkContextTests.java index d6c7eb54f..6d833ad06 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/ChunkContextTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/ChunkContextTests.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. @@ -30,12 +30,13 @@ import org.springframework.batch.core.JobParameters; /** * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public class ChunkContextTests { private ChunkContext context = new ChunkContext(new StepContext(new JobExecution(new JobInstance(0L, - "job"), 1L, new JobParameters(Collections.singletonMap("foo", new JobParameter("bar"))), null) + "job"), 1L, new JobParameters(Collections.singletonMap("foo", new JobParameter("bar")))) .createStepExecution("foo"))); @Test diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java index e0b70a668..4c795d1ab 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -32,7 +32,6 @@ import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; import org.springframework.batch.item.ExecutionContext; /** @@ -45,12 +44,10 @@ public class StepContextTests { private List list = new ArrayList<>(); - private StepExecution stepExecution = new StepExecution("step", new JobExecution(new JobInstance(2L, "job"), 0L, null, null), 1L); + private StepExecution stepExecution = new StepExecution("step", new JobExecution(new JobInstance(2L, "job"), 0L, null), 1L); private StepContext context = new StepContext(stepExecution); - private BatchPropertyContext propertyContext = new BatchPropertyContext(); - @Test public void testGetStepExecution() { context = new StepContext(stepExecution); @@ -68,19 +65,6 @@ public class StepContextTests { } } - @Test - public void testGetPartitionPlan() { - Properties partitionPropertyValues = new Properties(); - partitionPropertyValues.put("key1", "value1"); - - propertyContext.setStepProperties(stepExecution.getStepName(), partitionPropertyValues); - - context = new StepContext(stepExecution, propertyContext); - - Map plan = context.getPartitionPlan(); - assertEquals("value1", plan.get("key1")); - } - @Test public void testEqualsSelf() { assertEquals(context, context); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepSynchronizationManagerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepSynchronizationManagerTests.java index aee4e105e..215501bd4 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepSynchronizationManagerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepSynchronizationManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-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. @@ -32,12 +32,10 @@ import org.junit.Before; import org.junit.Test; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext; public class StepSynchronizationManagerTests { private StepExecution stepExecution = new StepExecution("step", new JobExecution(0L)); - private BatchPropertyContext propertyContext = new BatchPropertyContext(); @Before @After @@ -54,16 +52,6 @@ public class StepSynchronizationManagerTests { assertNotNull(StepSynchronizationManager.getContext()); } - @Test - public void testGetContextWithBatchProperties() { - StepContext context = StepSynchronizationManager.getContext(); - assertNull(context); - StepSynchronizationManager.register(stepExecution, propertyContext); - context = StepSynchronizationManager.getContext(); - assertNotNull(context); - assertEquals(stepExecution, context.getStepExecution()); - } - @Test public void testClose() throws Exception { final List list = new ArrayList<>(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/JobRepositorySupport.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/JobRepositorySupport.java index 6ef540fdc..a190681c1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/JobRepositorySupport.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/JobRepositorySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -27,6 +27,7 @@ import org.springframework.lang.Nullable; /** * @author Dave Syer * @author David Turanski + * @author Mahmoud Ben Hassine * */ public class JobRepositorySupport implements JobRepository { @@ -37,7 +38,7 @@ public class JobRepositorySupport implements JobRepository { @Override public JobExecution createJobExecution(String jobName, JobParameters jobParameters) { JobInstance jobInstance = new JobInstance(0L, jobName); - return new JobExecution(jobInstance, 11L, jobParameters, null); + return new JobExecution(jobInstance, 11L, jobParameters); } /* (non-Javadoc) @@ -112,9 +113,4 @@ public class JobRepositorySupport implements JobRepository { return null; } - @Override - public JobExecution createJobExecution(JobInstance jobInstance, - JobParameters jobParameters, String jobConfigurationLocation) { - return null; - } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java index 4a22fd629..790607d27 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java @@ -584,11 +584,6 @@ public class TaskletStepExceptionTests { return null; } - @Override - public JobExecution createJobExecution(JobInstance jobInstance, - JobParameters jobParameters, String jobConfigurationLocation) { - return null; - } } @SuppressWarnings("serial") diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java index 1602d92e2..85c2ac6ae 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java @@ -58,7 +58,7 @@ public class SystemCommandTaskletIntegrationTests { private SystemCommandTasklet tasklet; private StepExecution stepExecution = new StepExecution("systemCommandStep", new JobExecution(new JobInstance(1L, - "systemCommandJob"), 1L, new JobParameters(), "configurationName")); + "systemCommandJob"), 1L, new JobParameters())); @Mock private JobExplorer jobExplorer; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/StepExecutionSerializationUtilsTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/StepExecutionSerializationUtilsTests.java index 6d743b342..9327e7585 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/StepExecutionSerializationUtilsTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/StepExecutionSerializationUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2014 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,13 +35,14 @@ import org.springframework.util.SerializationUtils; /** * @author Dave Syer * @author Michael Minella + * @author Mahmoud Ben Hassine */ public class StepExecutionSerializationUtilsTests { @Test public void testCycle() throws Exception { StepExecution stepExecution = new StepExecution("step", new JobExecution(new JobInstance(123L, - "job"), 321L, new JobParameters(), null), 11L); + "job"), 321L, new JobParameters()), 11L); stepExecution.getExecutionContext().put("foo.bar.spam", 123); StepExecution result = getCopy(stepExecution); assertEquals(stepExecution, result); @@ -58,7 +59,7 @@ public class StepExecutionSerializationUtilsTests { CompletionService completionService = new ExecutorCompletionService<>(executor); for (int i = 0; i < repeats; i++) { - final JobExecution jobExecution = new JobExecution(new JobInstance(123L, "job"), 321L, new JobParameters(), null); + final JobExecution jobExecution = new JobExecution(new JobInstance(123L, "job"), 321L, new JobParameters()); for (int j = 0; j < threads; j++) { completionService.submit(new Callable() { @Override diff --git a/spring-batch-core/src/test/resources/META-INF/alternativeJsrBaseContext.xml b/spring-batch-core/src/test/resources/META-INF/alternativeJsrBaseContext.xml deleted file mode 100644 index 298ec1347..000000000 --- a/spring-batch-core/src/test/resources/META-INF/alternativeJsrBaseContext.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionAfterFlow-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionAfterFlow-context.xml deleted file mode 100644 index 59e39409a..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionAfterFlow-context.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionAsFirstStep-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionAsFirstStep-context.xml deleted file mode 100644 index f1e2cb9b2..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionAsFirstStep-context.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionCustomExitStatus-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionCustomExitStatus-context.xml deleted file mode 100644 index 51333699a..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionCustomExitStatus-context.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionInvalidExitStatus-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionInvalidExitStatus-context.xml deleted file mode 100644 index 64f8874ca..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionInvalidExitStatus-context.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionThrowsException-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionThrowsException-context.xml deleted file mode 100644 index ecbf2f970..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionThrowsException-context.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionValidExitStatus-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionValidExitStatus-context.xml deleted file mode 100644 index 8b06afcd4..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-decisionValidExitStatus-context.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-restart-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-restart-context.xml deleted file mode 100644 index 1742e2d77..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/DecisionStepTests-restart-context.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/ExceptionHandlingParsingTests-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/ExceptionHandlingParsingTests-context.xml deleted file mode 100644 index 57b584f9c..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/ExceptionHandlingParsingTests-context.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - One - Two - - - - - - - - Three - Four - - - - - - - - Five - Six - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTests-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTests-context.xml deleted file mode 100644 index cce7a773f..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTests-context.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsStepGetsFailedTransitionWhenNextAttributePresent.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsStepGetsFailedTransitionWhenNextAttributePresent.xml deleted file mode 100644 index aac5d92bf..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsStepGetsFailedTransitionWhenNextAttributePresent.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsStepNoOverrideWhenNextAndFailedTransitionElementExists.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsStepNoOverrideWhenNextAndFailedTransitionElementExists.xml deleted file mode 100644 index 2f1cde9e4..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsStepNoOverrideWhenNextAndFailedTransitionElementExists.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsWildcardAndNextAttrJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsWildcardAndNextAttrJob.xml deleted file mode 100644 index 959e5e450..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/FlowParserTestsWildcardAndNextAttrJob.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/ItemSkipParsingTests-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/ItemSkipParsingTests-context.xml deleted file mode 100644 index 5a4a5416f..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/ItemSkipParsingTests-context.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/SplitTests-testDecisionAfterSplit-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/SplitTests-testDecisionAfterSplit-context.xml deleted file mode 100644 index 487a762ef..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/SplitTests-testDecisionAfterSplit-context.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/SplitTests-testSplit-context.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/SplitTests-testSplit-context.xml deleted file mode 100644 index 31591ac19..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/SplitTests-testSplit-context.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - One - Two - Three - Four - Five - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/contextClosingTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/contextClosingTests.xml deleted file mode 100644 index c1b6a6e20..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/contextClosingTests.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserTests.xml deleted file mode 100644 index f2c71af80..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserTests.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithHardcodedPropertiesTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithHardcodedPropertiesTests.xml deleted file mode 100644 index 302125f50..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithHardcodedPropertiesTests.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithMapperPropertiesTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithMapperPropertiesTests.xml deleted file mode 100644 index b41e97126..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithMapperPropertiesTests.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithPropertiesTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithPropertiesTests.xml deleted file mode 100644 index b1b15de4b..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/fullPartitionParserWithPropertiesTests.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jobWithEndTransition.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jobWithEndTransition.xml deleted file mode 100644 index d31dc6640..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jobWithEndTransition.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestBeanCreationException.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestBeanCreationException.xml deleted file mode 100644 index 806f9ef99..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestBeanCreationException.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestJob.xml deleted file mode 100644 index 730f521c8..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestJob.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestNonRestartableJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestNonRestartableJob.xml deleted file mode 100644 index 3ce335123..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestNonRestartableJob.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestRestartAbandonJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestRestartAbandonJob.xml deleted file mode 100644 index c73264625..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestRestartAbandonJob.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestRestartJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestRestartJob.xml deleted file mode 100644 index 120dfdcd9..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobOperatorTestRestartJob.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobPropertyTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobPropertyTests.xml deleted file mode 100644 index 31a5cf2e2..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobPropertyTests.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobPropertyTestsContext.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobPropertyTestsContext.xml deleted file mode 100644 index fff9d7978..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrJobPropertyTestsContext.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrPartitionHandlerRestartWithOverrideJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrPartitionHandlerRestartWithOverrideJob.xml deleted file mode 100644 index f83c508d4..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrPartitionHandlerRestartWithOverrideJob.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml deleted file mode 100644 index caa838a55..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrSpringInstanceTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrSpringInstanceTests.xml deleted file mode 100644 index ebe602acf..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrSpringInstanceTests.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrUniqueInstanceTests.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrUniqueInstanceTests.xml deleted file mode 100644 index aab71ad34..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/jsrUniqueInstanceTests.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/longRunningJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/longRunningJob.xml deleted file mode 100644 index fc3e208e5..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/longRunningJob.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/partitionParserTestsBatchlet.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/partitionParserTestsBatchlet.xml deleted file mode 100644 index 6aef4f36a..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/partitionParserTestsBatchlet.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/partitionParserTestsChunk.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/partitionParserTestsChunk.xml deleted file mode 100644 index 6a9cf53a8..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/partitionParserTestsChunk.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch-jobs/threadLocalClassloaderBeanPostProcessorTestsJob.xml b/spring-batch-core/src/test/resources/META-INF/batch-jobs/threadLocalClassloaderBeanPostProcessorTestsJob.xml deleted file mode 100644 index e542a5d7a..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch-jobs/threadLocalClassloaderBeanPostProcessorTestsJob.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/META-INF/batch.xml b/spring-batch-core/src/test/resources/META-INF/batch.xml deleted file mode 100644 index 347468b4c..000000000 --- a/spring-batch-core/src/test/resources/META-INF/batch.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/ChunkListenerParsingTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/ChunkListenerParsingTests-context.xml deleted file mode 100644 index 70c40f2da..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/ChunkListenerParsingTests-context.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - One - Two - - - - - - - - Three - Four - - - - - - - - Five - Six - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/CustomWiredJsrJobOperatorTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/CustomWiredJsrJobOperatorTests-context.xml deleted file mode 100644 index 98b068b62..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/CustomWiredJsrJobOperatorTests-context.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/ItemListenerParsingTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/ItemListenerParsingTests-context.xml deleted file mode 100644 index e1a26a1b9..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/ItemListenerParsingTests-context.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - One - Two - - - - - - - - Three - Four - - - - - - - - Five - Six - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JobListenerParsingTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JobListenerParsingTests-context.xml deleted file mode 100644 index 84d3160ed..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JobListenerParsingTests-context.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JobPropertySubstitutionTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JobPropertySubstitutionTests-context.xml deleted file mode 100644 index 8079fe32c..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JobPropertySubstitutionTests-context.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParsingTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParsingTests-context.xml deleted file mode 100644 index c574daf77..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/JsrDecisionParsingTests-context.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryListenerTestBase-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryListenerTestBase-context.xml deleted file mode 100644 index 96cdf409f..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryListenerTestBase-context.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerExhausted.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerExhausted.xml deleted file mode 100644 index 37763e169..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerExhausted.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerListenerException.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerListenerException.xml deleted file mode 100644 index 0fadd800f..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerListenerException.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerRetryOnce.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerRetryOnce.xml deleted file mode 100644 index c5b6f9d63..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/RetryReadListenerRetryOnce.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/SimpleItemBasedJobParsingTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/SimpleItemBasedJobParsingTests-context.xml deleted file mode 100644 index f5456637d..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/SimpleItemBasedJobParsingTests-context.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - One - Two - Three - Four - Five - - - - - - - - One - Two - Three - Four - Five - - - - - - - - One - Two - - - - - - - - One - Two - Three - Four - Five - Six - Seven - Eight - Nine - Ten - Eleven - Twelve - Thirteen - Fourteen - Fifteen - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/SimpleJobParsingTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/SimpleJobParsingTests-context.xml deleted file mode 100644 index fec01304c..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/SimpleJobParsingTests-context.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/StepListenerParsingTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/StepListenerParsingTests-context.xml deleted file mode 100644 index bcec64d6f..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/StepListenerParsingTests-context.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/batch.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/batch.xml deleted file mode 100644 index 6c798fdbd..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/batch.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/default-split-task-executor-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/default-split-task-executor-context.xml deleted file mode 100644 index f5aa8de52..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/default-split-task-executor-context.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - One - Two - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/invalid-split-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/invalid-split-context.xml deleted file mode 100644 index 02422db4b..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/invalid-split-context.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/override_batch.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/override_batch.xml deleted file mode 100644 index 7649e1569..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/override_batch.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/user-specified-split-task-executor-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/user-specified-split-task-executor-context.xml deleted file mode 100644 index 6d50f5918..000000000 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/jsr/configuration/xml/user-specified-split-task-executor-context.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - One - Two - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/schema-prefix-hsqldb.sql b/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/schema-prefix-hsqldb.sql index b2c93d6bf..857fe2191 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/schema-prefix-hsqldb.sql +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/repository/dao/schema-prefix-hsqldb.sql @@ -28,7 +28,6 @@ CREATE TABLE PREFIX_JOB_EXECUTION ( EXIT_CODE VARCHAR(20) , EXIT_MESSAGE VARCHAR(2500) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint PREFIX_JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references PREFIX_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; @@ -68,7 +67,7 @@ CREATE TABLE PREFIX_STEP_EXECUTION ( constraint PREFIX_JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID) references PREFIX_JOB_EXECUTION(JOB_EXECUTION_ID) ) ; - + CREATE TABLE PREFIX_STEP_EXECUTION_CONTEXT ( STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY, SHORT_CONTEXT VARCHAR(2500) NOT NULL, @@ -76,7 +75,7 @@ CREATE TABLE PREFIX_STEP_EXECUTION_CONTEXT ( constraint PREFIX_STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID) references PREFIX_STEP_EXECUTION(STEP_EXECUTION_ID) ) ; - + CREATE TABLE PREFIX_JOB_EXECUTION_CONTEXT ( JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY, SHORT_CONTEXT VARCHAR(2500) NOT NULL, @@ -84,13 +83,13 @@ CREATE TABLE PREFIX_JOB_EXECUTION_CONTEXT ( constraint PREFIX_JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID) references PREFIX_JOB_EXECUTION(JOB_EXECUTION_ID) ) ; - -CREATE TABLE PREFIX_STEP_EXECUTION_SEQ ( - ID BIGINT IDENTITY -); -CREATE TABLE PREFIX_JOB_EXECUTION_SEQ ( - ID BIGINT IDENTITY -); -CREATE TABLE PREFIX_JOB_SEQ ( - ID BIGINT IDENTITY -); + +CREATE TABLE PREFIX_STEP_EXECUTION_SEQ ( + ID BIGINT IDENTITY +); +CREATE TABLE PREFIX_JOB_EXECUTION_SEQ ( + ID BIGINT IDENTITY +); +CREATE TABLE PREFIX_JOB_SEQ ( + ID BIGINT IDENTITY +); diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/schema-hsqldb-extended.sql b/spring-batch-core/src/test/resources/org/springframework/batch/core/schema-hsqldb-extended.sql index 4612aec20..66959b5e1 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/schema-hsqldb-extended.sql +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/schema-hsqldb-extended.sql @@ -23,7 +23,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(10000) , EXIT_MESSAGE VARCHAR(10000) , LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-docs/src/assembly/dist.xml b/spring-batch-docs/src/assembly/dist.xml index 265cd7595..ac94746ea 100644 --- a/spring-batch-docs/src/assembly/dist.xml +++ b/spring-batch-docs/src/assembly/dist.xml @@ -24,13 +24,6 @@ docs/api - - ../spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml - schema/batch - - *.xsd - - ../spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml schema/batch diff --git a/spring-batch-docs/src/assembly/schemas.xml b/spring-batch-docs/src/assembly/schemas.xml index def76e180..e721bf19f 100644 --- a/spring-batch-docs/src/assembly/schemas.xml +++ b/spring-batch-docs/src/assembly/schemas.xml @@ -7,13 +7,6 @@ false - - ../spring-batch-core/src/main/resources/org/springframework/batch/core/jsr/configuration/xml - batch - - *.xsd - - ../spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml batch diff --git a/spring-batch-docs/src/main/asciidoc/index-single.adoc b/spring-batch-docs/src/main/asciidoc/index-single.adoc index b1f568c08..621463a53 100644 --- a/spring-batch-docs/src/main/asciidoc/index-single.adoc +++ b/spring-batch-docs/src/main/asciidoc/index-single.adoc @@ -32,8 +32,6 @@ include::testing.adoc[] include::common-patterns.adoc[] -include::jsr-352.adoc[] - include::spring-batch-integration.adoc[] include::monitoring-and-metrics.adoc[] diff --git a/spring-batch-docs/src/main/asciidoc/index.adoc b/spring-batch-docs/src/main/asciidoc/index.adoc index 6773cd441..c83eef9b3 100644 --- a/spring-batch-docs/src/main/asciidoc/index.adoc +++ b/spring-batch-docs/src/main/asciidoc/index.adoc @@ -28,8 +28,6 @@ parallel steps, remote chunking and partitioning. <> :: Job and Step testing facilities and APIs. <> :: Common batch processing patterns and guidelines. -<> :: JSR-352 support, similarities and differences -with Spring Batch. <> :: Integration between Spring Batch and Spring Integration projects. <> :: Batch jobs diff --git a/spring-batch-docs/src/main/asciidoc/jsr-352.adoc b/spring-batch-docs/src/main/asciidoc/jsr-352.adoc deleted file mode 100644 index 53b46da80..000000000 --- a/spring-batch-docs/src/main/asciidoc/jsr-352.adoc +++ /dev/null @@ -1,620 +0,0 @@ -:batch-asciidoc: ./ -:toc: left -:toclevels: 4 - -[[jsr-352]] - -== JSR-352 Support - -ifndef::onlyonetoggle[] -include::toggle.adoc[] -endif::onlyonetoggle[] - -As of Spring Batch 3.0 support for JSR-352 has been fully implemented. This section is not a replacement for -the spec itself and instead, intends to explain how the JSR-352 specific concepts apply to Spring Batch. -Additional information on JSR-352 can be found via the -JCP here: link:$$https://jcp.org/en/jsr/detail?id=352$$[https://jcp.org/en/jsr/detail?id=352] - -[[jsrGeneralNotes]] - - -=== General Notes about Spring Batch and JSR-352 - -Spring Batch and JSR-352 are structurally the same. They both have jobs that are made up of steps. They -both have readers, processors, writers, and listeners. However, their interactions are subtly different. -For example, the `org.springframework.batch.core.SkipListener#onSkipInWrite(S item, Throwable t)` -within Spring Batch receives two parameters: the item that was skipped and the Exception that caused the -skip. The JSR-352 version of the same method -(`jakarta.batch.api.chunk.listener.SkipWriteListener#onSkipWriteItem(List<Object> items, Exception ex)`) -also receives two parameters. However the first one is a `List` of all the items -within the current chunk with the second being the `Exception` that caused the skip. -Because of these differences, it is important to note that there are two paths to execute a job within -Spring Batch: either a traditional Spring Batch job or a JSR-352 based job. While the use of Spring Batch -artifacts (readers, writers, etc) will work within a job configured with JSR-352's JSL and executed with the -`JsrJobOperator`, they will behave according to the rules of JSR-352. It is also -important to note that batch artifacts that have been developed against the JSR-352 interfaces will not work -within a traditional Spring Batch job. - -[[jsrSetup]] - - -=== Setup - -[[jsrSetupContexts]] - - -==== Application Contexts - -All JSR-352 based jobs within Spring Batch consist of two application contexts. A parent context, that -contains beans related to the infrastructure of Spring Batch such as the `JobRepository`, -`PlatformTransactionManager`, etc and a child context that consists of the configuration -of the job to be run. The parent context is defined via the `jsrBaseContext.xml` provided -by the framework. This context may be overridden by setting the `JSR-352-BASE-CONTEXT` system -property. - - -[NOTE] -==== -The base context is not processed by the JSR-352 processors for things like property injection so -no components requiring that additional processing should be configured there. - -==== - - -[[jsrSetupLaunching]] - - -==== Launching a JSR-352 based job - -JSR-352 requires a very simple path to executing a batch job. The following code is all that is needed to -execute your first batch job: - - - -[source, java] ----- -JobOperator operator = BatchRuntime.getJobOperator(); -jobOperator.start("myJob", new Properties()); ----- - -While that is convenient for developers, the devil is in the details. Spring Batch bootstraps a bit of -infrastructure behind the scenes that a developer may want to override. The following is bootstrapped the -first time `BatchRuntime.getJobOperator()` is called: - -|=============== -|__Bean Name__|__Default Configuration__|__Notes__ -| - dataSource - | - Apache DBCP BasicDataSource with configured values. - | - By default, HSQLDB is bootstrapped. - -|`transactionManager`|`org.springframework.jdbc.datasource.DataSourceTransactionManager`| - References the dataSource bean defined above. - -| - A Datasource initializer - || - This is configured to execute the scripts configured via the - `batch.drop.script` and `batch.schema.script` properties. By - default, the schema scripts for HSQLDB are executed. This behavior can be disabled by setting the - `batch.data.source.init` property. - -| - jobRepository - | - A JDBC based `SimpleJobRepository`. - | - This `JobRepository` uses the previously mentioned data source and transaction - manager. The schema's table prefix is configurable (defaults to BATCH_) via the - `batch.table.prefix` property. - -| - jobLauncher - |`org.springframework.batch.core.launch.support.SimpleJobLauncher`| - Used to launch jobs. - -| - batchJobOperator - |`org.springframework.batch.core.launch.support.SimpleJobOperator`| - The `JsrJobOperator` wraps this to provide most of it's functionality. - -| - jobExplorer - |`org.springframework.batch.core.explore.support.JobExplorerFactoryBean`| - Used to address lookup functionality provided by the `JsrJobOperator`. - -| - jobParametersConverter - |`org.springframework.batch.core.jsr.JsrJobParametersConverter`| - JSR-352 specific implementation of the `JobParametersConverter`. - -| - jobRegistry - |`org.springframework.batch.core.configuration.support.MapJobRegistry`| - Used by the `SimpleJobOperator`. - -| - placeholderProperties - |`org.springframework.beans.factory.config.PropertyPlaceholderConfigure`| - Loads the properties file `batch-${ENVIRONMENT:hsql}.properties` to configure - the properties mentioned above. ENVIRONMENT is a System property (defaults to `hsql`) - that can be used to specify any of the supported databases Spring Batch currently - supports. - - -|=============== - - - - - - -[NOTE] -==== -None of the above beans are optional for executing JSR-352 based jobs. All may be overridden to -provide customized functionality as needed. -==== - - -[[dependencyInjection]] - - -=== Dependency Injection - -JSR-352 is based heavily on the Spring Batch programming model. As such, while not explicitly requiring a -formal dependency injection implementation, DI of some kind implied. Spring Batch supports all three -methods for loading batch artifacts defined by JSR-352: - - -* Implementation Specific Loader: Spring Batch is built upon Spring and so supports -Spring dependency injection within JSR-352 batch jobs. -* Archive Loader: JSR-352 defines the existing of a `batch.xml` file that provides mappings -between a logical name and a class name. This file must be found within the `/META-INF/` -directory if it is used. -* Thread Context Class Loader: JSR-352 allows configurations to specify batch artifact -implementations in their JSL by providing the fully qualified class name inline. Spring -Batch supports this as well in JSR-352 configured jobs. - -To use Spring dependency injection within a JSR-352 based batch job consists of -configuring batch artifacts using a Spring application context as beans. Once the beans -have been defined, a job can refer to them as it would any bean defined within the -`batch.xml` file. - -[role="xmlContent"] -The following example shows how to use Spring dependency injection within a JSR-352 based -batch job in XML: - -.XML Configuration -[source, xml, role="xmlContent"] ----- - - - - - - - - - - - - - - - ----- - -[role="javaContent"] -The following example shows how to use Spring dependency injection within a JSR-352 based -batch job in Java: - -.Java Configuration -[source, java, role="javaContent"] ----- -@Configuration -public class BatchConfiguration { - - @Bean - public Batchlet fooBatchlet() { - FooBatchlet batchlet = new FooBatchlet(); - batchlet.setProp("bar"); - return batchlet; - } -} - - - - - - - - ----- - -The assembly of Spring contexts (imports, etc) works with JSR-352 jobs just as it would with any other -Spring based application. The only difference with a JSR-352 based job is that the entry point for the -context definition will be the job definition found in /META-INF/batch-jobs/. - -To use the thread context class loader approach, all you need to do is provide the fully qualified class -name as the ref. It is important to note that when using this approach or the `batch.xml` approach, the class -referenced requires a no argument constructor which will be used to create the bean. - - -[source, xml] ----- - - - - - - - ----- - -[[jsrJobProperties]] - - -=== Batch Properties - -[[jsrPropertySupport]] - - -==== Property Support - -JSR-352 allows for properties to be defined at the Job, Step and batch artifact level by way of -configuration in the JSL. Batch properties are configured at each level in the following way: - - -[source, xml] ----- - - - - ----- - - -`Properties` may be configured on any batch artifact. - -[[jsrBatchPropertyAnnotation]] - - -==== @BatchProperty annotation - -`Properties` are referenced in batch artifacts by annotating class fields with the -`@BatchProperty` and `@Inject` annotations (both annotations -are required by the spec). As defined by JSR-352, fields for properties must be String typed. Any type -conversion is up to the implementing developer to perform. - -An `jakarta.batch.api.chunk.ItemReader` artifact could be configured with a -properties block such as the one described above and accessed as such: - - -[source, java] ----- -public class MyItemReader extends AbstractItemReader { - @Inject - @BatchProperty - private String propertyName1; - - ... -} ----- - - -The value of the field "propertyName1" will be "propertyValue1" - -[[jsrPropertySubstitution]] - - -==== Property Substitution - -Property substitution is provided by way of operators and simple conditional expressions. The general -usage is `#{operator['key']}`. - -Supported operators: - -* `jobParameters`: access job parameter values that the job was started/restarted with. -* `jobProperties`: access properties configured at the job level of the JSL. -* `systemProperties`: access named system properties. -* `partitionPlan`: access named property from the partition plan of a partitioned step. - ----- -#{jobParameters['unresolving.prop']}?:#{systemProperties['file.separator']} ----- - -The left hand side of the assignment is the expected value, the right hand side is the -default value. In the preceding - example, the result will resolve to a value of the system property file.separator as - #{jobParameters['unresolving.prop']} is assumed to not be resolvable. If neither -expressions can be resolved, an empty String will be returned. Multiple conditions can be -used, which are separated by a ';'. - - -[[jsrProcessingModels]] - -=== Processing Models - -JSR-352 provides the same two basic processing models that Spring Batch does: - -* Item based processing - Using an `jakarta.batch.api.chunk.ItemReader`, an optional -`jakarta.batch.api.chunk.ItemProcessor`, and an `jakarta.batch.api.chunk.ItemWriter`. -* Task based processing - Using a `jakarta.batch.api.Batchlet` -implementation. This processing model is the same as the -`org.springframework.batch.core.step.tasklet.Tasklet` based processing -currently available. - - -==== Item based processing - -Item based processing in this context is a chunk size being set by the number of items read by an -`ItemReader`. To configure a step this way, specify the -`item-count` (which defaults to 10) and optionally configure the -`checkpoint-policy` as item (this is the default). - - -[source, xml] ----- -... - - - - - - - -... ----- - -If item-based checkpointing is chosen, an additional attribute `time-limit` is supported. -This sets a time limit for how long the number of items specified has to be processed. If -the timeout is reached, the chunk will complete with however many items have been read by -then regardless of what the `item-count` is configured to be. - - -==== Custom checkpointing - -JSR-352 calls the process around the commit interval within a step "checkpointing". -Item-based checkpointing is one approach as mentioned above. However, this is not robust -enough in many cases. Because of this, the spec allows for the implementation of a custom -checkpointing algorithm by implementing the `jakarta.batch.api.chunk.CheckpointAlgorithm` -interface. This functionality is functionally the same as Spring Batch's custom completion -policy. To use an implementation of `CheckpointAlgorithm`, configure your step with the -custom `checkpoint-policy` as shown below where `fooCheckpointer` refers to an -implementation of `CheckpointAlgorithm`. - - -[source, xml] ----- -... - - - - - - - - -... ----- - -[[jsrRunningAJob]] - -=== Running a job - -The entrance to executing a JSR-352 based job is through the -`jakarta.batch.operations.JobOperator`. Spring Batch provides its own implementation of -this interface (`org.springframework.batch.core.jsr.launch.JsrJobOperator`). This -implementation is loaded via the `jakarta.batch.runtime.BatchRuntime`. Launching a -JSR-352 based batch job is implemented as follows: - - -[source, java] ----- - -JobOperator jobOperator = BatchRuntime.getJobOperator(); -long jobExecutionId = jobOperator.start("fooJob", new Properties()); - ----- - -The above code does the following: - -* Bootstraps a base `ApplicationContext`: In order to provide batch functionality, the -framework needs some infrastructure bootstrapped. This occurs once per JVM. The -components that are bootstrapped are similar to those provided by -`@EnableBatchProcessing`. Specific details can be found in the javadoc for the -`JsrJobOperator`. -* Loads an `ApplicationContext` for the job requested: In the example -above, the framework looks in /META-INF/batch-jobs for a file named fooJob.xml and load a -context that is a child of the shared context mentioned previously. -* Launch the job: The job defined within the context will be executed asynchronously. -The `JobExecution's` ID will be returned. - -[NOTE] -==== -All JSR-352 based batch jobs are executed asynchronously. -==== - -When `JobOperator#start` is called using `SimpleJobOperator`, Spring Batch determines if -the call is an initial run or a retry of a previously executed run. Using the JSR-352 -based `JobOperator#start(String jobXMLName, Properties jobParameters)`, the framework -will always create a new JobInstance (JSR-352 job parameters are non-identifying). In order to -restart a job, a call to -`JobOperator#restart(long executionId, Properties restartParameters)` is required. - - -[[jsrContexts]] - -=== Contexts - -JSR-352 defines two context objects that are used to interact with the meta-data of a job or step from -within a batch artifact: `jakarta.batch.runtime.context.JobContext` and -`jakarta.batch.runtime.context.StepContext`. Both of these are available in any step -level artifact (`Batchlet`, `ItemReader`, etc) with the -`JobContext` being available to job level artifacts as well -(`JobListener` for example). - -To obtain a reference to the `JobContext` or `StepContext` -within the current scope, simply use the `@Inject` annotation: - - -[source, java] ----- -@Inject -JobContext jobContext; - ----- - - -[NOTE] -.@Autowire for JSR-352 contexts -==== -Using Spring's @Autowire is not supported for the injection of these contexts. -==== - - -In Spring Batch, the `JobContext` and `StepContext` wrap their -corresponding execution objects (`JobExecution` and -`StepExecution` respectively). Data stored through -`StepContext#setPersistentUserData(Serializable data)` is stored in the -Spring Batch `StepExecution#executionContext`. - -[[jsrStepFlow]] - - -=== Step Flow - -Within a JSR-352 based job, the flow of steps works similarly as it does within Spring Batch. -However, there are a few subtle differences: - - -* Decision's are steps - In a regular Spring Batch job, a decision is a state that does not -have an independent `StepExecution` or any of the rights and -responsibilities that go along with being a full step.. However, with JSR-352, a decision -is a step just like any other and will behave just as any other steps (transactionality, -it gets a `StepExecution`, etc). This means that they are treated the -same as any other step on restarts as well. - -* `next` attribute and step transitions - In a regular job, these are -allowed to appear together in the same step. JSR-352 allows them to both be used in the -same step with the next attribute taking precedence in evaluation. - -* Transition element ordering - In a standard Spring Batch job, transition elements are -sorted from most specific to least specific and evaluated in that order. JSR-352 jobs -evaluate transition elements in the order they are specified in the XML. - - - - -[[jsrScaling]] - - -=== Scaling a JSR-352 batch job - -Traditional Spring Batch jobs have four ways of scaling (the last two capable of being executed across -multiple JVMs): - -* Split - Running multiple steps in parallel. - - -* Multiple threads - Executing a single step via multiple threads. - - -* Partitioning - Dividing the data up for parallel processing (manager/worker). - - -* Remote Chunking - Executing the processor piece of logic remotely. - - - - -JSR-352 provides two options for scaling batch jobs. Both options support only a single JVM: - -* Split - Same as Spring Batch - - -* Partitioning - Conceptually the same as Spring Batch however implemented slightly different. - - - - - -[[jsrPartitioning]] - - -==== Partitioning - -Conceptually, partitioning in JSR-352 is the same as it is in Spring Batch. Meta-data is provided -to each worker to identify the input to be processed, with the workers reporting back to the manager the -results upon completion. However, there are some important differences: - -* Partitioned `Batchlet` - This will run multiple instances of the -configured `Batchlet` on multiple threads. Each instance will have -it's own set of properties as provided by the JSL or the -`PartitionPlan` - - -* `PartitionPlan` - With Spring Batch's partitioning, an -`ExecutionContext` is provided for each partition. With JSR-352, a -single `jakarta.batch.api.partition.PartitionPlan` is provided with an -array of `Properties` providing the meta-data for each partition. - - - -* `PartitionMapper` - JSR-352 provides two ways to generate partition -meta-data. One is via the JSL (partition properties). The second is via an implementation -of the `jakarta.batch.api.partition.PartitionMapper` interface. -Functionally, this interface is similar to the -`org.springframework.batch.core.partition.support.Partitioner` -interface provided by Spring Batch in that it provides a way to programmatically generate -meta-data for partitioning. - - -* `StepExecutions` - In Spring Batch, partitioned steps are run as -manager/worker. Within JSR-352, the same configuration occurs. However, the worker steps do -not get official `StepExecutions`. Because of that, calls to -`JsrJobOperator#getStepExecutions(long jobExecutionId)` will only -return the `StepExecution` for the manager. - -[NOTE] -==== -The child `StepExecutions` still exist in the job repository and are available -through the `JobExplorer`. -==== - - -* Compensating logic - Since Spring Batch implements the manager/worker logic of -partitioning using steps, `StepExecutionListeners` can be used to -handle compensating logic if something goes wrong. However, since the workers JSR-352 -provides a collection of other components for the ability to provide compensating logic when -errors occur and to dynamically set the exit status. These components include the following: - -|=============== -|__Artifact Interface__|__Description__ -|`jakarta.batch.api.partition.PartitionCollector`|Provides a way for worker steps to send information back to the -manager. There is one instance per worker thread. -|`jakarta.batch.api.partition.PartitionAnalyzer`|End point that receives the information collected by the -`PartitionCollector` as well as the resulting -statuses from a completed partition. -|`jakarta.batch.api.partition.PartitionReducer`|Provides the ability to provide compensating logic for a partitioned -step. - -|=============== - - -[[jsrTesting]] - -=== Testing - -Since all JSR-352 based jobs are executed asynchronously, it can be difficult to determine when a job has -completed. To help with testing, Spring Batch provides the -`org.springframework.batch.test.JsrTestUtils`. This utility class provides the -ability to start a job and restart a job and wait for it to complete. Once the job completes, the -associated `JobExecution` is returned. diff --git a/spring-batch-docs/src/main/asciidoc/schema-appendix.adoc b/spring-batch-docs/src/main/asciidoc/schema-appendix.adoc index 2df948d75..2877e19f5 100644 --- a/spring-batch-docs/src/main/asciidoc/schema-appendix.adoc +++ b/spring-batch-docs/src/main/asciidoc/schema-appendix.adoc @@ -190,7 +190,6 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500), LAST_UPDATED TIMESTAMP, - JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INSTANCE_EXECUTION_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ; diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index 5cff94a4d..43b6ae002 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -119,12 +119,6 @@ ${jakarta.persistence-api.version} true - - jakarta.batch - jakarta.batch-api - ${jakarta.batch-api.version} - true - org.springframework.data spring-data-geode diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/CheckpointSupport.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/CheckpointSupport.java deleted file mode 100644 index e252f3a37..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/CheckpointSupport.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2013-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.jsr.item; - -import java.io.Serializable; - -import jakarta.batch.api.chunk.ItemReader; -import jakarta.batch.api.chunk.ItemWriter; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemStreamException; -import org.springframework.batch.item.ItemStreamSupport; -import org.springframework.util.Assert; -import org.springframework.util.SerializationUtils; - -/** - * Provides support for JSR-352 checkpointing. Checkpoint objects are copied prior - * to being added to the {@link ExecutionContext} for persistence by the framework. - * If the checkpoint object cannot be copied and further changes occur to the same - * instance, side effects may occur. In cases like this, it is recommended that a - * copy of the object being acted upon in the reader/writer is returned via the - * {@link ItemReader#checkpointInfo()} or {@link ItemWriter#checkpointInfo()} calls. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public abstract class CheckpointSupport extends ItemStreamSupport{ - - private final Log logger = LogFactory.getLog(this.getClass()); - - private final String checkpointKey; - - /** - * @param checkpointKey key to store the checkpoint object with in the {@link ExecutionContext} - */ - public CheckpointSupport(String checkpointKey) { - Assert.hasText(checkpointKey, "checkpointKey is required"); - this.checkpointKey = checkpointKey; - } - - /* (non-Javadoc) - * @see org.springframework.batch.item.ItemStreamSupport#open(org.springframework.batch.item.ExecutionContext) - */ - @Override - public void open(ExecutionContext executionContext) - throws ItemStreamException { - try { - String executionContextKey = getExecutionContextKey(checkpointKey); - Serializable checkpoint = (Serializable) executionContext.get(executionContextKey); - doOpen(checkpoint); - } catch (Exception e) { - throw new ItemStreamException(e); - } - } - - /** - * Used to open a batch artifact with previously saved checkpoint information. - * - * @param checkpoint previously saved checkpoint object - * @throws Exception thrown by the implementation - */ - protected abstract void doOpen(Serializable checkpoint) throws Exception; - - /* (non-Javadoc) - * @see org.springframework.batch.item.ItemStreamSupport#update(org.springframework.batch.item.ExecutionContext) - */ - @Override - public void update(ExecutionContext executionContext) - throws ItemStreamException { - try { - executionContext.put(getExecutionContextKey(checkpointKey), deepCopy(doCheckpoint())); - } catch (Exception e) { - throw new ItemStreamException(e); - } - } - - /** - * Used to provide a {@link Serializable} representing the current state of the - * batch artifact. - * - * @return the current state of the batch artifact - * @throws Exception thrown by the implementation - */ - protected abstract Serializable doCheckpoint() throws Exception; - - /* (non-Javadoc) - * @see org.springframework.batch.item.ItemStreamSupport#close() - */ - @Override - public void close() throws ItemStreamException { - try { - doClose(); - } catch (Exception e) { - throw new ItemStreamException(e); - } - } - - /** - * Used to close the underlying batch artifact - * - * @throws Exception thrown by the underlying implementation - */ - protected abstract void doClose() throws Exception; - - private Object deepCopy(Serializable orig) { - Object obj = orig; - - try { - obj = SerializationUtils.deserialize(SerializationUtils.serialize(orig)); - } catch (Exception e) { - logger.warn("Unable to copy checkpoint object. Updating the instance passed may cause side effects"); - } - - return obj; - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemProcessorAdapter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemProcessorAdapter.java deleted file mode 100644 index b84874fac..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemProcessorAdapter.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013-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.jsr.item; - -import jakarta.batch.api.chunk.ItemProcessor; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -public class ItemProcessorAdapter implements org.springframework.batch.item.ItemProcessor { - - private ItemProcessor delegate; - - public ItemProcessorAdapter(ItemProcessor processor) { - Assert.notNull(processor, "An ItemProcessor implementation is required"); - this.delegate = processor; - } - - @Nullable - @SuppressWarnings("unchecked") - @Override - public O process(I item) throws Exception { - return (O) delegate.processItem(item); - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemReaderAdapter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemReaderAdapter.java deleted file mode 100644 index 750e7293c..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemReaderAdapter.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013-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.jsr.item; - -import java.io.Serializable; - -import jakarta.batch.api.chunk.ItemReader; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Adapter that wraps an {@link ItemReader} for use by Spring Batch. All calls are delegated as appropriate - * to the corresponding method on the delegate. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class ItemReaderAdapter extends CheckpointSupport implements org.springframework.batch.item.ItemReader { - - private static final String CHECKPOINT_KEY = "reader.checkpoint"; - - private ItemReader delegate; - - /** - * @param reader the {@link ItemReader} implementation to delegate to - */ - public ItemReaderAdapter(ItemReader reader) { - super(CHECKPOINT_KEY); - Assert.notNull(reader, "An ItemReader implementation is required"); - this.delegate = reader; - setExecutionContextName(ClassUtils.getShortName(delegate.getClass())); - } - - /* (non-Javadoc) - * @see org.springframework.batch.item.ItemReader#read() - */ - @Nullable - @SuppressWarnings("unchecked") - @Override - public T read() throws Exception { - return (T) delegate.readItem(); - } - - /* (non-Javadoc) - * @see org.springframework.batch.jsr.item.CheckpointSupport#doClose() - */ - @Override - protected void doClose() throws Exception{ - delegate.close(); - } - - /* (non-Javadoc) - * @see org.springframework.batch.jsr.item.CheckpointSupport#doCheckpoint() - */ - @Override - protected Serializable doCheckpoint() throws Exception { - return delegate.checkpointInfo(); - } - - /* (non-Javadoc) - * @see org.springframework.batch.jsr.item.CheckpointSupport#doOpen(java.io.Serializable) - */ - @Override - protected void doOpen(Serializable checkpoint) throws Exception { - delegate.open(checkpoint); - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemWriterAdapter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemWriterAdapter.java deleted file mode 100644 index d5377b481..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/ItemWriterAdapter.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013-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.jsr.item; - -import java.io.Serializable; -import java.util.List; - -import jakarta.batch.api.chunk.ItemWriter; - -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Adapter that wraps an {@link ItemWriter} for use by Spring Batch. All calls are delegated as appropriate - * to the corresponding method on the delegate. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class ItemWriterAdapter extends CheckpointSupport implements org.springframework.batch.item.ItemWriter { - - private static final String CHECKPOINT_KEY = "writer.checkpoint"; - - private ItemWriter delegate; - - /** - * @param writer a {@link ItemWriter} to delegate calls to - */ - public ItemWriterAdapter(ItemWriter writer) { - super(CHECKPOINT_KEY); - Assert.notNull(writer, "An ItemWriter implementation is required"); - this.delegate = writer; - super.setExecutionContextName(ClassUtils.getShortName(delegate.getClass())); - } - - /* (non-Javadoc) - * @see org.springframework.batch.item.ItemWriter#write(java.util.List) - */ - @SuppressWarnings("unchecked") - @Override - public void write(List items) throws Exception { - delegate.writeItems((List) items); - } - - /* (non-Javadoc) - * @see org.springframework.batch.jsr.item.CheckpointSupport#doOpen(java.io.Serializable) - */ - @Override - protected void doOpen(Serializable checkpoint) throws Exception { - delegate.open(checkpoint); - } - - /* (non-Javadoc) - * @see org.springframework.batch.jsr.item.CheckpointSupport#doCheckpoint() - */ - @Override - protected Serializable doCheckpoint() throws Exception { - Serializable checkpointInfo = delegate.checkpointInfo(); - return checkpointInfo; - } - - /* (non-Javadoc) - * @see org.springframework.batch.jsr.item.CheckpointSupport#doClose() - */ - @Override - protected void doClose() throws Exception{ - delegate.close(); - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/package-info.java deleted file mode 100644 index c4cad41a1..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/item/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Components for adapting JSR item based components to Spring Batch. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.jsr.item; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/repeat/CheckpointAlgorithmAdapter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/repeat/CheckpointAlgorithmAdapter.java deleted file mode 100644 index d19c60edf..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/repeat/CheckpointAlgorithmAdapter.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-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.jsr.repeat; - -import jakarta.batch.api.chunk.CheckpointAlgorithm; -import jakarta.batch.operations.BatchRuntimeException; - -import org.springframework.batch.repeat.CompletionPolicy; -import org.springframework.batch.repeat.RepeatContext; -import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.util.Assert; - -/** - * Wrapper for the {@link CheckpointAlgorithm} to be used via the rest - * of the framework. - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @see CheckpointAlgorithm - * @see CompletionPolicy - */ -public class CheckpointAlgorithmAdapter implements CompletionPolicy { - - private CheckpointAlgorithm policy; - private boolean isComplete = false; - - public CheckpointAlgorithmAdapter(CheckpointAlgorithm policy) { - Assert.notNull(policy, "A CheckpointAlgorithm is required"); - - this.policy = policy; - } - - /* (non-Javadoc) - * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext, org.springframework.batch.repeat.RepeatStatus) - */ - @Override - public boolean isComplete(RepeatContext context, RepeatStatus result) { - try { - isComplete = policy.isReadyToCheckpoint(); - return isComplete; - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - /* (non-Javadoc) - * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext) - */ - @Override - public boolean isComplete(RepeatContext context) { - try { - isComplete = policy.isReadyToCheckpoint(); - return isComplete; - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } - - /* (non-Javadoc) - * @see org.springframework.batch.repeat.CompletionPolicy#start(org.springframework.batch.repeat.RepeatContext) - */ - @Override - public RepeatContext start(RepeatContext parent) { - try { - policy.beginCheckpoint(); - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - - return parent; - } - - /** - * If {@link CheckpointAlgorithm#isReadyToCheckpoint()} is true - * we will call {@link CheckpointAlgorithm#endCheckpoint()} - * - * @param context a {@link RepeatContext} - */ - @Override - public void update(RepeatContext context) { - try { - if(isComplete) { - policy.endCheckpoint(); - } - } catch (Exception e) { - throw new BatchRuntimeException(e); - } - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/repeat/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/repeat/package-info.java deleted file mode 100644 index 3ae51bc5c..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/jsr/repeat/package-info.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 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. - */ - -/** - * APIs for JSR-352 repeat support. - * - * @author Mahmoud Ben Hassine - */ -@NonNullApi -package org.springframework.batch.jsr.repeat; - -import org.springframework.lang.NonNullApi; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemProcessorAdapterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemProcessorAdapterTests.java deleted file mode 100644 index 227cb2645..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemProcessorAdapterTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-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.jsr.item; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.when; - -import jakarta.batch.api.chunk.ItemProcessor; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -public class ItemProcessorAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private ItemProcessorAdapter adapter; - @Mock - private ItemProcessor delegate; - - @Before - public void setUp() throws Exception { - adapter = new ItemProcessorAdapter<>(delegate); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new ItemProcessorAdapter<>(null); - } - - @Test - public void testProcess() throws Exception { - String input = "input"; - String output = "output"; - - when(delegate.processItem(input)).thenReturn(output); - - assertEquals(output, adapter.process(input)); - } -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemReaderAdapterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemReaderAdapterTests.java deleted file mode 100644 index d244f48f7..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemReaderAdapterTests.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2013-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.jsr.item; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.List; -import jakarta.batch.api.chunk.ItemReader; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemStreamException; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ItemReaderAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private ItemReaderAdapter adapter; - @Mock - private ItemReader delegate; - @Mock - private ExecutionContext executionContext; - - @Before - public void setUp() throws Exception { - adapter = new ItemReaderAdapter<>(delegate); - adapter.setName("jsrReader"); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new ItemReaderAdapter<>(null); - } - - @Test - public void testOpen() throws Exception { - when(executionContext.get("jsrReader.reader.checkpoint")).thenReturn("checkpoint"); - - adapter.open(executionContext); - - verify(delegate).open("checkpoint"); - } - - @Test(expected=ItemStreamException.class) - public void testOpenException() throws Exception { - when(executionContext.get("jsrReader.reader.checkpoint")).thenReturn("checkpoint"); - - doThrow(new Exception("expected")).when(delegate).open("checkpoint"); - - adapter.open(executionContext); - } - - @Test - public void testUpdate() throws Exception { - when(delegate.checkpointInfo()).thenReturn("checkpoint"); - - adapter.update(executionContext); - - verify(executionContext).put("jsrReader.reader.checkpoint", "checkpoint"); - } - - @Test(expected=ItemStreamException.class) - public void testUpdateException() throws Exception { - doThrow(new Exception("expected")).when(delegate).checkpointInfo(); - - adapter.update(executionContext); - } - - @Test - public void testClose() throws Exception { - adapter.close(); - - verify(delegate).close(); - } - - @Test(expected=ItemStreamException.class) - public void testCloseException() throws Exception { - doThrow(new Exception("expected")).when(delegate).close(); - - adapter.close(); - } - - @Test - public void testRead() throws Exception { - when(delegate.readItem()).thenReturn("item"); - - assertEquals("item", adapter.read()); - } - - @Test - public void testCheckpointChange() throws Exception { - ItemReaderAdapter adapter = new ItemReaderAdapter<>(new ItemReader() { - - private CheckpointContainer container = null; - private List items = Arrays.asList("foo", "bar", "baz"); - - @Override - public Object readItem() throws Exception { - int index = container.getCount(); - - if(index < items.size()) { - container.setCount(index + 1); - return items.get(index); - } else { - return null; - } - } - - @Override - public void open(Serializable checkpoint) throws Exception { - container = new CheckpointContainer(); - } - - @Override - public void close() throws Exception { - } - - @Override - public Serializable checkpointInfo() throws Exception { - return container; - } - }); - - ExecutionContext context = new ExecutionContext(); - - adapter.open(context); - adapter.read(); - adapter.read(); - adapter.update(context); - adapter.read(); - adapter.close(); - - CheckpointContainer container = (CheckpointContainer) context.get("ItemReaderAdapterTests.1.reader.checkpoint"); - assertEquals(2, container.getCount()); - - } - - public static class CheckpointContainer implements Serializable{ - private static final long serialVersionUID = 1L; - private int count; - - public CheckpointContainer() { - count = 0; - } - - public int getCount() { - return count; - } - - public void setCount(int count) { - this.count = count; - } - - @Override - public String toString() { - return "CheckpointContainer has a count of " + count; - } - } -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemWriterAdapterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemWriterAdapterTests.java deleted file mode 100644 index ba6f0d7a6..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/jsr/item/ItemWriterAdapterTests.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2013-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.jsr.item; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import jakarta.batch.api.chunk.ItemWriter; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemStreamException; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ItemWriterAdapterTests { - - @Rule - public MockitoRule rule = MockitoJUnit.rule().silent(); - - private ItemWriterAdapter adapter; - @Mock - private ItemWriter delegate; - @Mock - private ExecutionContext executionContext; - - @Before - public void setUp() throws Exception { - - adapter = new ItemWriterAdapter<>(delegate); - adapter.setName("jsrWriter"); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreateWithNull() { - adapter = new ItemWriterAdapter<>(null); - } - - @Test - public void testOpen() throws Exception { - when(executionContext.get("jsrWriter.writer.checkpoint")).thenReturn("checkpoint"); - - adapter.open(executionContext); - - verify(delegate).open("checkpoint"); - } - - @Test(expected=ItemStreamException.class) - public void testOpenException() throws Exception { - when(executionContext.get("jsrWriter.writer.checkpoint")).thenReturn("checkpoint"); - - doThrow(new Exception("expected")).when(delegate).open("checkpoint"); - - adapter.open(executionContext); - } - - @Test - public void testUpdate() throws Exception { - when(delegate.checkpointInfo()).thenReturn("checkpoint"); - - adapter.update(executionContext); - - verify(executionContext).put("jsrWriter.writer.checkpoint", "checkpoint"); - } - - @Test(expected=ItemStreamException.class) - public void testUpdateException() throws Exception { - doThrow(new Exception("expected")).when(delegate).checkpointInfo(); - - adapter.update(executionContext); - } - - @Test - public void testClose() throws Exception { - adapter.close(); - - verify(delegate).close(); - } - - @Test(expected=ItemStreamException.class) - public void testCloseException() throws Exception { - doThrow(new Exception("expected")).when(delegate).close(); - - adapter.close(); - } - - @Test - @SuppressWarnings({"rawtypes", "unchecked"}) - public void testWrite() throws Exception { - List items = new ArrayList(); - - items.add("item1"); - items.add("item2"); - - adapter.write(items); - - verify(delegate).writeItems(items); - } - - @Test - public void testCheckpointChange() throws Exception { - ItemWriterAdapter adapter = new ItemWriterAdapter<>(new ItemWriter() { - - private CheckpointContainer container = null; - - @Override - public void open(Serializable checkpoint) throws Exception { - container = new CheckpointContainer(); - } - - @Override - public void close() throws Exception { - } - - @Override - public void writeItems(List items) throws Exception { - container.setCount(container.getCount() + items.size()); - } - - @Override - public Serializable checkpointInfo() throws Exception { - return container; - } - }); - - ExecutionContext context = new ExecutionContext(); - - List items = new ArrayList<>(); - items.add("foo"); - items.add("bar"); - items.add("baz"); - adapter.open(context); - adapter.write(items); - adapter.update(context); - adapter.write(items); - adapter.close(); - - CheckpointContainer container = (CheckpointContainer) context.get("ItemWriterAdapterTests.1.writer.checkpoint"); - assertEquals(3, container.getCount()); - - } - - public static class CheckpointContainer implements Serializable{ - private static final long serialVersionUID = 1L; - - private int count; - - public CheckpointContainer() { - count = 0; - } - - public int getCount() { - return count; - } - - public void setCount(int count) { - this.count = count; - } - - @Override - public String toString() { - return "CheckpointContainer has a count of " + count; - } - } -} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java index 79f23a92d..4a54fdae0 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 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. @@ -29,6 +29,7 @@ import org.springframework.lang.Nullable; /** * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public class JobRepositorySupport implements JobRepository { @@ -108,8 +109,4 @@ public class JobRepositorySupport implements JobRepository { return null; } - public JobExecution createJobExecution(JobInstance jobInstance, - JobParameters jobParameters, String jobConfigurationLocation) { - return null; - } } diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/LICENSE.txt b/spring-batch-jsr352-tck/jsr352-tck-1.0/LICENSE.txt deleted file mode 100644 index 8b9e31618..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/LICENSE.txt +++ /dev/null @@ -1,62 +0,0 @@ - -======================================================================================== -LICENSE for JSR 352 RI/TCK -======================================================================================== -The Program is licensed under the terms and conditions of the Apache 2.0 license: - -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, -and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"Licensee" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - - (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - - diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/NOTICE.txt b/spring-batch-jsr352-tck/jsr352-tck-1.0/NOTICE.txt deleted file mode 100644 index 79d7a7f3b..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/NOTICE.txt +++ /dev/null @@ -1,209 +0,0 @@ - -======================================================================================== -NOTICES AND INFORMATION for JSR 352 RI/TCK -======================================================================================== - -Apache 2.0 NOTICES AND INFORMATION -The Program includes the following, which were also obtained under the terms and conditions of the Apache 2.0 license: - -TestNG v6.8 -Java Inject v3.0 -SpringBatch API v2 - -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, -and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"Licensee" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - - (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - - -END OF APACHE NOTICES AND INFORMATION - -======================================================================================== -JUnit NOTICES AND INFORMATION - -JUnit v4.1.0 -The Program includes JUnit which was obtained under the terms and conditions of the following license: - - -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - -a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and - -b) in the case of each subsequent Contributor: - -i) changes to the Program, and - -ii) additions to the Program; - -where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. - -"Contributor" means any person or entity that distributes the Program. - -"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. - -"Program" means the Contributions distributed in accordance with this Agreement. - -"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. - -2. GRANT OF RIGHTS - -a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. - -b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. - -c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. - -d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. - -3. REQUIREMENTS - -A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: - -a) it complies with the terms and conditions of this Agreement; and - -b) its license agreement: - -i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; - -ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; - -iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and - -iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. - -When the Program is made available in source code form: - -a) it must be made available under this Agreement; and - -b) a copy of this Agreement must be included with each copy of the Program. - -Contributors may not remove or alter any copyright notices contained within the Program. - -Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. - -For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -7. GENERAL - -If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. - -If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. - -Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. - -This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. - -. - -End of JUnit NOTICES AND INFORMATION -======================================================================================== - -XML Unit NOTICES AND INFORMATION - -XML Unit v1.1 - -The Program includes XML Unit which was obtained under the terms and conditions of the following license: - -Copyright (c) 2001-2007, Jeff Martin, Tim Bacon -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of the xmlunit.sourceforge.net nor the names - of its contributors may be used to endorse or promote products - derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -End of XML Unit NOTICES AND INFORMATION -=========================================================================================[= - -End of JSR 352 RI/TCK NOTICES AND INFORMATION diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-api-sigtest-java6.sig b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-api-sigtest-java6.sig deleted file mode 100644 index 960da6bd0..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-api-sigtest-java6.sig +++ /dev/null @@ -1,539 +0,0 @@ -#Signature file v4.1 -#Version - -CLSS public abstract interface java.io.Serializable - -CLSS public abstract interface java.lang.Comparable<%0 extends java.lang.Object> -meth public abstract int compareTo({java.lang.Comparable%0}) - -CLSS public abstract java.lang.Enum<%0 extends java.lang.Enum<{java.lang.Enum%0}>> -cons protected (java.lang.String,int) -intf java.io.Serializable -intf java.lang.Comparable<{java.lang.Enum%0}> -meth protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException -meth protected final void finalize() -meth public final boolean equals(java.lang.Object) -meth public final int compareTo({java.lang.Enum%0}) -meth public final int hashCode() -meth public final int ordinal() -meth public final java.lang.Class<{java.lang.Enum%0}> getDeclaringClass() -meth public final java.lang.String name() -meth public java.lang.String toString() -meth public static <%0 extends java.lang.Enum<{%%0}>> {%%0} valueOf(java.lang.Class<{%%0}>,java.lang.String) -supr java.lang.Object -hfds name,ordinal - -CLSS public java.lang.Exception -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr java.lang.Throwable -hfds serialVersionUID - -CLSS public java.lang.Object -cons public () -meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException -meth protected void finalize() throws java.lang.Throwable -meth public boolean equals(java.lang.Object) -meth public final java.lang.Class getClass() -meth public final void notify() -meth public final void notifyAll() -meth public final void wait() throws java.lang.InterruptedException -meth public final void wait(long) throws java.lang.InterruptedException -meth public final void wait(long,int) throws java.lang.InterruptedException -meth public int hashCode() -meth public java.lang.String toString() - -CLSS public java.lang.RuntimeException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr java.lang.Exception -hfds serialVersionUID - -CLSS public java.lang.Throwable -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -intf java.io.Serializable -meth public java.lang.StackTraceElement[] getStackTrace() -meth public java.lang.String getLocalizedMessage() -meth public java.lang.String getMessage() -meth public java.lang.String toString() -meth public java.lang.Throwable fillInStackTrace() -meth public java.lang.Throwable getCause() -meth public java.lang.Throwable initCause(java.lang.Throwable) -meth public void printStackTrace() -meth public void printStackTrace(java.io.PrintStream) -meth public void printStackTrace(java.io.PrintWriter) -meth public void setStackTrace(java.lang.StackTraceElement[]) -supr java.lang.Object -hfds backtrace,cause,detailMessage,serialVersionUID,stackTrace - -CLSS public abstract interface java.lang.annotation.Annotation -meth public abstract boolean equals(java.lang.Object) -meth public abstract int hashCode() -meth public abstract java.lang.Class annotationType() -meth public abstract java.lang.String toString() - -CLSS public abstract interface !annotation java.lang.annotation.Documented - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation - -CLSS public abstract interface !annotation java.lang.annotation.Retention - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation -meth public abstract java.lang.annotation.RetentionPolicy value() - -CLSS public abstract interface !annotation java.lang.annotation.Target - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation -meth public abstract java.lang.annotation.ElementType[] value() - -CLSS public abstract jakarta.batch.api.AbstractBatchlet -cons public () -intf jakarta.batch.api.Batchlet -meth public abstract java.lang.String process() throws java.lang.Exception -meth public void stop() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface !annotation jakarta.batch.api.BatchProperty - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[FIELD, METHOD, PARAMETER]) - anno 0 javax.inject.Qualifier() -intf java.lang.annotation.Annotation -meth public abstract !hasdefault java.lang.String name() - -CLSS public abstract interface jakarta.batch.api.Batchlet -meth public abstract java.lang.String process() throws java.lang.Exception -meth public abstract void stop() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.Decider -meth public abstract java.lang.String decide(jakarta.batch.runtime.StepExecution[]) throws java.lang.Exception - -CLSS public abstract jakarta.batch.api.chunk.AbstractCheckpointAlgorithm -cons public () -intf jakarta.batch.api.chunk.CheckpointAlgorithm -meth public abstract boolean isReadyToCheckpoint() throws java.lang.Exception -meth public int checkpointTimeout() throws java.lang.Exception -meth public void beginCheckpoint() throws java.lang.Exception -meth public void endCheckpoint() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.AbstractItemReader -cons public () -intf jakarta.batch.api.chunk.ItemReader -meth public abstract java.lang.Object readItem() throws java.lang.Exception -meth public java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public void close() throws java.lang.Exception -meth public void open(java.io.Serializable) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.AbstractItemWriter -cons public () -intf jakarta.batch.api.chunk.ItemWriter -meth public abstract void writeItems(java.util.List) throws java.lang.Exception -meth public java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public void close() throws java.lang.Exception -meth public void open(java.io.Serializable) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.chunk.CheckpointAlgorithm -meth public abstract boolean isReadyToCheckpoint() throws java.lang.Exception -meth public abstract int checkpointTimeout() throws java.lang.Exception -meth public abstract void beginCheckpoint() throws java.lang.Exception -meth public abstract void endCheckpoint() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.ItemProcessor -meth public abstract java.lang.Object processItem(java.lang.Object) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.ItemReader -meth public abstract java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public abstract java.lang.Object readItem() throws java.lang.Exception -meth public abstract void close() throws java.lang.Exception -meth public abstract void open(java.io.Serializable) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.ItemWriter -meth public abstract java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public abstract void close() throws java.lang.Exception -meth public abstract void open(java.io.Serializable) throws java.lang.Exception -meth public abstract void writeItems(java.util.List) throws java.lang.Exception - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractChunkListener -cons public () -intf jakarta.batch.api.chunk.listener.ChunkListener -meth public void afterChunk() throws java.lang.Exception -meth public void beforeChunk() throws java.lang.Exception -meth public void onError(java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractItemProcessListener -cons public () -intf jakarta.batch.api.chunk.listener.ItemProcessListener -meth public void afterProcess(java.lang.Object,java.lang.Object) throws java.lang.Exception -meth public void beforeProcess(java.lang.Object) throws java.lang.Exception -meth public void onProcessError(java.lang.Object,java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractItemReadListener -cons public () -intf jakarta.batch.api.chunk.listener.ItemReadListener -meth public void afterRead(java.lang.Object) throws java.lang.Exception -meth public void beforeRead() throws java.lang.Exception -meth public void onReadError(java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractItemWriteListener -cons public () -intf jakarta.batch.api.chunk.listener.ItemWriteListener -meth public void afterWrite(java.util.List) throws java.lang.Exception -meth public void beforeWrite(java.util.List) throws java.lang.Exception -meth public void onWriteError(java.util.List,java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ChunkListener -meth public abstract void afterChunk() throws java.lang.Exception -meth public abstract void beforeChunk() throws java.lang.Exception -meth public abstract void onError(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ItemProcessListener -meth public abstract void afterProcess(java.lang.Object,java.lang.Object) throws java.lang.Exception -meth public abstract void beforeProcess(java.lang.Object) throws java.lang.Exception -meth public abstract void onProcessError(java.lang.Object,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ItemReadListener -meth public abstract void afterRead(java.lang.Object) throws java.lang.Exception -meth public abstract void beforeRead() throws java.lang.Exception -meth public abstract void onReadError(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ItemWriteListener -meth public abstract void afterWrite(java.util.List) throws java.lang.Exception -meth public abstract void beforeWrite(java.util.List) throws java.lang.Exception -meth public abstract void onWriteError(java.util.List,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.RetryProcessListener -meth public abstract void onRetryProcessException(java.lang.Object,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.RetryReadListener -meth public abstract void onRetryReadException(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.RetryWriteListener -meth public abstract void onRetryWriteException(java.util.List,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.SkipProcessListener -meth public abstract void onSkipProcessItem(java.lang.Object,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.SkipReadListener -meth public abstract void onSkipReadItem(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.SkipWriteListener -meth public abstract void onSkipWriteItem(java.util.List,java.lang.Exception) throws java.lang.Exception - -CLSS abstract interface jakarta.batch.api.chunk.listener.package-info - -CLSS abstract interface jakarta.batch.api.chunk.package-info - -CLSS public abstract jakarta.batch.api.listener.AbstractJobListener -cons public () -intf jakarta.batch.api.listener.JobListener -meth public void afterJob() throws java.lang.Exception -meth public void beforeJob() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.listener.AbstractStepListener -cons public () -intf jakarta.batch.api.listener.StepListener -meth public void afterStep() throws java.lang.Exception -meth public void beforeStep() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.listener.JobListener -meth public abstract void afterJob() throws java.lang.Exception -meth public abstract void beforeJob() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.listener.StepListener -meth public abstract void afterStep() throws java.lang.Exception -meth public abstract void beforeStep() throws java.lang.Exception - -CLSS abstract interface jakarta.batch.api.listener.package-info - -CLSS abstract interface jakarta.batch.api.package-info - -CLSS public abstract jakarta.batch.api.partition.AbstractPartitionAnalyzer -cons public () -intf jakarta.batch.api.partition.PartitionAnalyzer -meth public void analyzeCollectorData(java.io.Serializable) throws java.lang.Exception -meth public void analyzeStatus(jakarta.batch.runtime.BatchStatus,java.lang.String) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.partition.AbstractPartitionReducer -cons public () -intf jakarta.batch.api.partition.PartitionReducer -meth public void afterPartitionedStepCompletion(jakarta.batch.api.partition.PartitionReducer$PartitionStatus) throws java.lang.Exception -meth public void beforePartitionedStepCompletion() throws java.lang.Exception -meth public void beginPartitionedStep() throws java.lang.Exception -meth public void rollbackPartitionedStep() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.partition.PartitionAnalyzer -meth public abstract void analyzeCollectorData(java.io.Serializable) throws java.lang.Exception -meth public abstract void analyzeStatus(jakarta.batch.runtime.BatchStatus,java.lang.String) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.partition.PartitionCollector -meth public abstract java.io.Serializable collectPartitionData() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.partition.PartitionMapper -meth public abstract jakarta.batch.api.partition.PartitionPlan mapPartitions() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.partition.PartitionPlan -meth public abstract boolean getPartitionsOverride() -meth public abstract int getPartitions() -meth public abstract int getThreads() -meth public abstract java.util.Properties[] getPartitionProperties() -meth public abstract void setPartitionProperties(java.util.Properties[]) -meth public abstract void setPartitions(int) -meth public abstract void setPartitionsOverride(boolean) -meth public abstract void setThreads(int) - -CLSS public jakarta.batch.api.partition.PartitionPlanImpl -cons public () -intf jakarta.batch.api.partition.PartitionPlan -meth public boolean getPartitionsOverride() -meth public int getPartitions() -meth public int getThreads() -meth public java.util.Properties[] getPartitionProperties() -meth public void setPartitionProperties(java.util.Properties[]) -meth public void setPartitions(int) -meth public void setPartitionsOverride(boolean) -meth public void setThreads(int) -supr java.lang.Object -hfds override,partitionProperties,partitions,threads - -CLSS public abstract interface jakarta.batch.api.partition.PartitionReducer -innr public final static !enum PartitionStatus -meth public abstract void afterPartitionedStepCompletion(jakarta.batch.api.partition.PartitionReducer$PartitionStatus) throws java.lang.Exception -meth public abstract void beforePartitionedStepCompletion() throws java.lang.Exception -meth public abstract void beginPartitionedStep() throws java.lang.Exception -meth public abstract void rollbackPartitionedStep() throws java.lang.Exception - -CLSS public final static !enum jakarta.batch.api.partition.PartitionReducer$PartitionStatus - outer jakarta.batch.api.partition.PartitionReducer -fld public final static jakarta.batch.api.partition.PartitionReducer$PartitionStatus COMMIT -fld public final static jakarta.batch.api.partition.PartitionReducer$PartitionStatus ROLLBACK -meth public static jakarta.batch.api.partition.PartitionReducer$PartitionStatus valueOf(java.lang.String) -meth public static jakarta.batch.api.partition.PartitionReducer$PartitionStatus[] values() -supr java.lang.Enum - -CLSS abstract interface jakarta.batch.api.partition.package-info - -CLSS public jakarta.batch.operations.BatchRuntimeException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr java.lang.RuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionAlreadyCompleteException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionIsRunningException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionNotMostRecentException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionNotRunningException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public abstract interface jakarta.batch.operations.JobOperator -meth public abstract int getJobInstanceCount(java.lang.String) -meth public abstract java.util.List getRunningExecutions(java.lang.String) -meth public abstract java.util.List getJobExecutions(jakarta.batch.runtime.JobInstance) -meth public abstract java.util.List getJobInstances(java.lang.String,int,int) -meth public abstract java.util.List getStepExecutions(long) -meth public abstract java.util.Properties getParameters(long) -meth public abstract java.util.Set getJobNames() -meth public abstract jakarta.batch.runtime.JobExecution getJobExecution(long) -meth public abstract jakarta.batch.runtime.JobInstance getJobInstance(long) -meth public abstract long restart(long,java.util.Properties) -meth public abstract long start(java.lang.String,java.util.Properties) -meth public abstract void abandon(long) -meth public abstract void stop(long) - -CLSS public jakarta.batch.operations.JobRestartException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobSecurityException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobStartException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.NoSuchJobException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.NoSuchJobExecutionException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.NoSuchJobInstanceException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS abstract interface jakarta.batch.operations.package-info - -CLSS public jakarta.batch.runtime.BatchRuntime -cons public () -meth public static jakarta.batch.operations.JobOperator getJobOperator() -supr java.lang.Object -hfds logger,sourceClass - -CLSS public final !enum jakarta.batch.runtime.BatchStatus -fld public final static jakarta.batch.runtime.BatchStatus ABANDONED -fld public final static jakarta.batch.runtime.BatchStatus COMPLETED -fld public final static jakarta.batch.runtime.BatchStatus FAILED -fld public final static jakarta.batch.runtime.BatchStatus STARTED -fld public final static jakarta.batch.runtime.BatchStatus STARTING -fld public final static jakarta.batch.runtime.BatchStatus STOPPED -fld public final static jakarta.batch.runtime.BatchStatus STOPPING -meth public static jakarta.batch.runtime.BatchStatus valueOf(java.lang.String) -meth public static jakarta.batch.runtime.BatchStatus[] values() -supr java.lang.Enum - -CLSS public abstract interface jakarta.batch.runtime.JobExecution -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getJobName() -meth public abstract java.util.Date getCreateTime() -meth public abstract java.util.Date getEndTime() -meth public abstract java.util.Date getLastUpdatedTime() -meth public abstract java.util.Date getStartTime() -meth public abstract java.util.Properties getJobParameters() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract long getExecutionId() - -CLSS public abstract interface jakarta.batch.runtime.JobInstance -meth public abstract java.lang.String getJobName() -meth public abstract long getInstanceId() - -CLSS public abstract interface jakarta.batch.runtime.Metric -innr public final static !enum MetricType -meth public abstract jakarta.batch.runtime.Metric$MetricType getType() -meth public abstract long getValue() - -CLSS public final static !enum jakarta.batch.runtime.Metric$MetricType - outer jakarta.batch.runtime.Metric -fld public final static jakarta.batch.runtime.Metric$MetricType COMMIT_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType FILTER_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType PROCESS_SKIP_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType READ_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType READ_SKIP_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType ROLLBACK_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType WRITE_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType WRITE_SKIP_COUNT -meth public static jakarta.batch.runtime.Metric$MetricType valueOf(java.lang.String) -meth public static jakarta.batch.runtime.Metric$MetricType[] values() -supr java.lang.Enum - -CLSS public abstract interface jakarta.batch.runtime.StepExecution -meth public abstract java.io.Serializable getPersistentUserData() -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getStepName() -meth public abstract java.util.Date getEndTime() -meth public abstract java.util.Date getStartTime() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract jakarta.batch.runtime.Metric[] getMetrics() -meth public abstract long getStepExecutionId() - -CLSS public abstract interface jakarta.batch.runtime.context.JobContext -meth public abstract java.lang.Object getTransientUserData() -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getJobName() -meth public abstract java.util.Properties getProperties() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract long getExecutionId() -meth public abstract long getInstanceId() -meth public abstract void setExitStatus(java.lang.String) -meth public abstract void setTransientUserData(java.lang.Object) - -CLSS public abstract interface jakarta.batch.runtime.context.StepContext -meth public abstract java.io.Serializable getPersistentUserData() -meth public abstract java.lang.Exception getException() -meth public abstract java.lang.Object getTransientUserData() -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getStepName() -meth public abstract java.util.Properties getProperties() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract jakarta.batch.runtime.Metric[] getMetrics() -meth public abstract long getStepExecutionId() -meth public abstract void setExitStatus(java.lang.String) -meth public abstract void setPersistentUserData(java.io.Serializable) -meth public abstract void setTransientUserData(java.lang.Object) - -CLSS abstract interface jakarta.batch.runtime.context.package-info - -CLSS abstract interface jakarta.batch.runtime.package-info - -CLSS public abstract interface !annotation javax.inject.Qualifier - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation - diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-api-sigtest-java7.sig b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-api-sigtest-java7.sig deleted file mode 100644 index 763f5b10b..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-api-sigtest-java7.sig +++ /dev/null @@ -1,545 +0,0 @@ -#Signature file v4.1 -#Version - -CLSS public abstract interface java.io.Serializable - -CLSS public abstract interface java.lang.Comparable<%0 extends java.lang.Object> -meth public abstract int compareTo({java.lang.Comparable%0}) - -CLSS public abstract java.lang.Enum<%0 extends java.lang.Enum<{java.lang.Enum%0}>> -cons protected (java.lang.String,int) -intf java.io.Serializable -intf java.lang.Comparable<{java.lang.Enum%0}> -meth protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException -meth protected final void finalize() -meth public final boolean equals(java.lang.Object) -meth public final int compareTo({java.lang.Enum%0}) -meth public final int hashCode() -meth public final int ordinal() -meth public final java.lang.Class<{java.lang.Enum%0}> getDeclaringClass() -meth public final java.lang.String name() -meth public java.lang.String toString() -meth public static <%0 extends java.lang.Enum<{%%0}>> {%%0} valueOf(java.lang.Class<{%%0}>,java.lang.String) -supr java.lang.Object -hfds name,ordinal - -CLSS public java.lang.Exception -cons protected (java.lang.String,java.lang.Throwable,boolean,boolean) -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr java.lang.Throwable -hfds serialVersionUID - -CLSS public java.lang.Object -cons public () -meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException -meth protected void finalize() throws java.lang.Throwable -meth public boolean equals(java.lang.Object) -meth public final java.lang.Class getClass() -meth public final void notify() -meth public final void notifyAll() -meth public final void wait() throws java.lang.InterruptedException -meth public final void wait(long) throws java.lang.InterruptedException -meth public final void wait(long,int) throws java.lang.InterruptedException -meth public int hashCode() -meth public java.lang.String toString() - -CLSS public java.lang.RuntimeException -cons protected (java.lang.String,java.lang.Throwable,boolean,boolean) -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr java.lang.Exception -hfds serialVersionUID - -CLSS public java.lang.Throwable -cons protected (java.lang.String,java.lang.Throwable,boolean,boolean) -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -intf java.io.Serializable -meth public final java.lang.Throwable[] getSuppressed() -meth public final void addSuppressed(java.lang.Throwable) -meth public java.lang.StackTraceElement[] getStackTrace() -meth public java.lang.String getLocalizedMessage() -meth public java.lang.String getMessage() -meth public java.lang.String toString() -meth public java.lang.Throwable fillInStackTrace() -meth public java.lang.Throwable getCause() -meth public java.lang.Throwable initCause(java.lang.Throwable) -meth public void printStackTrace() -meth public void printStackTrace(java.io.PrintStream) -meth public void printStackTrace(java.io.PrintWriter) -meth public void setStackTrace(java.lang.StackTraceElement[]) -supr java.lang.Object -hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions -hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter - -CLSS public abstract interface java.lang.annotation.Annotation -meth public abstract boolean equals(java.lang.Object) -meth public abstract int hashCode() -meth public abstract java.lang.Class annotationType() -meth public abstract java.lang.String toString() - -CLSS public abstract interface !annotation java.lang.annotation.Documented - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation - -CLSS public abstract interface !annotation java.lang.annotation.Retention - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation -meth public abstract java.lang.annotation.RetentionPolicy value() - -CLSS public abstract interface !annotation java.lang.annotation.Target - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation -meth public abstract java.lang.annotation.ElementType[] value() - -CLSS public abstract jakarta.batch.api.AbstractBatchlet -cons public () -intf jakarta.batch.api.Batchlet -meth public abstract java.lang.String process() throws java.lang.Exception -meth public void stop() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface !annotation jakarta.batch.api.BatchProperty - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[FIELD, METHOD, PARAMETER]) - anno 0 javax.inject.Qualifier() -intf java.lang.annotation.Annotation -meth public abstract !hasdefault java.lang.String name() - -CLSS public abstract interface jakarta.batch.api.Batchlet -meth public abstract java.lang.String process() throws java.lang.Exception -meth public abstract void stop() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.Decider -meth public abstract java.lang.String decide(jakarta.batch.runtime.StepExecution[]) throws java.lang.Exception - -CLSS public abstract jakarta.batch.api.chunk.AbstractCheckpointAlgorithm -cons public () -intf jakarta.batch.api.chunk.CheckpointAlgorithm -meth public abstract boolean isReadyToCheckpoint() throws java.lang.Exception -meth public int checkpointTimeout() throws java.lang.Exception -meth public void beginCheckpoint() throws java.lang.Exception -meth public void endCheckpoint() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.AbstractItemReader -cons public () -intf jakarta.batch.api.chunk.ItemReader -meth public abstract java.lang.Object readItem() throws java.lang.Exception -meth public java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public void close() throws java.lang.Exception -meth public void open(java.io.Serializable) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.AbstractItemWriter -cons public () -intf jakarta.batch.api.chunk.ItemWriter -meth public abstract void writeItems(java.util.List) throws java.lang.Exception -meth public java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public void close() throws java.lang.Exception -meth public void open(java.io.Serializable) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.chunk.CheckpointAlgorithm -meth public abstract boolean isReadyToCheckpoint() throws java.lang.Exception -meth public abstract int checkpointTimeout() throws java.lang.Exception -meth public abstract void beginCheckpoint() throws java.lang.Exception -meth public abstract void endCheckpoint() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.ItemProcessor -meth public abstract java.lang.Object processItem(java.lang.Object) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.ItemReader -meth public abstract java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public abstract java.lang.Object readItem() throws java.lang.Exception -meth public abstract void close() throws java.lang.Exception -meth public abstract void open(java.io.Serializable) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.ItemWriter -meth public abstract java.io.Serializable checkpointInfo() throws java.lang.Exception -meth public abstract void close() throws java.lang.Exception -meth public abstract void open(java.io.Serializable) throws java.lang.Exception -meth public abstract void writeItems(java.util.List) throws java.lang.Exception - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractChunkListener -cons public () -intf jakarta.batch.api.chunk.listener.ChunkListener -meth public void afterChunk() throws java.lang.Exception -meth public void beforeChunk() throws java.lang.Exception -meth public void onError(java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractItemProcessListener -cons public () -intf jakarta.batch.api.chunk.listener.ItemProcessListener -meth public void afterProcess(java.lang.Object,java.lang.Object) throws java.lang.Exception -meth public void beforeProcess(java.lang.Object) throws java.lang.Exception -meth public void onProcessError(java.lang.Object,java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractItemReadListener -cons public () -intf jakarta.batch.api.chunk.listener.ItemReadListener -meth public void afterRead(java.lang.Object) throws java.lang.Exception -meth public void beforeRead() throws java.lang.Exception -meth public void onReadError(java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.chunk.listener.AbstractItemWriteListener -cons public () -intf jakarta.batch.api.chunk.listener.ItemWriteListener -meth public void afterWrite(java.util.List) throws java.lang.Exception -meth public void beforeWrite(java.util.List) throws java.lang.Exception -meth public void onWriteError(java.util.List,java.lang.Exception) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ChunkListener -meth public abstract void afterChunk() throws java.lang.Exception -meth public abstract void beforeChunk() throws java.lang.Exception -meth public abstract void onError(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ItemProcessListener -meth public abstract void afterProcess(java.lang.Object,java.lang.Object) throws java.lang.Exception -meth public abstract void beforeProcess(java.lang.Object) throws java.lang.Exception -meth public abstract void onProcessError(java.lang.Object,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ItemReadListener -meth public abstract void afterRead(java.lang.Object) throws java.lang.Exception -meth public abstract void beforeRead() throws java.lang.Exception -meth public abstract void onReadError(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.ItemWriteListener -meth public abstract void afterWrite(java.util.List) throws java.lang.Exception -meth public abstract void beforeWrite(java.util.List) throws java.lang.Exception -meth public abstract void onWriteError(java.util.List,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.RetryProcessListener -meth public abstract void onRetryProcessException(java.lang.Object,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.RetryReadListener -meth public abstract void onRetryReadException(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.RetryWriteListener -meth public abstract void onRetryWriteException(java.util.List,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.SkipProcessListener -meth public abstract void onSkipProcessItem(java.lang.Object,java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.SkipReadListener -meth public abstract void onSkipReadItem(java.lang.Exception) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.chunk.listener.SkipWriteListener -meth public abstract void onSkipWriteItem(java.util.List,java.lang.Exception) throws java.lang.Exception - -CLSS abstract interface jakarta.batch.api.chunk.listener.package-info - -CLSS abstract interface jakarta.batch.api.chunk.package-info - -CLSS public abstract jakarta.batch.api.listener.AbstractJobListener -cons public () -intf jakarta.batch.api.listener.JobListener -meth public void afterJob() throws java.lang.Exception -meth public void beforeJob() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.listener.AbstractStepListener -cons public () -intf jakarta.batch.api.listener.StepListener -meth public void afterStep() throws java.lang.Exception -meth public void beforeStep() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.listener.JobListener -meth public abstract void afterJob() throws java.lang.Exception -meth public abstract void beforeJob() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.listener.StepListener -meth public abstract void afterStep() throws java.lang.Exception -meth public abstract void beforeStep() throws java.lang.Exception - -CLSS abstract interface jakarta.batch.api.listener.package-info - -CLSS abstract interface jakarta.batch.api.package-info - -CLSS public abstract jakarta.batch.api.partition.AbstractPartitionAnalyzer -cons public () -intf jakarta.batch.api.partition.PartitionAnalyzer -meth public void analyzeCollectorData(java.io.Serializable) throws java.lang.Exception -meth public void analyzeStatus(jakarta.batch.runtime.BatchStatus,java.lang.String) throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract jakarta.batch.api.partition.AbstractPartitionReducer -cons public () -intf jakarta.batch.api.partition.PartitionReducer -meth public void afterPartitionedStepCompletion(jakarta.batch.api.partition.PartitionReducer$PartitionStatus) throws java.lang.Exception -meth public void beforePartitionedStepCompletion() throws java.lang.Exception -meth public void beginPartitionedStep() throws java.lang.Exception -meth public void rollbackPartitionedStep() throws java.lang.Exception -supr java.lang.Object - -CLSS public abstract interface jakarta.batch.api.partition.PartitionAnalyzer -meth public abstract void analyzeCollectorData(java.io.Serializable) throws java.lang.Exception -meth public abstract void analyzeStatus(jakarta.batch.runtime.BatchStatus,java.lang.String) throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.partition.PartitionCollector -meth public abstract java.io.Serializable collectPartitionData() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.partition.PartitionMapper -meth public abstract jakarta.batch.api.partition.PartitionPlan mapPartitions() throws java.lang.Exception - -CLSS public abstract interface jakarta.batch.api.partition.PartitionPlan -meth public abstract boolean getPartitionsOverride() -meth public abstract int getPartitions() -meth public abstract int getThreads() -meth public abstract java.util.Properties[] getPartitionProperties() -meth public abstract void setPartitionProperties(java.util.Properties[]) -meth public abstract void setPartitions(int) -meth public abstract void setPartitionsOverride(boolean) -meth public abstract void setThreads(int) - -CLSS public jakarta.batch.api.partition.PartitionPlanImpl -cons public () -intf jakarta.batch.api.partition.PartitionPlan -meth public boolean getPartitionsOverride() -meth public int getPartitions() -meth public int getThreads() -meth public java.util.Properties[] getPartitionProperties() -meth public void setPartitionProperties(java.util.Properties[]) -meth public void setPartitions(int) -meth public void setPartitionsOverride(boolean) -meth public void setThreads(int) -supr java.lang.Object -hfds override,partitionProperties,partitions,threads - -CLSS public abstract interface jakarta.batch.api.partition.PartitionReducer -innr public final static !enum PartitionStatus -meth public abstract void afterPartitionedStepCompletion(jakarta.batch.api.partition.PartitionReducer$PartitionStatus) throws java.lang.Exception -meth public abstract void beforePartitionedStepCompletion() throws java.lang.Exception -meth public abstract void beginPartitionedStep() throws java.lang.Exception -meth public abstract void rollbackPartitionedStep() throws java.lang.Exception - -CLSS public final static !enum jakarta.batch.api.partition.PartitionReducer$PartitionStatus - outer jakarta.batch.api.partition.PartitionReducer -fld public final static jakarta.batch.api.partition.PartitionReducer$PartitionStatus COMMIT -fld public final static jakarta.batch.api.partition.PartitionReducer$PartitionStatus ROLLBACK -meth public static jakarta.batch.api.partition.PartitionReducer$PartitionStatus valueOf(java.lang.String) -meth public static jakarta.batch.api.partition.PartitionReducer$PartitionStatus[] values() -supr java.lang.Enum - -CLSS abstract interface jakarta.batch.api.partition.package-info - -CLSS public jakarta.batch.operations.BatchRuntimeException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr java.lang.RuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionAlreadyCompleteException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionIsRunningException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionNotMostRecentException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobExecutionNotRunningException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public abstract interface jakarta.batch.operations.JobOperator -meth public abstract int getJobInstanceCount(java.lang.String) -meth public abstract java.util.List getRunningExecutions(java.lang.String) -meth public abstract java.util.List getJobExecutions(jakarta.batch.runtime.JobInstance) -meth public abstract java.util.List getJobInstances(java.lang.String,int,int) -meth public abstract java.util.List getStepExecutions(long) -meth public abstract java.util.Properties getParameters(long) -meth public abstract java.util.Set getJobNames() -meth public abstract jakarta.batch.runtime.JobExecution getJobExecution(long) -meth public abstract jakarta.batch.runtime.JobInstance getJobInstance(long) -meth public abstract long restart(long,java.util.Properties) -meth public abstract long start(java.lang.String,java.util.Properties) -meth public abstract void abandon(long) -meth public abstract void stop(long) - -CLSS public jakarta.batch.operations.JobRestartException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobSecurityException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.JobStartException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.NoSuchJobException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.NoSuchJobExecutionException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS public jakarta.batch.operations.NoSuchJobInstanceException -cons public () -cons public (java.lang.String) -cons public (java.lang.String,java.lang.Throwable) -cons public (java.lang.Throwable) -supr jakarta.batch.operations.BatchRuntimeException -hfds serialVersionUID - -CLSS abstract interface jakarta.batch.operations.package-info - -CLSS public jakarta.batch.runtime.BatchRuntime -cons public () -meth public static jakarta.batch.operations.JobOperator getJobOperator() -supr java.lang.Object -hfds logger,sourceClass - -CLSS public final !enum jakarta.batch.runtime.BatchStatus -fld public final static jakarta.batch.runtime.BatchStatus ABANDONED -fld public final static jakarta.batch.runtime.BatchStatus COMPLETED -fld public final static jakarta.batch.runtime.BatchStatus FAILED -fld public final static jakarta.batch.runtime.BatchStatus STARTED -fld public final static jakarta.batch.runtime.BatchStatus STARTING -fld public final static jakarta.batch.runtime.BatchStatus STOPPED -fld public final static jakarta.batch.runtime.BatchStatus STOPPING -meth public static jakarta.batch.runtime.BatchStatus valueOf(java.lang.String) -meth public static jakarta.batch.runtime.BatchStatus[] values() -supr java.lang.Enum - -CLSS public abstract interface jakarta.batch.runtime.JobExecution -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getJobName() -meth public abstract java.util.Date getCreateTime() -meth public abstract java.util.Date getEndTime() -meth public abstract java.util.Date getLastUpdatedTime() -meth public abstract java.util.Date getStartTime() -meth public abstract java.util.Properties getJobParameters() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract long getExecutionId() - -CLSS public abstract interface jakarta.batch.runtime.JobInstance -meth public abstract java.lang.String getJobName() -meth public abstract long getInstanceId() - -CLSS public abstract interface jakarta.batch.runtime.Metric -innr public final static !enum MetricType -meth public abstract jakarta.batch.runtime.Metric$MetricType getType() -meth public abstract long getValue() - -CLSS public final static !enum jakarta.batch.runtime.Metric$MetricType - outer jakarta.batch.runtime.Metric -fld public final static jakarta.batch.runtime.Metric$MetricType COMMIT_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType FILTER_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType PROCESS_SKIP_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType READ_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType READ_SKIP_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType ROLLBACK_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType WRITE_COUNT -fld public final static jakarta.batch.runtime.Metric$MetricType WRITE_SKIP_COUNT -meth public static jakarta.batch.runtime.Metric$MetricType valueOf(java.lang.String) -meth public static jakarta.batch.runtime.Metric$MetricType[] values() -supr java.lang.Enum - -CLSS public abstract interface jakarta.batch.runtime.StepExecution -meth public abstract java.io.Serializable getPersistentUserData() -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getStepName() -meth public abstract java.util.Date getEndTime() -meth public abstract java.util.Date getStartTime() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract jakarta.batch.runtime.Metric[] getMetrics() -meth public abstract long getStepExecutionId() - -CLSS public abstract interface jakarta.batch.runtime.context.JobContext -meth public abstract java.lang.Object getTransientUserData() -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getJobName() -meth public abstract java.util.Properties getProperties() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract long getExecutionId() -meth public abstract long getInstanceId() -meth public abstract void setExitStatus(java.lang.String) -meth public abstract void setTransientUserData(java.lang.Object) - -CLSS public abstract interface jakarta.batch.runtime.context.StepContext -meth public abstract java.io.Serializable getPersistentUserData() -meth public abstract java.lang.Exception getException() -meth public abstract java.lang.Object getTransientUserData() -meth public abstract java.lang.String getExitStatus() -meth public abstract java.lang.String getStepName() -meth public abstract java.util.Properties getProperties() -meth public abstract jakarta.batch.runtime.BatchStatus getBatchStatus() -meth public abstract jakarta.batch.runtime.Metric[] getMetrics() -meth public abstract long getStepExecutionId() -meth public abstract void setExitStatus(java.lang.String) -meth public abstract void setPersistentUserData(java.io.Serializable) -meth public abstract void setTransientUserData(java.lang.Object) - -CLSS abstract interface jakarta.batch.runtime.context.package-info - -CLSS abstract interface jakarta.batch.runtime.package-info - -CLSS public abstract interface !annotation javax.inject.Qualifier - anno 0 java.lang.annotation.Documented() - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME) - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE]) -intf java.lang.annotation.Annotation - diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI-javadoc.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI-javadoc.jar deleted file mode 100644 index deec681e7..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI-javadoc.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI-src.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI-src.jar deleted file mode 100644 index 09ef69c07..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI-src.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI.jar deleted file mode 100644 index ee28ac73e..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-SPI.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-javadoc.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-javadoc.jar deleted file mode 100644 index 128ca6a9a..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-javadoc.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-src.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-src.jar deleted file mode 100644 index 441e4ebea..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-src.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-suite.xml b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-suite.xml deleted file mode 100644 index 5d1ad64dc..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl-suite.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl.jar deleted file mode 100644 index be3603b4a..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/artifacts/jsr352-tck-impl.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/build.xml b/spring-batch-jsr352-tck/jsr352-tck-1.0/build.xml deleted file mode 100644 index 50e3913c5..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/build.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - JSR 352 TCK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/doc/jsr352-tck-reference-guide.pdf b/spring-batch-jsr352-tck/jsr352-tck-1.0/doc/jsr352-tck-reference-guide.pdf deleted file mode 100644 index a818d5126..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/doc/jsr352-tck-reference-guide.pdf and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/jsr352-tck.properties b/spring-batch-jsr352-tck/jsr352-tck-1.0/jsr352-tck.properties deleted file mode 100644 index 9a835beee..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/jsr352-tck.properties +++ /dev/null @@ -1,53 +0,0 @@ -# -# Edit this property to contain a classpath listing of the directories and jars for the SE JSR 352 runtime implementation (that you're running the TCK against) -# For example: batch.impl.classes=$HOME/foo/lib/classes:$HOME/foo/lib/foo.jar:$HOME/foo/lib/batch-api.jar -# -# Another example, for the RI root dir in the same parent directory as the TCK root dir, one could use: -#batch.impl.classes=../jsr352-ri-1.0/jakarta.batch.api.jar:../jsr352-ri-1.0/jsr352-SE-RI-runtime.jar:../jsr352-ri-1.0/jsr352-RI-spi.jar:../jsr352-ri-1.0/derby.jar -batch.impl.classes= - -# Add JVM options to pass to TestNG here. JVM arguments should be separated by spaces, as this will provided to the TestNG invocation -# using the function -jvm.options= - -###################################### -# Sleep timer values for TCK tests -###################################### - -# Test Class: ExecutionTests -ExecutionTests.testInvokeJobWithUserStop.sleep=1000 - -# Test Class: JobOperatorTests -JobOperatorTests.testInvokeJobWithUserStop.sleep=1000 -JobOperatorTests.testJobOperatorGetRunningJobExecutions.sleep=1000 -JobOperatorTests.testJobOperatorGetRunningJobExecutions.app.timeinterval=10000 -JobOperatorTests.testJobOperatorGetRunningJobInstancesException.app.timeinterval=10000 -JobOperatorTests.testJobOperatorTestAbandonActiveRestart.sleep=5000 -JobOperatorTests.testJobOperatorTestRestartAlreadAbandonedJob.sleep=1 - - -#Test Class: ParallelExecutionTests -ParallelExecutionTests.testStopRunningPartitionedStep.sleep=1900 -ParallelExecutionTests.testStopRestartRunningPartitionedStep.sleep=1900 -ParallelExecutionTests.testInvokeJobWithOnePartitionedStepExitStatus.sleep=2000 - -#Test Class: StopOrFailOnExitStatusWithRestartTests -StopOrFailOnExitStatusWithRestartTests.testInvokeJobWithUserStop.sleep=500 - -#Test Class: TransactionTests -TransactionTests.testGlobalTranNoExceptions.sleep=0 -TransactionTests.testGlobalTranForcedExceptionWithRollback.sleep=0 -TransactionTests.testGlobalTranForcedExceptionCheckpointRestart.sleep=0 -TransactionTests.testGlobalTranNoDelayLongTimeout.sleep=0 -TransactionTests.testGlobalTranLongDelayShortTimeoutThenNoDelayShortTimeout.sleep.1=10000 -TransactionTests.testGlobalTranLongDelayShortTimeoutThenNoDelayShortTimeout.sleep.2=0 -TransactionTests.testGlobalTranLongDelayMixOfLongTimeoutStepsAndShortTimeoutSteps.sleep=10000 -TransactionTests.testGlobalTranLongDelayMixOfLongTimeoutStepsAndShortTimeoutStepsCustomCheckpointAlgorithm.sleep=10000 -TransactionTests.testGlobalTranForcedTimeoutCheckpointRestart.sleep.1=10000 -TransactionTests.testGlobalTranForcedTimeoutCheckpointRestart.sleep.2=0 - -#Test Class: ChunkTests -ChunkTests.testChunkTimeBased10Seconds.sleep=500 -ChunkTests.testChunkRestartTimeBasedCheckpoint.sleep=500 -ChunkTests.testChunkTimeBasedTimeLimit0.sleep=500 -ChunkTests.testChunkRestartTimeBasedDefaultCheckpoint.sleep=500 \ No newline at end of file diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/javax.inject.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/javax.inject.jar deleted file mode 100644 index 1ff61ceec..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/javax.inject.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/junit-4.10.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/junit-4.10.jar deleted file mode 100644 index bf5c0b9c6..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/junit-4.10.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/testng-6.8.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/testng-6.8.jar deleted file mode 100644 index dd6c8bbf3..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/testng-6.8.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/xmlunit-1.1.jar b/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/xmlunit-1.1.jar deleted file mode 100644 index c2d2ac6e9..000000000 Binary files a/spring-batch-jsr352-tck/jsr352-tck-1.0/lib/xmlunit-1.1.jar and /dev/null differ diff --git a/spring-batch-jsr352-tck/jsr352-tck-1.0/readme.txt b/spring-batch-jsr352-tck/jsr352-tck-1.0/readme.txt deleted file mode 100644 index 810c0598d..000000000 --- a/spring-batch-jsr352-tck/jsr352-tck-1.0/readme.txt +++ /dev/null @@ -1,28 +0,0 @@ -Batch Applications for the Java Platform TCK ------------- - -The Batch Applications for the Java Platform specification (JSR-352) describes the job specification language, -Java programming model, and runtime environment for batch applications for the Java platform. - -This is the TCK for JSR-352. - -This distribution, as a whole, is licensed under the terms of the Apache Public License (see LICENSE.TXT). - - -This distribution consists of: - -artifacts/ - -- TCK binaries and source, packaged as jars - -- TestNG suite.xml file for running the TCK - -doc/ - -- Reference guide for the TCK - -lib/ - -- Dependencies for running the TCK - -build.xml - -- Ant build file used to run (and optionally build from source) the TCK - -jsr352-tck.properties - -- Specify the location of required properties here \ No newline at end of file diff --git a/spring-batch-jsr352-tck/pom.xml b/spring-batch-jsr352-tck/pom.xml deleted file mode 100644 index 88356c4cd..000000000 --- a/spring-batch-jsr352-tck/pom.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - 4.0.0 - - org.springframework.batch - spring-batch - 5.0.0-SNAPSHOT - - spring-batch-jsr352-tck - Spring Batch JSR-352 TCK - Executes the JSR-352-TCK suite - - - ${project.basedir}/jsr352-tck-1.0 - - - - - jakarta.batch - jakarta.batch-api - ${jakarta.batch-api.version} - - - org.springframework.batch - spring-batch-core - ${project.version} - - - org.springframework - spring-jdbc - ${spring-framework.version} - - - org.hsqldb - hsqldb - ${hsqldb.version} - - - org.apache.commons - commons-dbcp2 - ${commons-dbcp2.version} - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - 3.0.0 - - - run-jsr352-tck - verify - - run - - - - - - - - - - - - org.apache.maven.plugins - maven-deploy-plugin - ${maven-deploy-plugin.version} - - true - - - - - - \ No newline at end of file diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/person/PersonService.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/person/PersonService.java index 8b1afdc32..78b45b69f 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/person/PersonService.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/person/PersonService.java @@ -24,7 +24,7 @@ import org.springframework.batch.sample.domain.order.Address; /** * Custom class that contains logic that would normally be be contained in * {@link org.springframework.batch.item.ItemReader} and - * {@link jakarta.batch.api.chunk.ItemWriter}. + * {@link org.springframework.batch.item.ItemWriter}. * * @author tomas.slanina * @author Robert Kasanicky diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleBatchlet.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleBatchlet.java deleted file mode 100644 index 75c4ce441..000000000 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleBatchlet.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - * 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.sample.jsr352; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import jakarta.batch.api.AbstractBatchlet; -import jakarta.batch.api.BatchProperty; -import jakarta.inject.Inject; - -/** - *

- * Sample {@link jakarta.batch.api.Batchlet} implementation. - *

- * - * @since 3.0 - * @author Chris Schaefer - */ -public class JsrSampleBatchlet extends AbstractBatchlet { - private static final Log LOG = LogFactory.getLog(JsrSampleBatchlet.class); - - @Inject - @BatchProperty - private String remoteServiceURL; - - @Override - public String process() throws Exception { - if (LOG.isInfoEnabled()) { - LOG.info("Calling remote service at: " + remoteServiceURL); - } - Thread.sleep(2000); - - LOG.info("Remote service call complete"); - - return null; - } -} diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemProcessor.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemProcessor.java deleted file mode 100644 index 4429592ed..000000000 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemProcessor.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * 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.sample.jsr352; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import jakarta.batch.api.chunk.ItemProcessor; - -/** - *

- * Sample {@link jakarta.batch.api.chunk.ItemProcessor} implementation. - *

- * - * @since 3.0 - * @author Chris Schaefer - */ -public class JsrSampleItemProcessor implements ItemProcessor { - private static final Log LOG = LogFactory.getLog(JsrSampleItemProcessor.class); - - @Override - public Object processItem(Object o) throws Exception { - String person = (String) o; - - if (LOG.isInfoEnabled()) { - LOG.info("Transforming person: " + person + " to uppercase"); - } - return person.toUpperCase(); - } -} diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemReader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemReader.java deleted file mode 100644 index 6100980da..000000000 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemReader.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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.sample.jsr352; - -import java.util.ArrayList; -import java.util.List; -import jakarta.batch.api.chunk.AbstractItemReader; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - *

- * Sample {@link jakarta.batch.api.chunk.ItemReader} implementation. - *

- * - * @since 3.0 - * @author Chris Schaefer - */ -@SuppressWarnings("serial") -public class JsrSampleItemReader extends AbstractItemReader { - private static final Log LOG = LogFactory.getLog(JsrSampleItemReader.class); - - private List people = new ArrayList() {{ - add("John"); - add("Joe"); - add("Mark"); - add("Jane"); - }}; - - @Override - public Object readItem() throws Exception { - String person = null; - - if(people.iterator().hasNext()) { - person = people.iterator().next(); - people.remove(person); - if (LOG.isInfoEnabled()) { - LOG.info("Read person: " + person); - } - } - - return person; - } -} diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemWriter.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemWriter.java deleted file mode 100644 index a5dd77c4b..000000000 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleItemWriter.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * 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.sample.jsr352; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import jakarta.batch.api.chunk.AbstractItemWriter; -import java.util.List; - -/** - *

- * Sample {@link jakarta.batch.api.chunk.ItemWriter} implementation. - *

- * - * @since 3.0 - * @author Chris Schaefer - */ -public class JsrSampleItemWriter extends AbstractItemWriter { - private static final Log LOG = LogFactory.getLog(JsrSampleItemWriter.class); - - @Override - public void writeItems(List people) throws Exception { - for(Object person : people) { - if (LOG.isInfoEnabled()) { - LOG.info("Writing person: " + person); - } - } - } -} diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleTasklet.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleTasklet.java deleted file mode 100644 index 9101cc6c9..000000000 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jsr352/JsrSampleTasklet.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - * 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.sample.jsr352; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.batch.core.step.tasklet.Tasklet; -import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.lang.Nullable; - -import jakarta.batch.api.BatchProperty; -import jakarta.inject.Inject; - -/** - *

- * Sample {@link org.springframework.batch.core.step.tasklet.Tasklet} implementation. - *

- * - * @since 3.0 - * @author Chris Schaefer - */ -public class JsrSampleTasklet implements Tasklet { - private static final Log LOG = LogFactory.getLog(JsrSampleTasklet.class); - - @Inject - @BatchProperty - private String remoteServiceURL; - - @Nullable - @Override - public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception { - if (LOG.isInfoEnabled()) { - LOG.info("Calling remote service at: " + remoteServiceURL); - } - - Thread.sleep(2000); - - LOG.info("Remote service call complete"); - - return RepeatStatus.FINISHED; - } -} diff --git a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/batchXmlConfigSample.xml b/spring-batch-samples/src/main/resources/META-INF/batch-jobs/batchXmlConfigSample.xml deleted file mode 100644 index b62343d6c..000000000 --- a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/batchXmlConfigSample.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/inlineConfigSample.xml b/spring-batch-samples/src/main/resources/META-INF/batch-jobs/inlineConfigSample.xml deleted file mode 100644 index d99b61db9..000000000 --- a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/inlineConfigSample.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/springConfigSample.xml b/spring-batch-samples/src/main/resources/META-INF/batch-jobs/springConfigSample.xml deleted file mode 100644 index 0f7dcb300..000000000 --- a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/springConfigSample.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/springConfigSampleContext.xml b/spring-batch-samples/src/main/resources/META-INF/batch-jobs/springConfigSampleContext.xml deleted file mode 100644 index 3e3221c53..000000000 --- a/spring-batch-samples/src/main/resources/META-INF/batch-jobs/springConfigSampleContext.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - John - Joe - Mark - Jane - - - - - - - - - - - diff --git a/spring-batch-samples/src/main/resources/META-INF/batch.xml b/spring-batch-samples/src/main/resources/META-INF/batch.xml deleted file mode 100644 index 47caaf4ff..000000000 --- a/spring-batch-samples/src/main/resources/META-INF/batch.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/jsr352/JsrConfigSampleTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/jsr352/JsrConfigSampleTests.java deleted file mode 100644 index 8cd088d17..000000000 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/jsr352/JsrConfigSampleTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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. - * 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.sample.jsr352; - -import org.junit.Before; -import org.junit.Test; - -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import java.util.Properties; - -import static org.junit.Assert.assertTrue; - -/** - *

- * Test cases to run JSR-352 configuration samples. - *

- * - * @since 3.0 - * @author Chris Schaefer - * @author Mahmoud Ben Hassine - */ -public class JsrConfigSampleTests { - private Properties properties = new Properties(); - - @Before - public void setup() { - properties.setProperty("remoteServiceURL", "https://api.example.com"); - } - - /** - *

- * Use inline class names as batch artifact references. - *

- */ - @Test - public void inlineConfigSampleTest() { - JobOperator jobOperator = BatchRuntime.getJobOperator(); - Long executionId = jobOperator.start("inlineConfigSample", properties); - - BatchStatus batchStatus = waitForJobComplete(jobOperator, executionId); - assertTrue(BatchStatus.COMPLETED.equals(batchStatus)); - } - - /** - *

- * Use batch artifact references defined in batch.xml. - *

- */ - @Test - public void batchXmlConfigSampleTest() { - JobOperator jobOperator = BatchRuntime.getJobOperator(); - Long executionId = jobOperator.start("batchXmlConfigSample", properties); - - BatchStatus batchStatus = waitForJobComplete(jobOperator, executionId); - assertTrue(BatchStatus.COMPLETED.equals(batchStatus)); - } - - /** - *

- * Use batch artifact references defined via Spring beans. - *

- */ - @Test - public void springConfigSampleTest() { - JobOperator jobOperator = BatchRuntime.getJobOperator(); - Long executionId = jobOperator.start("springConfigSampleContext", properties); - - BatchStatus batchStatus = waitForJobComplete(jobOperator, executionId); - assertTrue(BatchStatus.COMPLETED.equals(batchStatus)); - } - - // JSR jobs run async - private BatchStatus waitForJobComplete(JobOperator jobOperator, long executionId) { - JobExecution execution = jobOperator.getJobExecution(executionId); - - BatchStatus curBatchStatus = execution.getBatchStatus(); - - while(true) { - if(curBatchStatus == BatchStatus.STOPPED || curBatchStatus == BatchStatus.COMPLETED || curBatchStatus == BatchStatus.FAILED) { - break; - } - - execution = jobOperator.getJobExecution(executionId); - curBatchStatus = execution.getBatchStatus(); - } - - return curBatchStatus; - } -} diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JsrTestUtils.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JsrTestUtils.java deleted file mode 100644 index 1f397c490..000000000 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JsrTestUtils.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2013-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.test; - -import jakarta.batch.operations.JobOperator; -import jakarta.batch.runtime.BatchRuntime; -import jakarta.batch.runtime.BatchStatus; -import jakarta.batch.runtime.JobExecution; -import jakarta.batch.runtime.Metric; -import jakarta.batch.runtime.StepExecution; -import java.util.Date; -import java.util.Properties; -import java.util.concurrent.TimeoutException; - -import org.springframework.lang.Nullable; - -/** - * Provides testing utilities to execute JSR-352 jobs and block until they are complete (since all JSR-352 based jobs - * are executed asynchronously). - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @since 3.0 - */ -public class JsrTestUtils { - - private static JobOperator operator; - - static { - operator = BatchRuntime.getJobOperator(); - } - - private JsrTestUtils() {} - - /** - * Executes a job and waits for it's status to be any of {@link BatchStatus#STOPPED}, - * {@link BatchStatus#COMPLETED}, or {@link BatchStatus#FAILED}. If the job does not - * reach one of those statuses within the given timeout, a {@link java.util.concurrent.TimeoutException} is - * thrown. - * - * @param jobName the name of the job. - * @param properties job parameters to be associated with the job. - * @param timeout maximum amount of time to wait in milliseconds. - * @return the {@link JobExecution} for the final state of the job - * @throws java.util.concurrent.TimeoutException if the timeout occurs - */ - public static JobExecution runJob(String jobName, Properties properties, long timeout) throws TimeoutException{ - long executionId = operator.start(jobName, properties); - JobExecution execution = operator.getJobExecution(executionId); - - Date curDate = new Date(); - BatchStatus curBatchStatus = execution.getBatchStatus(); - - while(true) { - if(curBatchStatus == BatchStatus.STOPPED || curBatchStatus == BatchStatus.COMPLETED || curBatchStatus == BatchStatus.FAILED) { - break; - } - - if(new Date().getTime() - curDate.getTime() > timeout) { - throw new TimeoutException("Job processing did not complete in time"); - } - - execution = operator.getJobExecution(executionId); - curBatchStatus = execution.getBatchStatus(); - } - return execution; - } - - /** - * Restarts a job and waits for it's status to be any of {@link BatchStatus#STOPPED}, - * {@link BatchStatus#COMPLETED}, or {@link BatchStatus#FAILED}. If the job does not - * reach one of those statuses within the given timeout, a {@link java.util.concurrent.TimeoutException} is - * thrown. - * - * @param executionId the id of the job execution to restart. - * @param properties job parameters to be associated with the job. - * @param timeout maximum amount of time to wait in milliseconds. - * @return the {@link JobExecution} for the final state of the job - * @throws java.util.concurrent.TimeoutException if the timeout occurs - */ - public static JobExecution restartJob(long executionId, Properties properties, long timeout) throws TimeoutException { - long restartId = operator.restart(executionId, properties); - JobExecution execution = operator.getJobExecution(restartId); - - Date curDate = new Date(); - BatchStatus curBatchStatus = execution.getBatchStatus(); - - while(true) { - if(curBatchStatus == BatchStatus.STOPPED || curBatchStatus == BatchStatus.COMPLETED || curBatchStatus == BatchStatus.FAILED) { - break; - } - - if(new Date().getTime() - curDate.getTime() > timeout) { - throw new TimeoutException("Job processing did not complete in time"); - } - - execution = operator.getJobExecution(restartId); - curBatchStatus = execution.getBatchStatus(); - } - return execution; - } - - @Nullable - public static Metric getMetric(StepExecution stepExecution, Metric.MetricType type) { - Metric[] metrics = stepExecution.getMetrics(); - - for (Metric metric : metrics) { - if(metric.getType() == type) { - return metric; - } - } - - return null; - } - -} diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/MetaDataInstanceFactory.java b/spring-batch-test/src/main/java/org/springframework/batch/test/MetaDataInstanceFactory.java index 5be0d8218..698d779ef 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/MetaDataInstanceFactory.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/MetaDataInstanceFactory.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. @@ -30,6 +30,7 @@ import org.springframework.batch.support.PropertiesConverter; * {@link JobInstance} and {@link StepExecution}. * * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public class MetaDataInstanceFactory { @@ -138,7 +139,7 @@ public class MetaDataInstanceFactory { */ public static JobExecution createJobExecution(String jobName, Long instanceId, Long executionId, JobParameters jobParameters) { - return new JobExecution(createJobInstance(jobName, instanceId), executionId, jobParameters, null); + return new JobExecution(createJobInstance(jobName, instanceId), executionId, jobParameters); } /**