@Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { stepTemplate.iterate(stepCallback); return RepeatStatus.FINISHED; } };
@Override public Void doInTransaction(org.springframework.transaction.TransactionStatus status) { repeatTemplate.iterate(new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { String text = (String) jmsTemplate.receiveAndConvert("queue"); list.add(text); jdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text); return RepeatStatus.continueIf(text != null); } }); // force rollback... status.setRollbackOnly(); return null; } });
@Test public void testExecute() throws Exception { template.iterate(new ItemReaderRepeatCallback<>(provider, processor)); assertEquals(NUMBER_OF_ITEMS, processor.count); }
public void testSingleOpenInterceptor() throws Exception { RepeatTemplate template = new RepeatTemplate(); final List<Object> calls = new ArrayList<>(); 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 testBeforeInterceptorCanVeto() throws Exception { RepeatTemplate template = new RepeatTemplate(); final List<Object> calls = new ArrayList<>(); 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<>(); 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 testCloseInterceptors() throws Exception { RepeatTemplate template = new RepeatTemplate(); final List<Object> calls = new ArrayList<>(); 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 testOpenInterceptors() throws Exception { RepeatTemplate template = new RepeatTemplate(); final List<Object> calls = new ArrayList<>(); 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()); }
@Transactional @Test public void testCommit() throws Exception { assertInitialState(); repeatTemplate.iterate(new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { String text = (String) jmsTemplate.receiveAndConvert("queue"); list.add(text); jdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text); return RepeatStatus.continueIf(text != null); } }); int count = jdbcTemplate.queryForObject("select count(*) from T_BARS", Integer.class); assertEquals(2, count); assertTrue(list.contains("foo")); assertTrue(list.contains("bar")); String text = (String) jmsTemplate.receiveAndConvert("queue"); assertEquals(null, text); }
@Test public void testExceptionThrownOnLastItem() throws Exception { template.setCompletionPolicy(new SimpleCompletionPolicy(2)); try { template.iterate(new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; if (count < 2) { return RepeatStatus.CONTINUABLE; } throw new RuntimeException("Barf second try count=" + count); } }); fail("Expected exception on last item in batch"); } catch (Exception e) { // expected assertEquals("Barf second try count=2", e.getMessage()); } }
/** * Check that a dedicated TerminationPolicy can terminate the batch. * * @throws Exception */ @Test public void testEarlyCompletionWithPolicy() throws Exception { template.setCompletionPolicy(new SimpleCompletionPolicy(2)); template.iterate(new ItemReaderRepeatCallback<>(provider, processor)); assertEquals(2, processor.count); }
/** * Test that a result is returned from the batch. * @throws Exception */ @Test public void testResult() throws Exception { RepeatStatus result = template.iterate(new ItemReaderRepeatCallback<>(provider, processor)); assertEquals(NUMBER_OF_ITEMS, processor.count); // We are complete - do not expect to be called again assertFalse(result.isContinuable()); }
/** * Check that a dedicated TerminationPolicy can terminate the batch. * * @throws Exception */ @Test public void testEarlyCompletionWithException() throws Exception { try { template.iterate(new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; throw new IllegalStateException("foo!"); } }); fail("Expected IllegalStateException"); } catch (IllegalStateException e) { assertEquals("foo!", e.getMessage()); } assertEquals(1, count); assertTrue("Too many attempts: "+count, count<=10); }
@Test public void testNestedSessionTerminatesBeforeIteration() throws Exception { RepeatTemplate outer = getRepeatTemplate(); RepeatTemplate inner = getRepeatTemplate(); outer.iterate(new NestedRepeatCallback(inner, new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; assertEquals(2, count); fail("Nested batch should not have been executed"); return RepeatStatus.FINISHED; } }) { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; context.setCompleteOnly(); return super.doInIteration(context); } }); assertEquals(1, count); }
/** * Check that a the context can be used to signal early completion. * * @throws Exception */ @Test public void testEarlyCompletionWithContext() throws Exception { RepeatStatus result = template.iterate(new ItemReaderRepeatCallback<Trade>(provider, processor) { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { RepeatStatus result = super.doInIteration(context); if (processor.count >= 2) { context.setCompleteOnly(); // If we return null the batch will terminate anyway // without an exception... } return result; } }); // 2 items were processed before completion signalled assertEquals(2, processor.count); // Not all items processed assertTrue(result.isContinuable()); }
@Test public void testNestedSession() throws Exception { RepeatTemplate outer = getRepeatTemplate(); RepeatTemplate inner = getRepeatTemplate(); outer.iterate(new NestedRepeatCallback(inner, new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; assertNotNull(context); assertNotSame("Nested batch should have new session", context, context.getParent()); assertSame(context, RepeatSynchronizationManager.getContext()); return RepeatStatus.FINISHED; } }) { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; assertSame(context, RepeatSynchronizationManager.getContext()); return super.doInIteration(context); } }); assertEquals(2, count); }
/** * Check that a the context can be used to signal early completion. * * @throws Exception */ @Test public void testEarlyCompletionWithContextTerminated() throws Exception { RepeatStatus result = template.iterate(new ItemReaderRepeatCallback<Trade>(provider, processor) { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { RepeatStatus result = super.doInIteration(context); if (processor.count >= 2) { context.setTerminateOnly(); // If we return null the batch will terminate anyway // without an exception... } return result; } }); // 2 items were processed before completion signalled assertEquals(2, processor.count); // Not all items processed assertTrue(result.isContinuable()); }
@Test public void testNestedSession() throws Exception { RepeatTemplate outer = getRepeatTemplate(); RepeatTemplate inner = new RepeatTemplate(); outer.iterate(new NestedRepeatCallback(inner, new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; assertNotNull(context); assertNotSame("Nested batch should have new session", context, context.getParent()); assertSame(context, RepeatSynchronizationManager.getContext()); return RepeatStatus.FINISHED; } }) { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; assertNotNull(context); assertSame(context, RepeatSynchronizationManager.getContext()); return super.doInIteration(context); } }); assertTrue("Too few attempts: " + count, count >= 1); assertTrue("Too many attempts: " + count, count <= 10); }
@Test public void testOuterContextPreserved() throws Exception { RepeatTemplate outer = getRepeatTemplate(); outer.setCompletionPolicy(new SimpleCompletionPolicy(2)); RepeatTemplate inner = getRepeatTemplate(); outer.iterate(new NestedRepeatCallback(inner, new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; assertNotNull(context); assertNotSame("Nested batch should have new session", context, context.getParent()); assertSame(context, RepeatSynchronizationManager.getContext()); return RepeatStatus.FINISHED; } }) { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; assertSame(context, RepeatSynchronizationManager.getContext()); super.doInIteration(context); return RepeatStatus.CONTINUABLE; } }); assertEquals(4, count); }
/** * Chunking with an asynchronous taskExecutor in the chunks. Transactions * have to be at the level of the business callback. */ @Test public void testAsynchronousChunkedBatchWithCompletionPolicy() throws Exception { RepeatTemplate repeatTemplate = new RepeatTemplate(); final RepeatCallback callback = new ItemReaderRepeatCallback<>(provider, processor); final TaskExecutorRepeatTemplate chunkTemplate = new TaskExecutorRepeatTemplate(); // The policy is resettable so we only have to resolve this dependency // once chunkTemplate.setCompletionPolicy(new SimpleCompletionPolicy(2)); chunkTemplate.setTaskExecutor(new SimpleAsyncTaskExecutor()); RepeatStatus result = repeatTemplate.iterate(new NestedRepeatCallback(chunkTemplate, callback) { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { count++; // for test assertion return super.doInIteration(context); } }); assertEquals(NUMBER_OF_ITEMS, processor.count); assertFalse(result.isContinuable()); assertTrue("Expected at least 3 chunks but found: "+count, count>=3); }