/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://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.repeat.listener;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatListener;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
public class RepeatListenerTests extends TestCase {
int count = 0;
public void testBeforeInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.setListeners(new RepeatListener[] { new RepeatListenerSupport() {
@Override
public void before(RepeatContext context) {
calls.add("1");
}
}, new RepeatListenerSupport() {
@Override
public void before(RepeatContext context) {
calls.add("2");
}
} });
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
count++;
return RepeatStatus.continueIf(count <= 1);
}
});
// 2 calls: the second time there is no processing
// (despite the fact that the callback returned null and batch was
// complete). Is this OK?
assertEquals(2, count);
// ... but the interceptor before() was called:
assertEquals("[1, 2, 1, 2]", calls.toString());
}
public void testBeforeInterceptorCanVeto() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.registerListener(new RepeatListenerSupport() {
@Override
public void before(RepeatContext context) {
calls.add("1");
context.setCompleteOnly();
}
});
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
count++;
return RepeatStatus.FINISHED;
}
});
assertEquals(0, count);
// ... but the interceptor before() was called:
assertEquals("[1]", calls.toString());
}
public void testAfterInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.setListeners(new RepeatListener[] { new RepeatListenerSupport() {
@Override
public void after(RepeatContext context, RepeatStatus result) {
calls.add("1");
}
}, new RepeatListenerSupport() {
@Override
public void after(RepeatContext context, RepeatStatus result) {
calls.add("2");
}
} });
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
count++;
return RepeatStatus.continueIf(count <= 1);
}
});
// 2 calls to the callback, and the second one had no processing...
assertEquals(2, count);
// ... so the interceptor after() is not called:
assertEquals("[2, 1]", calls.toString());
}
public void testOpenInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.setListeners(new RepeatListener[] { new RepeatListenerSupport() {
@Override
public void open(RepeatContext context) {
calls.add("1");
}
}, new RepeatListenerSupport() {
@Override
public void open(RepeatContext context) {
calls.add("2");
context.setCompleteOnly();
}
} });
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
count++;
return RepeatStatus.CONTINUABLE;
}
});
assertEquals(0, count);
assertEquals("[1, 2]", calls.toString());
}
public void testSingleOpenInterceptor() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.registerListener(new RepeatListenerSupport() {
@Override
public void open(RepeatContext context) {
calls.add("1");
}
});
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
count++;
context.setCompleteOnly();
return RepeatStatus.FINISHED;
}
});
assertEquals(1, count);
assertEquals("[1]", calls.toString());
}
public void testCloseInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.setListeners(new RepeatListener[] { new RepeatListenerSupport() {
@Override
public void close(RepeatContext context) {
calls.add("1");
}
}, new RepeatListenerSupport() {
@Override
public void close(RepeatContext context) {
calls.add("2");
}
} });
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
count++;
return RepeatStatus.continueIf(count < 2);
}
});
// Test that more than one call comes in to the callback...
assertEquals(2, count);
// ... but the interceptor is only called once.
assertEquals("[2, 1]", calls.toString());
}
public void testOnErrorInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.setListeners(new RepeatListener[] { new RepeatListenerSupport() {
@Override
public void onError(RepeatContext context, Throwable t) {
calls.add("1");
}
}, new RepeatListenerSupport() {
@Override
public void onError(RepeatContext context, Throwable t) {
calls.add("2");
}
} });
try {
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
throw new IllegalStateException("Bogus");
}
});
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
assertEquals(0, count);
assertEquals("[2, 1]", calls.toString());
}
public void testOnErrorInterceptorsPrecedence() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List<Object> calls = new ArrayList<Object>();
template.setListeners(new RepeatListener[] { new RepeatListenerSupport() {
@Override
public void after(RepeatContext context, RepeatStatus result) {
calls.add("1");
}
}, new RepeatListenerSupport() {
@Override
public void onError(RepeatContext context, Throwable t) {
calls.add("2");
}
} });
try {
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
throw new IllegalStateException("Bogus");
}
});
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
assertEquals(0, count);
// The after is not executed, if there is an error...
assertEquals("[2]", calls.toString());
}
public void testAsynchronousOnErrorInterceptorsPrecedence() throws Exception {
TaskExecutorRepeatTemplate template = new TaskExecutorRepeatTemplate();
template.setTaskExecutor(new SimpleAsyncTaskExecutor());
final List<Object> calls = new ArrayList<Object>();
final List<Object> fails = new ArrayList<Object>();
template.setListeners(new RepeatListener[] { new RepeatListenerSupport() {
@Override
public void after(RepeatContext context, RepeatStatus result) {
calls.add("1");
}
}, new RepeatListenerSupport() {
@Override
public void onError(RepeatContext context, Throwable t) {
calls.add("2");
fails.add("2");
}
} });
try {
template.iterate(new RepeatCallback() {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
throw new IllegalStateException("Bogus");
}
});
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
assertEquals("Bogus", e.getMessage());
}
assertEquals(0, count);
System.err.println(calls);
// The after is not executed on error...
assertEquals("2", calls.get(0));
assertEquals("2", calls.get(calls.size()-1));
assertFalse(calls.contains("1"));
assertEquals(fails.size(), calls.size());
}
}