From a7dc7c39129336f72f29aff76667e69746f1b11b Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Wed, 15 Jun 2016 19:37:00 -0400 Subject: [PATCH] INT-4057: Router: don't use convert for Class key JIRA: https://jira.spring.io/browse/INT-4057 When general router `channelKey` returns just a `Class` result, we end up with the `unsupported return type for router [class java.lang.Class]` and forced to to call its `getName()` in the target application code before returning to router. * Change the `AbstractMappingMessageRouter` logic to treat `Class` as a special String-aware case, use its `getName()` and don't go to the `ConversionService` * Increase receive timeout for replies in the `TcpInboundGatewayTests` --- .../router/AbstractMappingMessageRouter.java | 3 ++ .../router/MethodInvokingRouterTests.java | 37 +++++++++++++++- .../ip/tcp/TcpInboundGatewayTests.java | 42 +++++++++++-------- 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java index 07e5a0ed42..d2daec83e9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java @@ -281,6 +281,9 @@ public abstract class AbstractMappingMessageRouter extends AbstractMessageRouter else if (channelKey instanceof String) { addChannelFromString(channels, (String) channelKey, message); } + else if (channelKey instanceof Class) { + addChannelFromString(channels, ((Class) channelKey).getName(), message); + } else if (channelKey instanceof String[]) { for (String indicatorName : (String[]) channelKey) { addChannelFromString(channels, indicatorName, message); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java index 71311b1f80..e0ebfaa509 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -40,6 +40,7 @@ import org.springframework.messaging.support.GenericMessage; /** * @author Mark Fisher + * @author Artem Bilan */ public class MethodInvokingRouterTests { @@ -548,6 +549,32 @@ public class MethodInvokingRouterTests { } + @Test + public void testClassAsKeyResolution() { + QueueChannel stringsChannel = new QueueChannel(); + QueueChannel numbersChannel = new QueueChannel(); + TestChannelResolver channelResolver = new TestChannelResolver(); + channelResolver.addChannel("stringsChannel", stringsChannel); + channelResolver.addChannel("numbersChannel", numbersChannel); + + MethodInvokingRouter router = new MethodInvokingRouter(new ClassAsKeyTestBean()); + router.setChannelResolver(channelResolver); + router.setChannelMapping(String.class.getName(), "stringsChannel"); + router.setChannelMapping(Integer.class.getName(), "numbersChannel"); + + Message message = new GenericMessage<>("bar"); + router.handleMessage(message); + Message replyMessage = stringsChannel.receive(10000); + assertNotNull(replyMessage); + assertEquals(message, replyMessage); + + message = new GenericMessage<>(11); + router.handleMessage(message); + replyMessage = numbersChannel.receive(10000); + assertNotNull(replyMessage); + assertEquals(message, replyMessage); + } + public static class SingleChannelNameRoutingTestBean { @@ -668,4 +695,12 @@ public class MethodInvokingRouterTests { } + private static class ClassAsKeyTestBean { + + public Class routePayload(Object payload) { + return payload.getClass(); + } + + } + } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpInboundGatewayTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpInboundGatewayTests.java index d485dc6f92..963e0839a3 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpInboundGatewayTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpInboundGatewayTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -57,6 +57,10 @@ import org.springframework.messaging.core.DestinationResolver; import org.springframework.messaging.support.GenericMessage; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +/** + * @author Gary Russell + * @since 2.0 + */ public class TcpInboundGatewayTests { @Test @@ -82,8 +86,8 @@ public class TcpInboundGatewayTests { socket1.getOutputStream().write("Test1\r\n".getBytes()); Socket socket2 = SocketFactory.getDefault().createSocket("localhost", port); socket2.getOutputStream().write("Test2\r\n".getBytes()); - handler.handleMessage(channel.receive(1000)); - handler.handleMessage(channel.receive(1000)); + handler.handleMessage(channel.receive(10000)); + handler.handleMessage(channel.receive(10000)); byte[] bytes = new byte[12]; readFully(socket1.getInputStream(), bytes); assertEquals("Echo:Test1\r\n", new String(bytes)); @@ -275,24 +279,28 @@ public class TcpInboundGatewayTests { } - private class Service { - @SuppressWarnings("unused") - public String serviceMethod(byte[] bytes) { - return "Echo:" + new String(bytes); - } - } - - private class FailingService { - @SuppressWarnings("unused") - public String serviceMethod(byte[] bytes) { - throw new RuntimeException("Planned Failure For Tests"); - } - } - private void readFully(InputStream is, byte[] buff) throws IOException { for (int i = 0; i < buff.length; i++) { buff[i] = (byte) is.read(); } } + private class Service { + + @SuppressWarnings("unused") + public String serviceMethod(byte[] bytes) { + return "Echo:" + new String(bytes); + } + + } + + private class FailingService { + + @SuppressWarnings("unused") + public String serviceMethod(byte[] bytes) { + throw new RuntimeException("Planned Failure For Tests"); + } + + } + }