INT-4257-2: Document ErrorMessagePublisher

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

* Remove deprecated `EnhancedErrorMessage`
* Document `ErrorMessagePublisher` and `ErrorMessageStrategy`
* Fix Reactor version to `3.1` in Doc
* Fix sample about Reactive Streams in the `router.adoc`
This commit is contained in:
Artem Bilan
2017-04-19 19:11:58 -04:00
committed by Gary Russell
parent f7f7bdd067
commit 71b93987d7
7 changed files with 22 additions and 84 deletions

View File

@@ -1,64 +0,0 @@
/*
* Copyright 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.
* 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.integration.message;
import java.util.Map;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.ErrorMessage;
/**
* An error message that is enhanced with a message that is available at the
* stack frame where the error message is generated. Typically this will be a
* message that begins a subflow, whereas if the {@link Throwable} payload is
* a {@link org.springframework.messaging.MessagingException}, its failedMessage
* property will contain the message at the point where the exception occurred.
*
* @author Gary Russell
*
* @since 4.3.10
*
* @deprecated since 4.3.10 in favor of direct {@link ErrorMessage} usage since 5.0.
*/
@Deprecated
public class EnhancedErrorMessage extends ErrorMessage {
private static final long serialVersionUID = 5857673472822628678L;
private final Message<?> originalMessage;
public EnhancedErrorMessage(Message<?> originalMessage, Throwable payload) {
super(payload);
this.originalMessage = originalMessage;
}
public EnhancedErrorMessage(Message<?> originalMessage, Throwable payload, MessageHeaders headers) {
super(payload, headers);
this.originalMessage = originalMessage;
}
public EnhancedErrorMessage(Message<?> originalMessage, Throwable payload, Map<String, Object> headers) {
super(payload, headers);
this.originalMessage = originalMessage;
}
public Message<?> getOriginalMessage() {
return this.originalMessage;
}
}

View File

@@ -36,12 +36,9 @@ import org.springframework.messaging.support.ErrorMessage;
public class DefaultErrorMessageStrategy implements ErrorMessageStrategy {
@Override
@SuppressWarnings("deprecation")
public ErrorMessage buildErrorMessage(Throwable throwable, AttributeAccessor attributes) {
Object inputMessage = attributes.getAttribute(ErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEY);
return inputMessage instanceof Message
? new org.springframework.integration.message.EnhancedErrorMessage((Message<?>) inputMessage, throwable)
: new ErrorMessage(throwable);
return new ErrorMessage(throwable, inputMessage instanceof Message ? (Message<?>) inputMessage : null);
}
}

View File

@@ -35,6 +35,7 @@ import org.springframework.messaging.support.ErrorMessage;
*
* @since 4.3.10
*/
@FunctionalInterface
public interface ErrorMessageStrategy {
/**

View File

@@ -1034,24 +1034,21 @@ public class AdvisedMessageHandlerTests {
}
assertEquals(expected, counter.get());
}
@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, instanceOf(ErrorMessage.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"));
assertThat(((ErrorMessage) error).getOriginalMessage().getPayload(), equalTo("foo"));
}
private interface Bar {

View File

@@ -195,6 +195,15 @@ To enable global error handling, simply register a handler on that channel.
For example, you can configure Spring Integration's `ErrorMessageExceptionTypeRouter` as the handler of an endpoint that is subscribed to the 'errorChannel'.
That router can then spread the error messages across multiple channels based on `Exception` type.
Starting with _version 4.3.10_, the `ErrorMessagePublisher` and the `ErrorMessageStrategy` are provided.
They can be used as general mechanism for publishing `ErrorMessage` s and can be called or extended in any error handling scenarios.
The `ErrorMessageSendingRecoverer` extends this class as a `RecoveryCallback` implementation that can be used with retry, such as the
<<retry-advice, RequestHandlerRetryAdvice>>.
The `ErrorMessageStrategy` is used to build an `ErrorMessage` based on the provided exception and an `AttributeAccessor` context.
It can be injected to any `MessageProducerSupport` and `MessagingGatewaySupport` - and the `requestMessage` is stored under `ErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEY` in the `AttributeAccessor` context.
The `ErrorMessageStrategy` can use that `requestMessage` as the `originalMessage` property of the `ErrorMessage` it creates.
The `DefaultErrorMessageStrategy` does exactly that.
[[global-properties]]
=== Global Properties

View File

@@ -1380,18 +1380,12 @@ public PollableChannel resultsChannel() {
public RoutingSlipRouteStrategy routeStrategy() {
return (requestMessage, reply) -> requestMessage.getPayload() instanceof String
? new FixedSubscriberChannel(m ->
Streams.defer((String) m.getPayload())
.env(this.reactorEnv)
.get()
Mono.just((String) m.getPayload())
.map(String::toUpperCase)
.consume(v -> messagingTemplate().convertAndSend(resultsChannel(), v))
.flush())
.subscribe(v -> messagingTemplate().convertAndSend(resultsChannel(), v)))
: new FixedSubscriberChannel(m ->
Streams.defer((Integer) m.getPayload())
.env(this.reactorEnv)
.get()
Mono.just((Integer) m.getPayload())
.map(v -> v * 2)
.consume(v -> messagingTemplate().convertAndSend(resultsChannel(), v))
.flush());
.subscribe(v -> messagingTemplate().convertAndSend(resultsChannel(), v)));
}
----

View File

@@ -37,11 +37,15 @@ See <<http-outbound>> for more information.
Now that we use the new `InvocableHandlerMethod` -based infrastructure for service method invocations, we can perform `contentType` conversion from payload to target method argument.
See <<content-type-conversion>> for more information.
==== ErrorMessagePublisher and ErrorMessageStrategy
The `ErrorMessagePublisher` abd the `ErrorMessageStrategy` are provided for creating `ErrorMessage` instances.
See <<namespace-errorhandler>> for more information.
[[x5.0-general]]
=== General Changes
Spring Integration is now fully based on Spring Framework `5.0` and Project Reactor `3.0`.
Spring Integration is now fully based on Spring Framework `5.0` and Project Reactor `3.1`.
Previous Project Reactor versions are no longer supported.
==== Core Changes