INT-267: Implement Routing Slip Pattern
JIRA: https://jira.spring.io/browse/INT-267 The implementation looks like: * There is the `ROUTING_SLIP` header to keep the list of bean ids; * The `ROUTING_SLIP_INDEX` header keeps track of current `index` in the `ROUTING_SLIP` header; * `ROUTING_SLIP` List can contain channel names or bean references for the `RoutingSlip` strategy implementations. They are differentiated with `@` prefix; * The `<header-enricher>` adds `<routing-slip>` sub-element to specify the comma-delimited value for desired `ROUTING_SLIP` for the downstream flow; * The `AbstractReplyProducingMessageHandler` adds the logic to get deal with `ROUTING_SLIP` List and the algorithm is: - If `ROUTING_SLIP` isn't `null` we build `AtomicInteger` for the current `routingSlipIndex`; - the recursive `getReplyChannelFromRoutingSlip` should return a channel name or `null`; - if current `ROUTING_SLIP_INDEX` if for the `RoutingSlip` strategy, we check its result for `null` and `incrementAndGet()` the current index or not; - for the simple channel name value from `ROUTING_SLIP` list we just `incrementAndGet()` the current index and return the value; - the new `ROUTING_SLIP_INDEX` is populated to the headers of new reply message. * Polishing for `AbstractMessageSplitter` **TODO**: Docs and applying `RoutingSlip` algorithm for the `AbstractCorrelatingMessageHandler` INT-267: Move `replyProducing` logic `ARPMH` -> `AMPH` * Rework `AbstractCorrelatingMessageHandler` to use methods from super class * Rework `MessageHandlerChain.ReplyForwardingMessageChannel` to use `produceReply` * Rename `RoutingSlip` -> `RoutingSlipRouteStrategy` * Add `ExpressionEvaluationRoutingSlipRouteStrategy` Now `routingSlip` header can be configured like: ``` <routing-slip value="channel1; #{@routingSlipRoutingPojo.get(request, reply)}; @routingSlipRoutingStrategy; #{request.headers[myRoutingSlipChannel]}; channel6"/> ``` Where `;` is used as delimiter, because of `,` in the method invocation from SpEL. The simple literal (`channel1`) is just a `MessageChannel` `id`. `@` is used for `RoutingSlipRouteStrategy` bean reference. `#{...}` used for SpEL. The `HeaderEnricherParserSupport` parses this `value` to the `List<String>` - a set of bean names, where any SpEL is wrapped to the `ExpressionEvaluationRoutingSlipRouteStrategy` bean definition INT-267: Introduce `RoutingSlip` Domain class Rename `AbstractMessageProducingHandler` methods: `*reply` -> `*output` Conflicts: src/reference/docbook/whats-new.xml INT-267: Rework `RoutingSlip` -> `Map<List<String>, Integer>` Since `RoutingSlip` POJO isn't scalable in the distributed multi-language environment, it would be better to use some Java generic type for this `ROUTING_SLIP` header. The `Collections.singletonMap(Collections.unmodifiableList(routingSlipPath), 0)` is the best candidate to be convertible to other systems and allow to have thread-safety. The `ROUTING_SLIP` header is recalculated now on each `nextPath` INT-267: Introduce `RoutingSlipHeaderValueMessageProcessor` * Rework `HeaderEnricherParserSupport` logic to get rid of SpEL parsing and change `routingSlipPath` to the `ManagedList<String>` to get gain of `property-placehoder` * Add `<context:property-placeholder>` stuff to the `RoutingSlipTests` INT-267: Move inline expressions to the implicit `EERSRS` from the `RoutingSlipHeaderValueMessageProcessor` INT-267: Fix up JavaDocs and add JDBC test-case INT-267: Address PR comments INT-267: Polishing according PR comments Polishing
This commit is contained in:
committed by
Gary Russell
parent
c7286cc991
commit
fa03c6f268
@@ -8,7 +8,7 @@
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
|
||||
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
<int:logging-channel-adapter channel="output" />
|
||||
|
||||
<service-activator id="service-activator"
|
||||
input-channel="input" output-channel="output"
|
||||
input-channel="input" output-channel="output"
|
||||
xmlns="http://www.springframework.org/schema/integration">
|
||||
<beans:bean
|
||||
<beans:bean
|
||||
class="org.springframework.integration.jdbc.JdbcMessageStoreChannelIntegrationTests$Service" />
|
||||
<poller fixed-rate="200">
|
||||
<advice-chain>
|
||||
@@ -69,4 +69,8 @@
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<int:header-enricher input-channel="routingSlip" output-channel="input">
|
||||
<int:routing-slip value="@myService.nextPath(request, reply)"/>
|
||||
</int:header-enricher>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
|
||||
package org.springframework.integration.jdbc;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.NotSerializableException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -31,8 +34,11 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.serializer.support.SerializationFailedException;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageDeliveryException;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
@@ -71,6 +77,9 @@ public class JdbcMessageStoreChannelIntegrationTests {
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel routingSlip;
|
||||
|
||||
@Before
|
||||
public void clear() {
|
||||
Service.reset(1);
|
||||
@@ -220,6 +229,21 @@ public class JdbcMessageStoreChannelIntegrationTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRoutingSlip() {
|
||||
try {
|
||||
this.routingSlip.send(new GenericMessage<String>("foo"));
|
||||
fail("MessageDeliveryException expected");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(MessageDeliveryException.class));
|
||||
assertThat(e.getCause(), instanceOf(SerializationFailedException.class));
|
||||
assertThat(e.getCause().getCause(), instanceOf(NotSerializableException.class));
|
||||
assertThat(e.getMessage(),
|
||||
containsString("org.springframework.integration.routingslip.ExpressionEvaluatingRoutingSlipRouteStrategy"));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Service {
|
||||
private static boolean fail = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user