Merge pull request #105 from mminella/BATCH-1943

BATCH-1943: Added ChunkContext to all ChunkListener calls
This commit is contained in:
Michael Minella
2013-01-09 07:35:45 -08:00
17 changed files with 73 additions and 64 deletions

View File

@@ -32,13 +32,17 @@ public interface ChunkListener extends StepListener {
/**
* Callback before the chunk is executed, but inside the transaction.
*
* @param context The current {@link ChunkContext}
*/
void beforeChunk();
void beforeChunk(ChunkContext context);
/**
* Callback after the chunk is executed, outside the transaction.
*
* @param context The current {@link ChunkContext}
*/
void afterChunk();
void afterChunk(ChunkContext context);
/**
* Callback after a chunk has been marked for rollback. It is invoked

View File

@@ -21,15 +21,16 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.batch.core.ChunkListener;
import org.springframework.batch.core.scope.context.ChunkContext;
/**
* Marks a method to be called after a chunk is executed.<br>
* <br/>
* Expected signature: void afterChunk()
*
* Expected signature: void afterChunk(ChunkContext context)
*
* @author Lucas Ward
* @since 2.0
* @see ChunkListener#afterChunk()
* @see ChunkListener#afterChunk(ChunkContext context)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})

View File

@@ -31,7 +31,7 @@ import org.springframework.batch.core.scope.context.ChunkContext;
*
* @author Michael Minella
* @since 2.2
* @see ChunkListener#afterChunkError(ChunkContext)
* @see ChunkListener#afterChunkError(ChunkContext context)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-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.
@@ -21,15 +21,16 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.batch.core.ChunkListener;
import org.springframework.batch.core.scope.context.ChunkContext;
/**
* Marks a method to be called before a chunk is executed. <br>
* <br>
* Expected signature: void beforeChunk()
*
* Expected signature: void beforeChunk(ChunkContext context)
*
* @author Lucas Ward
* @since 2.0
* @see ChunkListener#beforeChunk()
* @see ChunkListener#beforeChunk(ChunkContext context)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})

View File

@@ -22,6 +22,7 @@ import org.springframework.batch.core.scope.context.ChunkContext;
* Basic support implementation of {@link ChunkListener}
*
* @author Lucas Ward
* @author Michael Minella
*
*/
public class ChunkListenerSupport implements ChunkListener {
@@ -30,14 +31,14 @@ public class ChunkListenerSupport implements ChunkListener {
* @see org.springframework.batch.core.domain.ChunkListener#afterChunk()
*/
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
}
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.ChunkListener#beforeChunk()
*/
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
}

View File

@@ -49,29 +49,29 @@ public class CompositeChunkListener implements ChunkListener {
}
/**
* Call the registered listeners in order, respecting and prioritising those
* Call the registered listeners in order, respecting and prioritizing those
* that implement {@link Ordered}.
*
* @see org.springframework.batch.core.ChunkListener#afterChunk()
* @see org.springframework.batch.core.ChunkListener#afterChunk(ChunkContext context)
*/
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
for (Iterator<ChunkListener> iterator = listeners.iterator(); iterator.hasNext();) {
ChunkListener listener = iterator.next();
listener.afterChunk();
listener.afterChunk(context);
}
}
/**
* Call the registered listeners in reverse order.
*
* @see org.springframework.batch.core.ChunkListener#beforeChunk()
* @see org.springframework.batch.core.ChunkListener#beforeChunk(ChunkContext context)
*/
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
for (Iterator<ChunkListener> iterator = listeners.reverse(); iterator.hasNext();) {
ChunkListener listener = iterator.next();
listener.beforeChunk();
listener.beforeChunk(context);
}
}

View File

