BATCH-1016: applied patch promotionlistener-core-B-v2.patch
This commit is contained in:
@@ -15,11 +15,13 @@
|
||||
*/
|
||||
package org.springframework.batch.core.listener;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.support.util.PatternMatcher;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -32,12 +34,17 @@ import com.sun.org.apache.xerces.internal.impl.xpath.XPath.Step;
|
||||
* end of a step. A list of keys should be provided that correspond to the items
|
||||
* in the {@link Step} {@link ExecutionContext} that should be promoted.
|
||||
*
|
||||
* Additionally, an optional list of statuses can be set to indicate for which
|
||||
* exit status codes the promotion should occur. These statuses will be checked
|
||||
* using the {@link PatternMatcher}, so wildcards are allowed.
|
||||
*
|
||||
* @author Dan Garrette
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ExecutionContextPromotionListener extends StepExecutionListenerSupport implements InitializingBean {
|
||||
|
||||
private List<String> keys = null;
|
||||
private List<String> statuses = Collections.singletonList(ExitStatus.FINISHED.getExitCode());
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -46,19 +53,52 @@ public class ExecutionContextPromotionListener extends StepExecutionListenerSupp
|
||||
* stepExecution)
|
||||
*/
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
if (statuses == null) {
|
||||
this.performPromotion(stepExecution);
|
||||
}
|
||||
else {
|
||||
String exitCode = stepExecution.getExitStatus().getExitCode();
|
||||
for (String statusPattern : statuses) {
|
||||
if (PatternMatcher.match(statusPattern, exitCode)) {
|
||||
this.performPromotion(stepExecution);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void performPromotion(StepExecution stepExecution) {
|
||||
ExecutionContext stepContext = stepExecution.getExecutionContext();
|
||||
ExecutionContext jobContext = stepExecution.getJobExecution().getExecutionContext();
|
||||
for (String key : keys) {
|
||||
jobContext.put(key, stepContext.get(key));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(this.keys, "The 'keys' property must be provided");
|
||||
Assert.notEmpty(this.statuses, "The 'keys' property must not be empty");
|
||||
Assert.notNull(this.statuses, "The 'statuses' property must be provided");
|
||||
Assert.notEmpty(this.statuses, "The 'statuses' property must not be empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keys
|
||||
* A list of keys corresponding to items in the {@link Step}
|
||||
* {@link ExecutionContext} that must be promoted.
|
||||
*/
|
||||
public void setKeys(List<String> keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param statuses
|
||||
* A list of statuses for which the promotion should occur.
|
||||
* Statuses can may contain wildcards recognizable by the
|
||||
* {@link PatternMatcher} class.
|
||||
*/
|
||||
public void setStatuses(List<String> statuses) {
|
||||
this.statuses = statuses;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import static org.junit.Assert.*;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -14,34 +15,140 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class ExecutionContextPromotionListenerTests {
|
||||
|
||||
private ExecutionContextPromotionListener tested = new ExecutionContextPromotionListener();
|
||||
|
||||
private static final String key = "testKey";
|
||||
|
||||
private static final String value = "testValue";
|
||||
private static final String key2 = "testKey2";
|
||||
private static final String value2 = "testValue2";
|
||||
private static final String status = "COMPLETED WITH SKIPS";
|
||||
private static final String status2 = "FAILURE";
|
||||
private static final String statusWildcard = "COMPL*SKIPS";
|
||||
|
||||
/**
|
||||
* CONDITION: keys = {key1, key2}. statuses is not set (defaults to
|
||||
* {COMPLETED}).
|
||||
*
|
||||
* EXPECTED: key is promoted. key2 is not.
|
||||
*/
|
||||
@Test
|
||||
public void promoteEntryFromStepToJobExectutionContext() throws Exception {
|
||||
public void promoteEntry_nullStatuses() throws Exception {
|
||||
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
|
||||
|
||||
JobExecution jobExecution = new JobExecution(1L);
|
||||
StepExecution stepExecution = jobExecution.createStepExecution("step1");
|
||||
stepExecution.setExitStatus(ExitStatus.FINISHED);
|
||||
|
||||
Assert.state(jobExecution.getExecutionContext().isEmpty());
|
||||
Assert.state(stepExecution.getExecutionContext().isEmpty());
|
||||
|
||||
stepExecution.getExecutionContext().putString(key, value);
|
||||
stepExecution.getExecutionContext().putString(key2, value2);
|
||||
|
||||
tested.setKeys(Collections.singletonList(key));
|
||||
tested.afterPropertiesSet();
|
||||
listener.setKeys(Collections.singletonList(key));
|
||||
listener.afterPropertiesSet();
|
||||
|
||||
tested.afterStep(stepExecution);
|
||||
listener.afterStep(stepExecution);
|
||||
|
||||
assertEquals(value, jobExecution.getExecutionContext().getString(key));
|
||||
assertFalse(jobExecution.getExecutionContext().containsKey(key2));
|
||||
}
|
||||
|
||||
/**
|
||||
* CONDITION: keys = {key1, key2}. statuses = {status}. ExitStatus = status
|
||||
*
|
||||
* EXPECTED: key is promoted. key2 is not.
|
||||
*/
|
||||
@Test
|
||||
public void promoteEntry_statusFound() throws Exception {
|
||||
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
|
||||
|
||||
JobExecution jobExecution = new JobExecution(1L);
|
||||
StepExecution stepExecution = jobExecution.createStepExecution("step1");
|
||||
stepExecution.setExitStatus(new ExitStatus(status));
|
||||
|
||||
Assert.state(jobExecution.getExecutionContext().isEmpty());
|
||||
Assert.state(stepExecution.getExecutionContext().isEmpty());
|
||||
|
||||
stepExecution.getExecutionContext().putString(key, value);
|
||||
stepExecution.getExecutionContext().putString(key2, value2);
|
||||
|
||||
listener.setKeys(Collections.singletonList(key));
|
||||
listener.setStatuses(Collections.singletonList(status));
|
||||
listener.afterPropertiesSet();
|
||||
|
||||
listener.afterStep(stepExecution);
|
||||
|
||||
assertEquals(value, jobExecution.getExecutionContext().getString(key));
|
||||
assertFalse(jobExecution.getExecutionContext().containsKey(key2));
|
||||
}
|
||||
|
||||
/**
|
||||
* CONDITION: keys = {key1, key2}. statuses = {status}. ExitStatus = status2
|
||||
*
|
||||
* EXPECTED: no promotions.
|
||||
*/
|
||||
@Test
|
||||
public void promoteEntry_statusNotFound() throws Exception {
|
||||
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
|
||||
|
||||
JobExecution jobExecution = new JobExecution(1L);
|
||||
StepExecution stepExecution = jobExecution.createStepExecution("step1");
|
||||
stepExecution.setExitStatus(new ExitStatus(status2));
|
||||
|
||||
Assert.state(jobExecution.getExecutionContext().isEmpty());
|
||||
Assert.state(stepExecution.getExecutionContext().isEmpty());
|
||||
|
||||
stepExecution.getExecutionContext().putString(key, value);
|
||||
stepExecution.getExecutionContext().putString(key2, value2);
|
||||
|
||||
listener.setKeys(Collections.singletonList(key));
|
||||
listener.setStatuses(Collections.singletonList(status));
|
||||
listener.afterPropertiesSet();
|
||||
|
||||
listener.afterStep(stepExecution);
|
||||
|
||||
assertFalse(jobExecution.getExecutionContext().containsKey(key));
|
||||
assertFalse(jobExecution.getExecutionContext().containsKey(key2));
|
||||
}
|
||||
|
||||
/**
|
||||
* CONDITION: keys = {key1, key2}. statuses = {statusWildcard}. ExitStatus =
|
||||
* status
|
||||
*
|
||||
* EXPECTED: key is promoted. key2 is not.
|
||||
*/
|
||||
@Test
|
||||
public void promoteEntry_statusWildcardFound() throws Exception {
|
||||
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
|
||||
|
||||
JobExecution jobExecution = new JobExecution(1L);
|
||||
StepExecution stepExecution = jobExecution.createStepExecution("step1");
|
||||
stepExecution.setExitStatus(new ExitStatus(status));
|
||||
|
||||
Assert.state(jobExecution.getExecutionContext().isEmpty());
|
||||
Assert.state(stepExecution.getExecutionContext().isEmpty());
|
||||
|
||||
stepExecution.getExecutionContext().putString(key, value);
|
||||
stepExecution.getExecutionContext().putString(key2, value2);
|
||||
|
||||
listener.setKeys(Collections.singletonList(key));
|
||||
listener.setStatuses(Collections.singletonList(statusWildcard));
|
||||
listener.afterPropertiesSet();
|
||||
|
||||
listener.afterStep(stepExecution);
|
||||
|
||||
assertEquals(value, jobExecution.getExecutionContext().getString(key));
|
||||
assertFalse(jobExecution.getExecutionContext().containsKey(key2));
|
||||
}
|
||||
|
||||
/**
|
||||
* CONDITION: keys = NULL
|
||||
*
|
||||
* EXPECTED: IllegalArgumentException
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void keysMustBeSet() throws Exception {
|
||||
// didn't set the keys, same as tested.setKeys(null);
|
||||
tested.afterPropertiesSet();
|
||||
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
|
||||
// didn't set the keys, same as listener.setKeys(null);
|
||||
listener.afterPropertiesSet();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user