From d41464c1768d6797b5d1dc7fa82a9d048e532a8d Mon Sep 17 00:00:00 2001 From: dsyer Date: Mon, 25 Aug 2008 16:08:19 +0000 Subject: [PATCH] OPEN - issue BATCH-777: Parametrise RetryCallback and related interfaces Move key generator and item identifier to retry interceptor package --- .../batch/jms/ExternalRetryInBatchTests.java | 18 +-- .../batch/retry/jms/ExternalRetryTests.java | 17 +-- .../batch/item/jms/JmsItemReader.java | 136 +----------------- .../batch/item/jms/JmsItemWriter.java | 64 +++++++++ .../jms/JmsMethodArgumentsKeyGenerator.java | 61 ++++++++ .../jms/JmsMethodInvocationRecoverer.java | 63 ++++++++ .../jms/JmsNewMethodArgumentsIdentifier.java | 55 +++++++ .../batch/item/jms/MessageTypeAccessor.java | 68 +++++++++ .../MethodArgumentsKeyGenerator.java} | 8 +- .../MethodInvocationRecoverer.java} | 10 +- .../NewMethodArgumentsIdentifier.java} | 16 +-- .../StatefulRetryOperationsInterceptor.java | 41 +++--- .../batch/item/ItemRecoveryHandlerTests.java | 8 +- .../batch/item/jms/JmsItemReaderTests.java | 81 ----------- .../JmsMethodArgumentsKeyGeneratorTests.java | 52 +++++++ .../JmsMethodInvocationRecovererTests.java | 42 ++++++ .../JmsNewMethodArgumentsIdentifierTests.java | 48 +++++++ ...atefulRetryOperationsInterceptorTests.java | 5 +- .../retry/PollableSourceRetryTests.java | 25 ++-- 19 files changed, 519 insertions(+), 299 deletions(-) create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemWriter.java create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGenerator.java create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodInvocationRecoverer.java create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifier.java create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/MessageTypeAccessor.java rename spring-batch-infrastructure/src/main/java/org/springframework/batch/{item/ItemKeyGenerator.java => retry/interceptor/MethodArgumentsKeyGenerator.java} (84%) rename spring-batch-infrastructure/src/main/java/org/springframework/batch/{item/ItemRecoverer.java => retry/interceptor/MethodInvocationRecoverer.java} (83%) rename spring-batch-infrastructure/src/main/java/org/springframework/batch/{item/NewItemIdentifier.java => retry/interceptor/NewMethodArgumentsIdentifier.java} (62%) create mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java create mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java create mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java index 8ad275e53..533c952cd 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java @@ -28,7 +28,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; @@ -63,7 +62,7 @@ public class ExternalRetryInBatchTests { @Autowired private RepeatTemplate repeatTemplate; - private ItemReaderRecoverer provider; + private ItemReader provider; private SimpleJdbcTemplate jdbcTemplate; @@ -81,17 +80,12 @@ public class ExternalRetryInBatchTests { jdbcTemplate.getJdbcOperations().execute("delete from T_FOOS"); jmsTemplate.convertAndSend("queue", "foo"); jmsTemplate.convertAndSend("queue", "bar"); - provider = new ItemReaderRecoverer() { + provider = new ItemReader() { public String read() { String text = (String) jmsTemplate.receiveAndConvert("queue"); list.add(text); return text; } - - public String recover(String data, Throwable cause) { - recovered.add(data); - return data; - } }; retryTemplate = new RetryTemplate(); } @@ -109,7 +103,7 @@ public class ExternalRetryInBatchTests { private List list = new ArrayList(); - private List recovered = new ArrayList(); + private List recovered = new ArrayList(); @Test public void testExternalRetryRecoveryInBatch() throws Exception { @@ -153,7 +147,8 @@ public class ExternalRetryInBatchTests { public String recover(RetryContext context) { // aggressive commit on a recovery RepeatSynchronizationManager.setCompleteOnly(); - return provider.recover(item, context.getLastThrowable()); + recovered.add(item); + return item; } }; @@ -212,7 +207,4 @@ public class ExternalRetryInBatchTests { return msgs; } - private interface ItemReaderRecoverer extends ItemReader, ItemRecoverer { - - } } diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java index 197a335dd..d2af73012 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java @@ -29,7 +29,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.retry.RecoveryCallback; import org.springframework.batch.retry.RetryCallback; @@ -55,7 +54,7 @@ public class ExternalRetryTests { private RetryTemplate retryTemplate; - private ItemReaderRecoverer provider; + private ItemReader provider; private SimpleJdbcTemplate simpleJdbcTemplate; @@ -72,17 +71,12 @@ public class ExternalRetryTests { getMessages(); // drain queue simpleJdbcTemplate.getJdbcOperations().execute("delete from T_FOOS"); jmsTemplate.convertAndSend("queue", "foo"); - provider = new ItemReaderRecoverer() { + provider = new ItemReader() { public String read() { String text = (String) jmsTemplate.receiveAndConvert("queue"); list.add(text); return text; } - - public String recover(String data, Throwable cause) { - recovered.add(data); - return data; - } }; retryTemplate = new RetryTemplate(); } @@ -196,7 +190,8 @@ public class ExternalRetryTests { final RecoveryCallback recoveryCallback = new RecoveryCallback() { public String recover(RetryContext context) { - return provider.recover(item, context.getLastThrowable()); + recovered.add(item); + return item; } }; @@ -254,8 +249,4 @@ public class ExternalRetryTests { return msgs; } - private interface ItemReaderRecoverer extends ItemReader, ItemRecoverer { - - } - } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java index 3e09a4075..72a8c3281 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java @@ -16,27 +16,16 @@ package org.springframework.batch.item.jms; -import javax.jms.Destination; -import javax.jms.JMSException; import javax.jms.Message; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemRecoverer; -import org.springframework.batch.item.NewItemIdentifier; -import org.springframework.batch.item.UnexpectedInputException; -import org.springframework.jms.JmsException; -import org.springframework.jms.core.JmsOperations; import org.springframework.jms.core.JmsTemplate; import org.springframework.util.Assert; /** * An {@link ItemReader} for JMS using a {@link JmsTemplate}. The template * should have a default destination, which will be used to provide items in - * {@link #read()}. If a recovery step is needed, set the error destination and - * the item will be sent there if processing fails in a stateful retry. + * {@link #read()}.

* * The implementation is thread safe after its properties are set (normal * singleton behaviour). @@ -44,60 +33,7 @@ import org.springframework.util.Assert; * @author Dave Syer * */ -public class JmsItemReader implements ItemReader, ItemRecoverer, ItemKeyGenerator, - NewItemIdentifier { - - protected Log logger = LogFactory.getLog(getClass()); - - private JmsOperations jmsTemplate; - - private Class itemType; - - private String errorDestinationName; - - private Destination errorDestination; - - /** - * Set the error destination. Should not be the same as the default - * destination of the jms template. - * @param errorDestination a JMS Destination - */ - public void setErrorDestination(Destination errorDestination) { - this.errorDestination = errorDestination; - } - - /** - * Set the error destination by name. Will be resolved by the destination - * resolver in the jms template. - * - * @param errorDestinationName the name of a JMS Destination - */ - public void setErrorDestinationName(String errorDestinationName) { - this.errorDestinationName = errorDestinationName; - } - - /** - * Setter for jms template. - * - * @param jmsTemplate a {@link JmsOperations} instance - */ - public void setJmsTemplate(JmsOperations jmsTemplate) { - this.jmsTemplate = jmsTemplate; - } - - /** - * Set the expected type of incoming message payloads. Set this to - * {@link Message} to receive the raw underlying message. - * - * @param itemType the java class of the items to be delivered. Typically - * the same as the class parameter - * - * @throws IllegalStateException if the message payload is of the wrong - * type. - */ - public void setItemType(Class itemType) { - this.itemType = itemType; - } +public class JmsItemReader extends MessageTypeAccessor implements ItemReader { @SuppressWarnings("unchecked") public T read() { @@ -112,72 +48,4 @@ public class JmsItemReader implements ItemReader, ItemRecoverer, Item return (T) result; } - /** - * Send the message back to the provider using the specified error - * destination property of this reader. If the recovery is successful the - * item itself is returned, otherwise null. - * - * @see org.springframework.batch.item.ItemRecoverer#recover(Object, - * Throwable) - */ - public T recover(T item, Throwable cause) { - try { - if (errorDestination != null) { - jmsTemplate.convertAndSend(errorDestination, item); - } - else if (errorDestinationName != null) { - jmsTemplate.convertAndSend(errorDestinationName, item); - } - else { - // do nothing - it doesn't make sense to send the message back - // to the destination it came from - return null; - } - return item; - } - catch (JmsException e) { - logger.error("Could not recover because of JmsException.", e); - throw e; - } - } - - /** - * If the message is a {@link Message} then returns the JMS message ID. - * Otherwise just delegate to parent class. - * - * @see org.springframework.batch.item.ItemKeyGenerator#getKey(java.lang.Object) - * - * @throws UnexpectedInputException if the JMS id cannot be determined from - * a JMS Message - */ - public Object getKey(Object item) { - if (itemType != null && itemType.isAssignableFrom(Message.class)) { - try { - return ((Message) item).getJMSMessageID(); - } - catch (JMSException e) { - throw new UnexpectedInputException("Could not extract message ID", e); - } - } - return item; - } - - /** - * If the item is a message, check the JMS re-delivered flag, otherwise - * return false to be on the safe side. - * - * @see org.springframework.batch.item.NewItemIdentifier#isNew(java.lang.Object) - */ - public boolean isNew(Object item) { - if (itemType != null && itemType.isAssignableFrom(Message.class)) { - try { - return !((Message) item).getJMSRedelivered(); - } - catch (JMSException e) { - throw new UnexpectedInputException("Could not extract message ID", e); - } - } - return false; - } - } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemWriter.java new file mode 100644 index 000000000..056ec39ff --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemWriter.java @@ -0,0 +1,64 @@ +/* + * 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.item.jms; + +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.batch.item.ItemWriter; +import org.springframework.jms.core.JmsOperations; +import org.springframework.jms.core.JmsTemplate; + +/** + * An {@link ItemWriter} for JMS using a {@link JmsTemplate}. The template + * should have a default destination, which will be used to send items in + * {@link #write(List)}.

+ * + * The implementation is thread safe after its properties are set (normal + * singleton behaviour). + * + * @author Dave Syer + * + */ +public class JmsItemWriter implements ItemWriter { + + protected Log logger = LogFactory.getLog(getClass()); + + private JmsOperations jmsTemplate; + + /** + * Setter for jms template. + * + * @param jmsTemplate a {@link JmsOperations} instance + */ + public void setJmsTemplate(JmsOperations jmsTemplate) { + this.jmsTemplate = jmsTemplate; + } + + /** + * Send the items one-by-one to the default destination of the jms template. + * + * @see org.springframework.batch.item.ItemWriter#write(java.util.List) + */ + public void write(List items) throws Exception { + for (T item : items) { + jmsTemplate.convertAndSend(item); + } + } + +} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGenerator.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGenerator.java new file mode 100644 index 000000000..dff7e575b --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGenerator.java @@ -0,0 +1,61 @@ +/* + * 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.item.jms; + +import javax.jms.JMSException; +import javax.jms.Message; + +import org.springframework.batch.item.UnexpectedInputException; +import org.springframework.batch.retry.interceptor.MethodArgumentsKeyGenerator; + +/** + * A {@link MethodArgumentsKeyGenerator} for JMS + * + * @author Dave Syer + * + */ +public class JmsMethodArgumentsKeyGenerator implements MethodArgumentsKeyGenerator { + + /** + * If the message is a {@link Message} then returns the JMS message ID. + * Otherwise just return the first argument. + * + * @see org.springframework.batch.retry.interceptor.MethodArgumentsKeyGenerator#getKey(Object[]) + * + * @throws UnexpectedInputException if the JMS id cannot be determined from + * a JMS Message + * @throws IllegalArgumentException if the arguments are empty + */ + public Object getKey(Object[] items) { + for (Object item : items) { + if (item instanceof Message) { + try { + return ((Message) item).getJMSMessageID(); + } + catch (JMSException e) { + throw new UnexpectedInputException("Could not extract message ID", e); + } + } + } + if (items.length == 0) { + throw new IllegalArgumentException( + "Method parameters are empty. The key generator cannot determine a unique key."); + } + return items[0]; + } + +} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodInvocationRecoverer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodInvocationRecoverer.java new file mode 100644 index 000000000..836259757 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsMethodInvocationRecoverer.java @@ -0,0 +1,63 @@ +/* + * 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.item.jms; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.batch.retry.interceptor.MethodInvocationRecoverer; +import org.springframework.jms.JmsException; +import org.springframework.jms.core.JmsOperations; + +/** + * @author Dave Syer + * + */ +public class JmsMethodInvocationRecoverer implements MethodInvocationRecoverer { + + protected Log logger = LogFactory.getLog(getClass()); + + private JmsOperations jmsTemplate; + + /** + * Setter for jms template. + * + * @param jmsTemplate a {@link JmsOperations} instance + */ + public void setJmsTemplate(JmsOperations jmsTemplate) { + this.jmsTemplate = jmsTemplate; + } + + /** + * Send one message per item in the arguments list using the default destination of + * the jms template. If the recovery is successful null is returned. + * + * @see org.springframework.batch.retry.interceptor.MethodInvocationRecoverer#recover(Object[], + * Throwable) + */ + public T recover(Object[] items, Throwable cause) { + try { + for (Object item : items) { + jmsTemplate.convertAndSend(item); + } + return null; + } + catch (JmsException e) { + logger.error("Could not recover because of JmsException.", e); + throw e; + } + } + +} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifier.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifier.java new file mode 100644 index 000000000..eb37701f4 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifier.java @@ -0,0 +1,55 @@ +/* + * 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.item.jms; + +import javax.jms.JMSException; +import javax.jms.Message; + +import org.springframework.batch.item.UnexpectedInputException; +import org.springframework.batch.retry.interceptor.NewMethodArgumentsIdentifier; + +/** + * A {@link NewMethodArgumentsIdentifier} for JMS that looks for a message in + * the arguments and checks its delivery status. + * + * @author Dave Syer + * + */ +public class JmsNewMethodArgumentsIdentifier implements NewMethodArgumentsIdentifier { + + /** + * If any of the arguments is a message, check the JMS re-delivered flag and + * return it, otherwise return false to be on the safe side. + * + * @see org.springframework.batch.retry.interceptor.NewMethodArgumentsIdentifier#isNew(java.lang.Object[]) + */ + public boolean isNew(Object[] args) { + + for (Object item : args) { + if (item instanceof Message) { + try { + return !((Message) item).getJMSRedelivered(); + } + catch (JMSException e) { + throw new UnexpectedInputException("Could not extract message ID", e); + } + } + } + return false; + } + +} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/MessageTypeAccessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/MessageTypeAccessor.java new file mode 100644 index 000000000..c78a90c2c --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/MessageTypeAccessor.java @@ -0,0 +1,68 @@ +/* + * 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.item.jms; + +import javax.jms.Message; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.jms.core.JmsOperations; + +/** + * Base class for JMS concerns. + * + * @author Dave Syer + * + */ +class MessageTypeAccessor { + + protected Log logger = LogFactory.getLog(getClass()); + + protected Class itemType; + + protected JmsOperations jmsTemplate; + + /** + * Setter for jms template. + * + * @param jmsTemplate a {@link JmsOperations} instance + */ + public void setJmsTemplate(JmsOperations jmsTemplate) { + this.jmsTemplate = jmsTemplate; + } + + /** + * Set the expected type of incoming message payloads. Set this to + * {@link Message} to receive the raw underlying message. + * + * @param itemType the java class of the items to be delivered. Typically + * the same as the class parameter + * + * @throws IllegalStateException if the message payload is of the wrong + * type. + */ + public void setItemType(Class itemType) { + this.itemType = itemType; + } + + public boolean isMessageType() { + return itemType != null && itemType.isAssignableFrom(Message.class); + } + + + +} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemKeyGenerator.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/MethodArgumentsKeyGenerator.java similarity index 84% rename from spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemKeyGenerator.java rename to spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/MethodArgumentsKeyGenerator.java index 2dc5badc5..801a8e849 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemKeyGenerator.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/MethodArgumentsKeyGenerator.java @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.item; +package org.springframework.batch.retry.interceptor; + +import org.springframework.batch.item.ItemReader; /** * Extension of the {@link ItemReader} interface that allows items to be @@ -22,7 +24,7 @@ package org.springframework.batch.item; * @author Dave Syer * */ -public interface ItemKeyGenerator { +public interface MethodArgumentsKeyGenerator { /** * Get a unique identifier for the item that can be used to cache it between @@ -31,6 +33,6 @@ public interface ItemKeyGenerator { * @param item the current item. * @return a unique identifier. */ - Object getKey(Object item); + Object getKey(Object[] item); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemRecoverer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/MethodInvocationRecoverer.java similarity index 83% rename from spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemRecoverer.java rename to spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/MethodInvocationRecoverer.java index f767cc6bc..cbc16ca44 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemRecoverer.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/MethodInvocationRecoverer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.batch.item; +package org.springframework.batch.retry.interceptor; /** @@ -22,7 +22,7 @@ package org.springframework.batch.item; * * @author Dave Syer */ -public interface ItemRecoverer { +public interface MethodInvocationRecoverer { /** * Recover gracefully from an error. Clients can call this if processing of @@ -30,11 +30,11 @@ public interface ItemRecoverer { * to decide whether to try more corrective action or perhaps throw an * exception. * - * @param data - * the item that failed. + * @param args + * the arguments for the method invocation that failed. * @param cause * the cause of the failure that led to this recovery. * @return the value to be returned to the caller */ - T recover(S data, Throwable cause); + T recover(Object[] args, Throwable cause); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/NewItemIdentifier.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/NewMethodArgumentsIdentifier.java similarity index 62% rename from spring-batch-infrastructure/src/main/java/org/springframework/batch/item/NewItemIdentifier.java rename to spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/NewMethodArgumentsIdentifier.java index 9069dc81a..86548dcfd 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/NewItemIdentifier.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/NewMethodArgumentsIdentifier.java @@ -14,24 +14,24 @@ * limitations under the License. */ -package org.springframework.batch.item; +package org.springframework.batch.retry.interceptor; /** - * Strategy interface to distinguish a new item from one that has been processed - * before and one that has not, e.g. by examining a message flag. + * Strategy interface to distinguish new arguments from ones that have been + * processed before, e.g. by examining a message flag. * * @author Dave Syer * */ -public interface NewItemIdentifier { +public interface NewMethodArgumentsIdentifier { /** - * Inspect the item and determine if it has never been processed before. - * The safest choice when the answer is indeterminate is 'false'. + * Inspect the arguments and determine if they have never been processed + * before. The safest choice when the answer is indeterminate is 'false'. * - * @param item the current item. + * @param args the current method arguments. * @return true if the item is known to have never been processed before. */ - boolean isNew(Object item); + boolean isNew(Object[] args); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptor.java index c8e25404e..fdf1fb417 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptor.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptor.java @@ -20,9 +20,6 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.batch.item.ItemKeyGenerator; -import org.springframework.batch.item.ItemRecoverer; -import org.springframework.batch.item.NewItemIdentifier; import org.springframework.batch.retry.ExhaustedRetryException; import org.springframework.batch.retry.RecoveryCallback; import org.springframework.batch.retry.RetryCallback; @@ -40,8 +37,8 @@ import org.springframework.util.ObjectUtils; * a method on a service if it fails. The argument to the service method is * treated as an item to be remembered in case the call fails. So the retry * operation is stateful, and the item that failed is tracked by its unique key - * (via {@link ItemKeyGenerator}) until the retry is exhausted, at which point - * the {@link ItemRecoverer} is called.
+ * (via {@link MethodArgumentsKeyGenerator}) until the retry is exhausted, at which point + * the {@link MethodInvocationRecoverer} is called.
* * The main use case for this is where the service is transactional, via a * transaction interceptor on the interceptor chain. In this case the retry (and @@ -57,11 +54,11 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor { private transient Log logger = LogFactory.getLog(getClass()); - private ItemKeyGenerator keyGenerator; + private MethodArgumentsKeyGenerator keyGenerator; - private ItemRecoverer recoverer; + private MethodInvocationRecoverer recoverer; - private NewItemIdentifier newItemIdentifier; + private NewMethodArgumentsIdentifier newMethodArgumentsIdentifier; private final RetryTemplate retryTemplate = new RetryTemplate(); @@ -74,7 +71,7 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor { } /** - * Public setter for the {@link ItemRecoverer} to use if the retry is + * Public setter for the {@link MethodInvocationRecoverer} to use if the retry is * exhausted. The recoverer should be able to return an object of the same * type as the target object because its return value will be used to return * to the caller in the case of a recovery.
@@ -82,13 +79,13 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor { * If no recoverer is set then an exhausted retry will result in an * {@link ExhaustedRetryException}. * - * @param recoverer the {@link ItemRecoverer} to set + * @param recoverer the {@link MethodInvocationRecoverer} to set */ - public void setRecoverer(ItemRecoverer recoverer) { + public void setRecoverer(MethodInvocationRecoverer recoverer) { this.recoverer = recoverer; } - public void setKeyGenerator(ItemKeyGenerator keyGenerator) { + public void setKeyGenerator(MethodArgumentsKeyGenerator keyGenerator) { this.keyGenerator = keyGenerator; } @@ -103,29 +100,29 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor { } /** - * Public setter for the {@link NewItemIdentifier}. Only set this if the + * Public setter for the {@link NewMethodArgumentsIdentifier}. Only set this if the * arguments to the intercepted method can be inspected to find out if they * have never been processed before. - * @param newItemIdentifier the {@link NewItemIdentifier} to set + * @param newMethodArgumentsIdentifier the {@link NewMethodArgumentsIdentifier} to set */ - public void setNewItemIdentifier(NewItemIdentifier newItemIdentifier) { - this.newItemIdentifier = newItemIdentifier; + public void setNewItemIdentifier(NewMethodArgumentsIdentifier newMethodArgumentsIdentifier) { + this.newMethodArgumentsIdentifier = newMethodArgumentsIdentifier; } /** * Wrap the method invocation in a stateful retry with the policy and other * helpers provided. If there is a failure the exception will generally be * re-thrown. The only time it is not re-thrown is when retry is exhausted - * and the recovery path is taken (though the {@link ItemRecoverer} provided + * and the recovery path is taken (though the {@link MethodInvocationRecoverer} provided * if there is one). In that case the value returned from the method * invocation will be the value returned by the recoverer (so the return * type for that should be the same as the intercepted method). * * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) - * @see ItemRecoverer#recover(Object, Throwable) + * @see MethodInvocationRecoverer#recover(Object[], Throwable) * * @throws ExhaustedRetryException if the retry is exhausted and no - * {@link ItemRecoverer} is provided. + * {@link MethodInvocationRecoverer} is provided. */ public Object invoke(final MethodInvocation invocation) throws Throwable { @@ -141,7 +138,7 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor { } final Object item = arg; - RetryState retryState = new RetryState(keyGenerator != null ? keyGenerator.getKey(item) : item, newItemIdentifier != null ? newItemIdentifier.isNew(item) : false ); + RetryState retryState = new RetryState(keyGenerator != null ? keyGenerator.getKey(args) : item, newMethodArgumentsIdentifier != null ? newMethodArgumentsIdentifier.isNew(args) : false ); Object result = retryTemplate.execute(new MethodInvocationRetryCallback(invocation), new ItemRecovererCallback(args, recoverer), retryState); @@ -192,12 +189,12 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor { private final Object[] args; - private final ItemRecoverer recoverer; + private final MethodInvocationRecoverer recoverer; /** * @param args the item that failed. */ - private ItemRecovererCallback(Object[] args, ItemRecoverer recoverer) { + private ItemRecovererCallback(Object[] args, MethodInvocationRecoverer recoverer) { this.args = args; this.recoverer = recoverer; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemRecoveryHandlerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemRecoveryHandlerTests.java index 1a6e6fb99..b45ae81ca 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemRecoveryHandlerTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemRecoveryHandlerTests.java @@ -16,19 +16,21 @@ package org.springframework.batch.item; +import org.springframework.batch.retry.interceptor.MethodInvocationRecoverer; + import junit.framework.TestCase; public class ItemRecoveryHandlerTests extends TestCase { - ItemRecoverer recoverer = new ItemRecoverer() { - public String recover(String data, Throwable cause) { + MethodInvocationRecoverer recoverer = new MethodInvocationRecoverer() { + public String recover(Object[] data, Throwable cause) { return null; } }; public void testRecover() throws Exception { try { - recoverer.recover("foo", null); + recoverer.recover(new Object[]{"foo"}, null); } catch (Exception e) { fail("Unexpected Exception"); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java index c2f0d9b50..4cbdb3e6a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java @@ -23,7 +23,6 @@ import static org.junit.Assert.fail; import java.util.Date; import javax.jms.Message; -import javax.jms.Queue; import org.easymock.EasyMock; import org.junit.Test; @@ -106,84 +105,4 @@ public class JmsItemReaderTests { EasyMock.verify(jmsTemplate); } - @Test - public void testRecoverWithNoDestination() throws Exception { - JmsOperations jmsTemplate = EasyMock.createMock(JmsOperations.class); - EasyMock.replay(jmsTemplate); - - itemReader.setJmsTemplate(jmsTemplate); - itemReader.setItemType(String.class); - itemReader.recover("foo", null); - - EasyMock.verify(jmsTemplate); - } - - @Test - public void testErrorQueueWithDestinationName() throws Exception { - JmsOperations jmsTemplate = EasyMock.createMock(JmsOperations.class); - jmsTemplate.convertAndSend("queue", "foo"); - EasyMock.expectLastCall(); - EasyMock.replay(jmsTemplate); - - itemReader.setJmsTemplate(jmsTemplate); - itemReader.setItemType(String.class); - itemReader.setErrorDestinationName("queue"); - itemReader.recover("foo", null); - - EasyMock.verify(jmsTemplate); - } - - @Test - public void testErrorQueueWithDestination() throws Exception { - JmsOperations jmsTemplate = EasyMock.createMock(JmsOperations.class); - Queue queue = EasyMock.createMock(Queue.class); - jmsTemplate.convertAndSend(queue, "foo"); - EasyMock.expectLastCall(); - EasyMock.replay(jmsTemplate, queue); - - itemReader.setJmsTemplate(jmsTemplate); - itemReader.setItemType(String.class); - itemReader.setErrorDestination(queue); - itemReader.recover("foo", null); - - EasyMock.verify(jmsTemplate, queue); - } - - @Test - public void testGetKeyFromMessage() throws Exception { - Message message = EasyMock.createMock(Message.class); - EasyMock.expect(message.getJMSMessageID()).andReturn("foo"); - EasyMock.replay(message); - - JmsItemReader itemReader = new JmsItemReader(); - itemReader.setItemType(Message.class); - assertEquals("foo", itemReader.getKey(message)); - - EasyMock.verify(message); - } - - @Test - public void testGetKeyFromNonMessage() throws Exception { - itemReader.setItemType(String.class); - assertEquals("foo", itemReader.getKey("foo")); - } - - @Test - public void testIsNewForMessage() throws Exception { - Message message = EasyMock.createMock(Message.class); - EasyMock.expect(message.getJMSRedelivered()).andReturn(true); - EasyMock.replay(message); - - JmsItemReader itemReader = new JmsItemReader(); - itemReader.setItemType(Message.class); - assertEquals(false, itemReader.isNew(message)); - - EasyMock.verify(message); - } - - @Test - public void testIsNewForNonMessage() throws Exception { - itemReader.setItemType(String.class); - assertEquals(false, itemReader.isNew("foo")); - } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java new file mode 100644 index 000000000..ab6ca6708 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java @@ -0,0 +1,52 @@ +/* + * 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.item.jms; + +import static org.junit.Assert.assertEquals; + +import javax.jms.Message; + +import org.easymock.EasyMock; +import org.junit.Test; + + +/** + * @author Dave Syer + * + */ +public class JmsMethodArgumentsKeyGeneratorTests { + + private JmsMethodArgumentsKeyGenerator methodArgumentsKeyGenerator = new JmsMethodArgumentsKeyGenerator(); + + @Test + public void testGetKeyFromMessage() throws Exception { + Message message = EasyMock.createMock(Message.class); + EasyMock.expect(message.getJMSMessageID()).andReturn("foo"); + EasyMock.replay(message); + + JmsItemReader itemReader = new JmsItemReader(); + itemReader.setItemType(Message.class); + assertEquals("foo", methodArgumentsKeyGenerator.getKey(new Object[]{message})); + + EasyMock.verify(message); + } + + @Test + public void testGetKeyFromNonMessage() throws Exception { + assertEquals("foo", methodArgumentsKeyGenerator.getKey(new Object[]{"foo"})); + } + +} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java new file mode 100644 index 000000000..56c45a9aa --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java @@ -0,0 +1,42 @@ +/* + * 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.item.jms; + +import org.easymock.EasyMock; +import org.junit.Test; +import org.springframework.jms.core.JmsOperations; + +/** + * @author Dave Syer + * + */ +public class JmsMethodInvocationRecovererTests { + + private JmsMethodInvocationRecoverer itemReader = new JmsMethodInvocationRecoverer(); + + @Test + public void testRecoverWithNoDestination() throws Exception { + JmsOperations jmsTemplate = EasyMock.createMock(JmsOperations.class); + jmsTemplate.convertAndSend("foo"); + EasyMock.replay(jmsTemplate); + + itemReader.setJmsTemplate(jmsTemplate); + itemReader.recover(new Object[] { "foo" }, null); + + EasyMock.verify(jmsTemplate); + } + +} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java new file mode 100644 index 000000000..f7c2dbb1e --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java @@ -0,0 +1,48 @@ +/* + * 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.item.jms; + +import static org.junit.Assert.assertEquals; + +import javax.jms.Message; + +import org.easymock.EasyMock; +import org.junit.Test; + + +/** + * @author Dave Syer + * + */ +public class JmsNewMethodArgumentsIdentifierTests { + + private JmsNewMethodArgumentsIdentifier newMethodArgumentsIdentifier = new JmsNewMethodArgumentsIdentifier(); + + @Test + public void testIsNewForMessage() throws Exception { + Message message = EasyMock.createMock(Message.class); + EasyMock.expect(message.getJMSRedelivered()).andReturn(true); + EasyMock.replay(message); + assertEquals(false, newMethodArgumentsIdentifier.isNew(new Object[]{message})); + + EasyMock.verify(message); + } + + @Test + public void testIsNewForNonMessage() throws Exception { + assertEquals(false, newMethodArgumentsIdentifier.isNew(new Object[]{"foo"})); + } +} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptorTests.java index b2310ebbe..a42ba9729 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/interceptor/StatefulRetryOperationsInterceptorTests.java @@ -27,7 +27,6 @@ import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.target.SingletonTargetSource; -import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.retry.ExhaustedRetryException; import org.springframework.batch.retry.policy.AlwaysRetryPolicy; import org.springframework.batch.retry.policy.NeverRetryPolicy; @@ -170,7 +169,7 @@ public class StatefulRetryOperationsInterceptorTests extends TestCase { assertTrue("Wrong message: " + message, message.startsWith("Not enough calls")); } assertEquals(1, count); - interceptor.setRecoverer(new ItemRecoverer() { + interceptor.setRecoverer(new MethodInvocationRecoverer() { public Object recover(Object[] data, Throwable cause) { count++; return null; @@ -192,7 +191,7 @@ public class StatefulRetryOperationsInterceptorTests extends TestCase { assertTrue("Wrong message: " + message, message.startsWith("Not enough calls")); } assertEquals(1, count); - interceptor.setRecoverer(new ItemRecoverer, Object[]>() { + interceptor.setRecoverer(new MethodInvocationRecoverer>() { public Collection recover(Object[] data, Throwable cause) { count++; return Collections.singleton((String)data[0]); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/retry/PollableSourceRetryTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/retry/PollableSourceRetryTests.java index 8f98974c7..ffe06221b 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/retry/PollableSourceRetryTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/retry/PollableSourceRetryTests.java @@ -15,10 +15,10 @@ import org.junit.Test; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.NameMatchMethodPointcut; -import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.support.ListItemReader; +import org.springframework.batch.retry.interceptor.MethodArgumentsKeyGenerator; +import org.springframework.batch.retry.interceptor.MethodInvocationRecoverer; import org.springframework.batch.retry.interceptor.StatefulRetryOperationsInterceptor; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; @@ -51,16 +51,13 @@ public class PollableSourceRetryTests { processed.add(str); } - ItemKeyGenerator itemKeyGenerator = new ItemKeyGenerator() { + MethodArgumentsKeyGenerator methodArgumentsKeyGenerator = new MethodArgumentsKeyGenerator() { @SuppressWarnings("unchecked") - public Object getKey(Object item) { + public Object getKey(Object[] item) { if (item == null) { return "NULL"; } - if (item.getClass().isArray()) { - item = ((Object[]) item)[0]; - } - return ((Message) item).getPayload(); + return ((Message) item[0]).getPayload(); } }; @@ -266,7 +263,7 @@ public class PollableSourceRetryTests { MessageTarget target = getChannel(handler); // this was the old dispatch advice chain target = (MessageTarget) getProxy(target, MessageTarget.class, - new Advice[] { getRetryOperationsInterceptor(itemKeyGenerator) }, "send"); + new Advice[] { getRetryOperationsInterceptor(methodArgumentsKeyGenerator) }, "send"); PollingDispatcher trigger = getPollingDispatcher(source, target, transactionManager, 1); TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger); @@ -309,7 +306,7 @@ public class PollableSourceRetryTests { MessageTarget target = getChannel(handler); // this was the old dispatch advice chain target = (MessageTarget) getProxy(target, MessageTarget.class, - new Advice[] { getRetryOperationsInterceptor(itemKeyGenerator) }, "send"); + new Advice[] { getRetryOperationsInterceptor(methodArgumentsKeyGenerator) }, "send"); PollingDispatcher trigger = getPollingDispatcher(source, target, transactionManager, 3); TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger); @@ -398,12 +395,12 @@ public class PollableSourceRetryTests { } /** - * @param itemKeyGenerator + * @param methodArgumentsKeyGenerator * @return */ - private StatefulRetryOperationsInterceptor getRetryOperationsInterceptor(ItemKeyGenerator itemKeyGenerator) { + private StatefulRetryOperationsInterceptor getRetryOperationsInterceptor(MethodArgumentsKeyGenerator methodArgumentsKeyGenerator) { StatefulRetryOperationsInterceptor advice = new StatefulRetryOperationsInterceptor(); - advice.setRecoverer(new ItemRecoverer() { + advice.setRecoverer(new MethodInvocationRecoverer() { @SuppressWarnings("unchecked") public Boolean recover(Object[] data, Throwable cause) { if (data == null) { @@ -415,7 +412,7 @@ public class PollableSourceRetryTests { return true; } }); - advice.setKeyGenerator(itemKeyGenerator); + advice.setKeyGenerator(methodArgumentsKeyGenerator); return advice; }