INT-4257: Introduce ErrorMessagePublisher

JIRA: https://jira.spring.io/browse/INT-4257

To make a target `ErrorMessage` customizable introduce
`ErrorMessagePublishingRecoveryCallback` and
`ErrorMessageStrategy` to inject

**Cherry-pick to 4.3.x**

Fix `ErrorMessagePublishingRecoveryCallback` generic type for
`RequestHandlerRetryAdvice` compatibility

Polishing

- Support publishing when no retry context is available
- Use a constant for the message context key

Add EnhancedErrorMessage

- contains input message at time of error message generation
- make the default RecovererErrorMessageStrategy public and extensible

Fix `RetryAdviceParserTests` for new `RecoveryCallback` architecture

Rename to `ErrorMessagePublisher`
Decouple ErrorMessagePublisher from Retry

Refactoring for better purpose reflection and JavaDocs

Use `ErrorMessageStrategy` in message producers.

Add JavaDocs to the `DefaultErrorMessageStrategy`

Deprecate EnhancedErrorMessage

Minor Polish for Subclass Use

- make setters final
- allow subclasses to supply the AttributeAccessor

Fix Tests
This commit is contained in:
Artem Bilan
2017-03-10 16:06:56 -05:00
committed by Gary Russell
parent 5224779a04
commit 28058884f4
12 changed files with 581 additions and 54 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2017 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.
@@ -37,6 +37,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Gary Russell
* @author Artem Bilan
*
* @since 4.0
*
*/
@@ -99,7 +101,7 @@ public class RetryAdviceParserTests {
assertNull(TestUtils.getPropertyValue(a1, "recoveryCallback"));
assertNotNull(TestUtils.getPropertyValue(a7, "recoveryCallback"));
assertSame(this.foo, TestUtils.getPropertyValue(a7, "recoveryCallback.messagingTemplate.defaultDestination"));
assertSame(this.foo, TestUtils.getPropertyValue(a7, "recoveryCallback.channel"));
assertEquals(4567L, TestUtils.getPropertyValue(a7, "recoveryCallback.messagingTemplate.sendTimeout"));
assertSame(this.a1, TestUtils.getPropertyValue(this.handler1, "adviceChain", List.class).get(0));

View File

@@ -16,9 +16,11 @@
package org.springframework.integration.endpoint;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -102,7 +104,7 @@ public class MessageProducerSupportTests {
mps.start();
Message<?> message = new GenericMessage<String>("hello");
mps.sendMessage(message);
assertEquals(ErrorMessage.class, errorService.lastMessage.getClass());
assertThat(errorService.lastMessage, instanceOf(ErrorMessage.class));
ErrorMessage errorMessage = (ErrorMessage) errorService.lastMessage;
assertEquals(MessageDeliveryException.class, errorMessage.getPayload().getClass());
MessageDeliveryException exception = (MessageDeliveryException) errorMessage.getPayload();

View File

@@ -16,6 +16,8 @@
package org.springframework.integration.handler.advice;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -1035,6 +1037,23 @@ public class AdvisedMessageHandlerTests {
}
@Test
@SuppressWarnings("deprecation")
public void enhancedRecoverer() throws Exception {
QueueChannel channel = new QueueChannel();
ErrorMessageSendingRecoverer recoverer = new ErrorMessageSendingRecoverer(channel);
recoverer.publish(new GenericMessage<>("foo"), new GenericMessage<>("bar"), new RuntimeException("baz"));
Message<?> error = channel.receive(0);
assertThat(error, instanceOf(org.springframework.integration.message.EnhancedErrorMessage.class));
assertThat(error.getPayload(), instanceOf(MessagingException.class));
MessagingException payload = (MessagingException) error.getPayload();
assertThat(payload.getCause(), instanceOf(RuntimeException.class));
assertThat(payload.getCause().getMessage(), equalTo("baz"));
assertThat(payload.getFailedMessage().getPayload(), equalTo("bar"));
assertThat(((org.springframework.integration.message.EnhancedErrorMessage) error).getOriginalMessage()
.getPayload(), equalTo("foo"));
}
private interface Bar {
Object handleRequestMessage(Message<?> message) throws Throwable;