@@ -176,12 +176,12 @@ ItemProcessListener<T, S>, ItemWriteListener<S>, SkipListener<T, S> {
/**
*
* @see org.springframework.batch.core.listener.CompositeChunkListener#afterChunk()
* @see org.springframework.batch.core.listener.CompositeChunkListener#afterChunk(ChunkContext context)
*/
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
try {
chunkListener.afterChunk();
chunkListener.afterChunk(context);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in afterChunk.", e);
@@ -190,12 +190,12 @@ ItemProcessListener<T, S>, ItemWriteListener<S>, SkipListener<T, S> {
/**
*
* @see org.springframework.batch.core.listener.CompositeChunkListener#beforeChunk()
* @see org.springframework.batch.core.listener.CompositeChunkListener#beforeChunk(ChunkContext context)
*/
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
try {
chunkListener.beforeChunk();
chunkListener.beforeChunk(context);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in beforeChunk.", e);

View File

@@ -59,8 +59,8 @@ public enum StepListenerMetaData implements ListenerMetaData {
BEFORE_STEP("beforeStep", "before-step-method", BeforeStep.class, StepExecutionListener.class, StepExecution.class),
AFTER_STEP("afterStep", "after-step-method", AfterStep.class, StepExecutionListener.class, StepExecution.class),
BEFORE_CHUNK("beforeChunk", "before-chunk-method", BeforeChunk.class, ChunkListener.class),
AFTER_CHUNK("afterChunk", "after-chunk-method", AfterChunk.class, ChunkListener.class),
BEFORE_CHUNK("beforeChunk", "before-chunk-method", BeforeChunk.class, ChunkListener.class, ChunkContext.class),
AFTER_CHUNK("afterChunk", "after-chunk-method", AfterChunk.class, ChunkListener.class, ChunkContext.class),
AFTER_CHUNK_ERROR("afterChunkError", "after-chunk-error-method", AfterChunkError.class, ChunkListener.class, ChunkContext.class),
BEFORE_READ("beforeRead", "before-read-method", BeforeRead.class, ItemReadListener.class),
AFTER_READ("afterRead", "after-read-method", AfterRead.class, ItemReadListener.class, Object.class),

View File

@@ -53,17 +53,17 @@ ItemReadListener<T>, ItemProcessListener<T,S>, ItemWriteListener<S>, SkipListene
}
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.ChunkListener#afterChunk()
* @see org.springframework.batch.core.domain.ChunkListener#afterChunk(ChunkContext context)
*/
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
}
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.ChunkListener#beforeChunk()
* @see org.springframework.batch.core.domain.ChunkListener#beforeChunk(ChunkContext context)
*/
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
}
/* (non-Javadoc)

View File

@@ -649,9 +649,9 @@ public class FaultTolerantStepBuilder<I, O> extends SimpleStepBuilder<I, O> {
}
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
try {
chunkListener.beforeChunk();
chunkListener.beforeChunk(context);
}
catch (Throwable t) {
throw new FatalStepExecutionException("ChunkListener threw exception, rethrowing as fatal", t);
@@ -659,9 +659,9 @@ public class FaultTolerantStepBuilder<I, O> extends SimpleStepBuilder<I, O> {
}
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
try {
chunkListener.afterChunk();
chunkListener.afterChunk(context);
}
catch (Throwable t) {
throw new FatalStepExecutionException("ChunkListener threw exception, rethrowing as fatal", t);

View File

@@ -272,7 +272,7 @@ public class TaskletStep extends AbstractStep {
throw (Exception) e.getCause();
}
chunkListener.afterChunk();
chunkListener.afterChunk(chunkContext);
// Check for interruption after transaction as well, so that
// the interrupted exception is correctly propagated up to
@@ -380,7 +380,7 @@ public class TaskletStep extends AbstractStep {
StepContribution contribution = stepExecution.createStepContribution();
chunkListener.beforeChunk();
chunkListener.beforeChunk(chunkContext);
// In case we need to push it back to its old value
// after a commit fails...

View File

@@ -33,9 +33,11 @@ public class CompositeChunkListenerTests {
ChunkListener listener;
CompositeChunkListener compositeListener;
ChunkContext chunkContext;
@Before
public void setUp() throws Exception {
chunkContext = new ChunkContext(null);
listener = createMock(ChunkListener.class);
compositeListener = new CompositeChunkListener();
compositeListener.register(listener);
@@ -43,19 +45,18 @@ public class CompositeChunkListenerTests {
@Test
public void testBeforeChunk(){
listener.beforeChunk();
listener.beforeChunk(chunkContext);
replay(listener);
compositeListener.beforeChunk();
compositeListener.beforeChunk(chunkContext);
verify(listener);
}
@Test
public void testAfterChunk(){
listener.afterChunk();
listener.afterChunk(chunkContext);
replay(listener);
compositeListener.afterChunk();
compositeListener.afterChunk(chunkContext);
verify(listener);
}

View File

@@ -25,6 +25,7 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.scope.context.ChunkContext;
/**
* @author Dave Syer
@@ -128,25 +129,25 @@ public class MulticasterBatchListenerTests {
/**
* Test method for
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#afterChunk()}
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#afterChunk(ChunkContext context)}
* .
*/
@Test
public void testAfterChunk() {
multicast.afterChunk();
multicast.afterChunk(null);
assertEquals(1, count);
}
/**
* Test method for
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#afterChunk()}
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#afterChunk(ChunkContext context)}
* .
*/
@Test
public void testAfterChunkFails() {
error = true;
try {
multicast.afterChunk();
multicast.afterChunk(null);
fail("Expected StepListenerFailedException");
}
catch (StepListenerFailedException e) {
@@ -159,25 +160,25 @@ public class MulticasterBatchListenerTests {
/**
* Test method for
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#beforeChunk()}
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#beforeChunk(ChunkContext context)}
* .
*/
@Test
public void testBeforeChunk() {
multicast.beforeChunk();
multicast.beforeChunk(null);
assertEquals(1, count);
}
/**
* Test method for
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#beforeChunk()}
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#beforeChunk(ChunkContext context)}
* .
*/
@Test
public void testBeforeChunkFails() {
error = true;
try {
multicast.beforeChunk();
multicast.beforeChunk(null);
fail("Expected StepListenerFailedException");
}
catch (StepListenerFailedException e) {
@@ -528,12 +529,12 @@ public class MulticasterBatchListenerTests {
* ()
*/
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
count++;
if (error) {
throw new RuntimeException("listener error");
}
super.afterChunk();
super.afterChunk(context);
}
/*
@@ -576,12 +577,12 @@ public class MulticasterBatchListenerTests {
* ()
*/
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
count++;
if (error) {
throw new RuntimeException("listener error");
}
super.beforeChunk();
super.beforeChunk(context);
}
/*

View File

@@ -95,8 +95,8 @@ public class StepListenerFactoryBeanTests {
StepListener listener = (StepListener) factoryBean.getObject();
((StepExecutionListener) listener).beforeStep(stepExecution);
((StepExecutionListener) listener).afterStep(stepExecution);
((ChunkListener) listener).beforeChunk();
((ChunkListener) listener).afterChunk();
((ChunkListener) listener).beforeChunk(null);
((ChunkListener) listener).afterChunk(null);
((ChunkListener) listener).afterChunkError(new ChunkContext(null));
((ItemReadListener<String>) listener).beforeRead();
((ItemReadListener<String>) listener).afterRead(readItem);

View File

@@ -598,14 +598,14 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
}
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
if(phase == 1){
throw new IllegalArgumentException("Planned exception");
}
}
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
if(phase == 2) {
throw new IllegalArgumentException("Planned exception");
}

View File

@@ -785,12 +785,12 @@ public class FaultTolerantStepFactoryBeanTests {
}
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
listenerCalls.add(4);
}
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
}
@Override

View File

@@ -256,13 +256,13 @@ public class SimpleStepFactoryBeanTests {
}
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
writeListener.trail = writeListener.trail + "4";
afterCount++;
}
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
writeListener.trail = writeListener.trail + "1";
beforeCount++;
}
@@ -399,12 +399,12 @@ public class SimpleStepFactoryBeanTests {
}
@Override
public void afterChunk() {
public void afterChunk(ChunkContext context) {
listenerCalls.add("chunk");
}
@Override
public void beforeChunk() {
public void beforeChunk(ChunkContext context) {
}
@Override