OPEN - issue BATCH-378: RepeatListener is confusing and too generic to use for 'intercepting' a step

http://jira.springframework.org/browse/BATCH-378

Open StepListsner with StepExecution.
This commit is contained in:
dsyer
2008-02-28 16:24:46 +00:00
parent 611ab8bfbe
commit e9f0b41eed
6 changed files with 81 additions and 31 deletions

View File

@@ -25,15 +25,25 @@ import org.springframework.batch.repeat.ExitStatus;
public interface StepListener {
/**
* Initialise the state of the listener with the job parameters from the
* current scope.
* @param jobParameters
* Initialise the state of the listener with the {@link StepExecution} from
* the current scope.
* @param stepExecution
*/
void open(JobParameters jobParameters);
void open(StepExecution stepExecution);
/**
* The value returned will be combined with the normal exit status using
* {@link ExitStatus#and(ExitStatus)}.
*
* @param e an exception thrown by the step execution
* @return an exit status to be combined with the normal one, or null
*/
ExitStatus onError(Throwable e);
/**
* Give a listener a chance to modify the exit status from a step. The value
* returned will be combined with the normal exit status.
* returned will be combined with the normal exit status using
* {@link ExitStatus#and(ExitStatus)}.
*
* @return an {@link ExitStatus} to combine with the normal value. Return
* null to leave the old value unchanged.

View File

@@ -20,7 +20,7 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.springframework.batch.core.domain.JobParameters;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepListener;
import org.springframework.batch.repeat.ExitStatus;
@@ -79,11 +79,23 @@ public class CompositeStepListener implements StepListener {
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.StepListener#open(org.springframework.batch.core.domain.JobParameters)
*/
public void open(JobParameters jobParameters) {
public void open(StepExecution stepExecution) {
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
StepListener listener = (StepListener) iterator.next();
listener.open(jobParameters);
listener.open(stepExecution);
}
}
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.StepListener#onError(java.lang.Throwable)
*/
public ExitStatus onError(Throwable e) {
ExitStatus status = null;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
StepListener listener = (StepListener) iterator.next();
ExitStatus close = listener.onError(e);
status = status!=null ? status.and(close): close;
}
return status;
}
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.batch.core.interceptor;
import org.springframework.batch.core.domain.JobParameters;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepListener;
import org.springframework.batch.repeat.ExitStatus;
@@ -29,13 +29,19 @@ public class StepListenerSupport implements StepListener {
* @see org.springframework.batch.core.domain.StepListener#close()
*/
public ExitStatus close() {
return ExitStatus.CONTINUABLE;
return null;
}
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.StepListener#open(org.springframework.batch.item.ExecutionContext)
*/
public void open(JobParameters jobParameters) {
public void open(StepExecution stepExecution) {
}
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.StepListener#onError(java.lang.Throwable)
*/
public ExitStatus onError(Throwable e) {
return null;
}
}

View File

@@ -20,8 +20,9 @@ import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.core.domain.JobParameters;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepListener;
import org.springframework.batch.core.domain.StepSupport;
import org.springframework.batch.repeat.ExitStatus;
/**
@@ -71,15 +72,30 @@ public class CompositeStepListenerTests extends TestCase {
/**
* Test method for
* {@link org.springframework.batch.core.interceptor.CompositeStepListener#open(JobParameters)}.
* {@link org.springframework.batch.core.interceptor.CompositeStepListener#open(StepExecution)}.
*/
public void testOpen() {
listener.setListener(new StepListenerSupport() {
public void open(JobParameters jobParameters) {
public void open(StepExecution stepExecution) {
list.add("foo");
}
});
listener.open(new JobParameters());
listener.open(new StepExecution(new StepSupport("foo"), null));
assertEquals(1, list.size());
}
/**
* Test method for
* {@link org.springframework.batch.core.interceptor.CompositeStepListener#open(StepExecution)}.
*/
public void testOnError() {
listener.setListener(new StepListenerSupport() {
public ExitStatus onError(Throwable e) {
list.add("foo");
return null;
}
});
listener.onError(new RuntimeException());
assertEquals(1, list.size());
}

View File

@@ -83,7 +83,8 @@ public class TaskletStep implements Step, InitializingBean, BeanNameAware {
this.name = name;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.core.domain.Step#getStartLimit()
*/
public int getStartLimit() {
@@ -99,7 +100,8 @@ public class TaskletStep implements Step, InitializingBean, BeanNameAware {
this.startLimit = startLimit;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.core.domain.Step#isAllowStartIfComplete()
*/
public boolean isAllowStartIfComplete() {
@@ -180,8 +182,14 @@ public class TaskletStep implements Step, InitializingBean, BeanNameAware {
Exception fatalException = null;
try {
listener.open(stepExecution.getJobParameters());
exitStatus = tasklet.execute();
listener.open(stepExecution);
exitStatus = tasklet.execute();
try {
exitStatus = exitStatus.and(listener.close());
}
catch (Exception e) {
logger.error("Encountered an error on listener close.", e);
}
try {
jobRepository.saveOrUpdateExecutionContext(stepExecution);
@@ -193,23 +201,21 @@ public class TaskletStep implements Step, InitializingBean, BeanNameAware {
}
}
catch (RuntimeException e) {
logger.error("Encountered an error running the tasklet");
updateStatus(stepExecution, BatchStatus.FAILED);
throw e;
}
catch (Exception e) {
logger.error("Encountered an error running the tasklet");
updateStatus(stepExecution, BatchStatus.FAILED);
try {
exitStatus = exitStatus.and(listener.onError(e));
}
catch (Exception ex) {
logger.error("Encountered an error on listener close.", ex);
}
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new BatchCriticalException(e);
}
finally {
try {
exitStatus = exitStatus.and(listener.close());
}
catch (Exception e) {
logger.error("Encountered an error on listener close.", e);
}
stepExecution.setExitStatus(exitStatus);
stepExecution.setEndTime(new Date());
try {

View File

@@ -105,7 +105,7 @@ public class TaskletStepTests extends TestCase {
public void testSuccessfulExecutionWithListener() throws Exception {
TaskletStep step = new TaskletStep(new StubTasklet(false, false), new JobRepositorySupport());
step.setListener(new StepListenerSupport() {
public void open(JobParameters context) {
public void open(StepExecution context) {
list.add("open");
}
public ExitStatus close() {