GH-2873: Preserve mapping order in the router (#2877)

* GH-2873: Preserve mapping order in the router

Fixes https://github.com/spring-projects/spring-integration/issues/2873

Sometime it is important to map to most specific exception instead of
its super class.

* Use `LinkedHashMap` for mapping keys in the
`ErrorMessageExceptionTypeRouter`, as well as in its
`AbstractMappingMessageRouter` superclass.
Since we don't do that internal map modification, there is no reason to
worry about concurrent access: we just replace an internal instance
atomically with a new `LinkedHashMap` every time we modify a mapping
for router

**Cherry-pick to 5.1.x**

* * Fix `RouterSpec.RouterMappingProvider` to `LinkedHashMap` as well

* * Fix `RouterTests` for proper mapping order
* Polishing for `AbstractMappingMessageRouter` hierarchy, so we don't
use `protected channelMappings` field access any more
This commit is contained in:
Artem Bilan
2019-04-01 15:29:39 -04:00
committed by Gary Russell
parent 3fc278688c
commit 23a73fab87
7 changed files with 51 additions and 55 deletions

View File

@@ -743,8 +743,8 @@ public class RouterTests {
public IntegrationFlow exceptionTypeRouteFlow() {
return f -> f
.routeByException(r -> r
.channelMapping(IllegalArgumentException.class, "illegalArgumentChannel")
.channelMapping(RuntimeException.class, "runtimeExceptionChannel")
.channelMapping(IllegalArgumentException.class, "illegalArgumentChannel")
.subFlowMapping(MessageHandlingException.class, sf ->
sf.channel("messageHandlingExceptionChannel"))
.defaultOutputChannel("exceptionRouterDefaultChannel"));

View File

@@ -79,8 +79,8 @@ public class ErrorMessageExceptionTypeRouterTests {
ErrorMessageExceptionTypeRouter router = new ErrorMessageExceptionTypeRouter();
router.setBeanFactory(this.context);
router.setApplicationContext(this.context);
router.setChannelMapping(IllegalArgumentException.class.getName(), "illegalArgumentChannel");
router.setChannelMapping(RuntimeException.class.getName(), "runtimeExceptionChannel");
router.setChannelMapping(IllegalArgumentException.class.getName(), "illegalArgumentChannel");
router.setChannelMapping(MessageHandlingException.class.getName(), "messageHandlingExceptionChannel");
router.setDefaultOutputChannel(this.defaultChannel);
router.afterPropertiesSet();
@@ -104,7 +104,7 @@ public class ErrorMessageExceptionTypeRouterTests {
router.setBeanFactory(this.context);
router.setApplicationContext(this.context);
router.setChannelMapping(RuntimeException.class.getName(), "runtimeExceptionChannel");
router.setChannelMapping(MessageHandlingException.class.getName(), "runtimeExceptionChannel");
router.setChannelMapping(MessageHandlingException.class.getName(), "messageHandlingExceptionChannel");
router.setDefaultOutputChannel(this.defaultChannel);
router.afterPropertiesSet();
@@ -192,8 +192,8 @@ public class ErrorMessageExceptionTypeRouterTests {
ErrorMessageExceptionTypeRouter router = new ErrorMessageExceptionTypeRouter();
router.setBeanFactory(this.context);
router.setApplicationContext(this.context);
router.setChannelMapping(IllegalArgumentException.class.getName(), "illegalArgumentChannel");
router.setChannelMapping(RuntimeException.class.getName(), "runtimeExceptionChannel");
router.setChannelMapping(IllegalArgumentException.class.getName(), "illegalArgumentChannel");
router.setChannelMapping(MessageHandlingException.class.getName(), "messageHandlingExceptionChannel");
router.setDefaultOutputChannel(this.defaultChannel);
router.afterPropertiesSet();