does somebody happen to know if it is valid to reuse a service activator and so also the output-channel using several methods (inbound) especially with a splitter and aggregator.
--> Always with result on the gateway.
In several tests it seems to work fine. As soon I added a splitter with an aggregator I get wrongs result routed to the gateway which then fails with a conversion exception (here in my case it cannot convert boolean to integer).
Thanks,
Paul
Flow
Spring Integration Config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
<int:gateway service-interface="activity.BulbMessageGateway">
<int:method name="sendToBulb" request-channel="bulbMessages" reply-channel="bulbSendResult"></int:method>
<int:method name="updateHomeLightStatus" request-channel="homeBulbEntity" reply-channel="homeBulbEntityResult">
</int:method>
<int:method name="updateLightStatus" request-channel="bulbEntities" reply-channel="bulbSendResult">
<int:header name="homeId" expression="#args[0].homeId"/>
<int:header name="bulbId" expression="#args[0].strongId"/>
</int:method>
</int:gateway>
<int:channel id="bulbMessages" />
<int:channel id="bulbSendResult" />
<int:channel id="bulbEntities" />
<int:channel id="homeBulbEntity" />
<int:channel id="homeBulbEntityResult" />
<int:chain input-channel="homeBulbEntity" output-channel="bulbEntities">
<int:splitter expression="payload.bulbs" />
<int:header-enricher>
<int:header name="bulbId" expression="payload.strongId"/>
<int:header name="homeId" expression="payload.homeId"/>
</int:header-enricher>
</int:chain>
<int:transformer method="bulbToLightStatus" input-channel="bulbEntities" output-channel="bulbMessages">
<bean class="util.BulbTransformer"></bean>
</int:transformer>
<int:aggregator input-channel="bulbSendResult" output-channel="homeBulbEntityResult" method="aggregate">
<bean class="util.BooleanAggregator" />
</int:aggregator>
<int:service-activator input-channel="bulbMessages" output-channel="bulbSendResult" method="send">
<bean class="activity.BulbWebsocketMessageSenderBA" />
</int:service-activator>
</beans>
Unit test
#Test
public void sendMessageNoReceiver() {
assertFalse(gateway.sendToBulb(new HomeId("1"), new BulbId("1"), BulbMessageBuilder.restart("foo")));
}
#Test
public void sendMessageWithReceiver() {
MockSession<BulbId, BulbBE> bulbSession = new MockSession<BulbId, BulbBE>(new BulbBE(HomeId.of("1"), BulbId.of("1"), "bulb", "pass"));
registry.addBulbSession(bulbSession);
assertTrue(gateway.sendToBulb(new HomeId("1"), new BulbId("1"), BulbMessageBuilder.restart("foo")));
assertEquals(1, bulbSession.receivedMessages());
}
#Test
public void updateBulbStatus() {
final MockSession<BulbId, BulbBE> bulbSession1 = new MockSession<BulbId, BulbBE>(new BulbBE(HomeId.of("1"), BulbId.of("1"), "bulb", "pass"));
assertFalse(gateway.updateLightStatus(bulbSession1.getIdentity()));
registry.addBulbSession(bulbSession1);
assertTrue(gateway.updateLightStatus(bulbSession1.getIdentity()));
assertEquals(1, bulbSession1.receivedMessages());
final MockSession<BulbId, BulbBE> bulbSession2 = new MockSession<BulbId, BulbBE>(new BulbBE(HomeId.of("1"), BulbId.of("2"), "bulb", "pass"));
assertFalse(gateway.updateLightStatus(bulbSession2.getIdentity()));
registry.addBulbSession(bulbSession2);
assertTrue(gateway.updateLightStatus(bulbSession2.getIdentity()));
assertTrue(gateway.updateLightStatus(bulbSession2.getIdentity()));
assertEquals(2, bulbSession2.receivedMessages());
assertEquals(1, bulbSession1.receivedMessages());
}
#Test
public void updateHomeBulbStatus() {
final HomeBE home = new HomeBE();
home.setId(new ObjectId());
final MockSession<BulbId, BulbBE> bulbSession1 = new MockSession<BulbId, BulbBE>(new BulbBE(home.getStrongId(), BulbId.of("1"), "bulb", "pass"));
registry.addBulbSession(bulbSession1);
final MockSession<BulbId, BulbBE> bulbSession2 = new MockSession<BulbId, BulbBE>(new BulbBE(home.getStrongId(), BulbId.of("2"), "bulb", "pass"));
registry.addBulbSession(bulbSession2);
home.addBulb(bulbSession1.getIdentity());
assertEquals(1, gateway.updateHomeLightStatus(home));
assertEquals(1, bulbSession1.receivedMessages());
assertEquals(0, bulbSession2.receivedMessages());
home.addBulb(bulbSession2.getIdentity());
assertEquals(2, gateway.updateHomeLightStatus(home));
assertEquals(2, bulbSession1.receivedMessages());
assertEquals(1, bulbSession2.receivedMessages());
}
The last test fails if it is executed together with the other tests. It passes if it is executed alone.
The error is that the last method (using the splitter) receives now a boolean, which seems to be a result of the other two methods registered. The result of these methods is a boolean.
Please, share config on the matter.
And according your graph it would be better if you'd minimize the config as much as possible to isolate the problem.
From other side, please, be more specific: your question is fully unclear.
That is your own service. How can we be sure that it is safe to be used in different places? Only you, as an author, can determine that.
UPDATE
Sorry for the delay. Was busy with the release.
And thank for sharing the config for your use-case.
Now I see the problem.
You use everywhere on the gateway's methods a reply-channel. See the documentation on the matter when you need that:
Typically you don’t have to specify the default-reply-channel, since a Gateway will auto-create a temporary, anonymous reply channel, where it will listen for the reply. However, there are some cases which may prompt you to define a default-reply-channel (or reply-channel with adapter gateways such as HTTP, JMS, etc.).
Since you use the same bulbSendResult in different places the behavior is really unpredictable. Moreoever that channel is DirectChannel, so the round-robin balancer are on the scene.
You should get rid of those reply-channel's at all and just rely from your downstream components on the replyChannel header. Therefore you should remove those output-channels in the components which are intended to return replies to your gateway.
For example the last service-activator should be just like this:
<int:service-activator input-channel="bulbMessages" method="send">
<bean class="activity.BulbWebsocketMessageSenderBA"/>
</int:service-activator>
Since you general question how to reuse this service-activator, I'm answering to the question having the config from you:
<int:chain input-channel="homeBulbEntity">
<int:splitter expression="payload.bulbs"/>
<int:header-enricher>
<int:header name="bulbId" expression="payload.strongId"/>
<int:header name="homeId" expression="payload.homeId"/>
</int:header-enricher>
<int:transformer method="bulbToLightStatus">
<bean class="util.BulbTransformer"/>
</int:transformer>
<int:gateway request-channel="bulbMessages"/>
<int:aggregator method="aggregate">
<bean class="util.BooleanAggregator"/>
</int:aggregator>
</int:chain>
Pay attention to the absent output-channel for the <chain>. Therefore it sends reply directly to the replyChannel from headers and as a return to your updateHomeLightStatus gateway's method.
Another trick is that <int:gateway request-channel="bulbMessages"/> which sends messages in the middle of the <chain> flow to your <service-activator> and wait for the reply from there exactly the same way as a top-level gateway - via replyChannel header. For the <service-activator> without an output-channel it is a black-box where to send the reply. It uses just replyChannel from headers!
After receiving the reply gateway in the <chain> push the message to the <aggregator>.
When aggregator will do its logic, the result will be send to the top-level gateway as an output from the <chain>.
That's all.
Let me know what else isn't clear here.
configuration of my application is like :
<int:inbound-channel-adapter channel="quakeinfotrigger.channel"
expression="''">
<int:poller fixed-delay="60000"></int:poller>
</int:inbound-channel-adapter>
<int:channel id="quakeinfo.channel">
<int:queue capacity="10" />
</int:channel>
<int:channel id="quakeinfotrigger.channel"></int:channel>
<int-http:outbound-gateway id="quakerHttpGateway"
request-channel="quakeinfotrigger.channel"
url="http://fff.com/rest/objects"
http-method="POST"
expected-response-type="java.lang.String"
charset="UTF-8"
reply-timeout="5000"
reply-channel="quakeinfo.channel">
</int-http:outbound-gateway>
I need to handle errors according to http_statusCode on the response header. Can you tell me to intercept it in my code.
Thanks
It depends on exactly what you want to do.
There are lots of ways to use the header, for example:
You can subscribe a <router/> to quakeinfo.channel and route based on the header value.
You can use a service activator...
<service-activator input-channel="quakeinfo.channel" ref="foo" method="handle" />
and
public class Foo {
public void handle(#Header("http_statusCode") HttpStatus statusCode) {
...
}
}
I am building a Kafka consumer with spring. My configuration seems to be pretty straightforward. Messages are being consumed and saved in files. However, the payload is cryptic and I can't get the data (short "hello world" messages).
This is what I get when I access the payload (e.g. when I set up a transformer bean btween in inbound kafka and the outboud file:
{test-topic={0=[[B#713c9d72, [B#7d656f90, [B#26bb8c83, [B#4b959d83 [B#5ed74e8e]}}
My question is: How do I access the actual payload (the "hellow world" string")?
My configuration is :
<int:channel id="inputFromKafka">
<int:queue />
</int:channel>
<int:poller
max-messages-per-poll="5" default = "true" fixed-delay="10" time-unit="MILLISECONDS"/>
<int-kafka:inbound-channel-adapter
id="kafkaInboundChannelAdapter" kafka-consumer-context-ref="consumerContext"
auto-startup="true" channel="inputFromKafka">
<int-kafka:consumer-context id="consumerContext"
consumer-timeout="40000" zookeeper-connect="zookeeperConnect">
<int-kafka:consumer-configurations>
<int-kafka:consumer-configuration
group-id="group12" max-messages="5">
<int-kafka:topic id="test-topic" streams="1" />
</int-kafka:consumer-configuration>
</int-kafka:consumer-configurations>
</int-kafka:consumer-context>
<int-kafka:zookeeper-connect id="zookeeperConnect"
zk-connect="localhost:2181" zk-connection-timeout="6000"
zk-session-timeout="6000" zk-sync-time="2000" />
<file:outbound-channel-adapter id="filesOut"
directory="/tmp/fromKafka">
</file:outbound-channel-adapter>
You are seeing raw byte[].
Add...
<bean id="decoder"
class="org.springframework.integration.kafka.serializer.common.StringDecoder" />
and
<int-kafka:consumer-configuration
value-decoder="decoder"
...
I am trying to run the Sample MQTT-SPring integration project . How ever I have modified some the configuration details to fetch from property file . And trying connect to message broker from the runMQTT.java file.
Code snippet are as follow
MQTT-Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:int-mqtt="http://www.springframework.org/schema/integration/mqtt"
xsi:schemaLocation="
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/integration/mqtt http://www.springframework.org/schema/integration/mqtt/spring-integration-mqtt-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<bean id="clientFactory"
class="org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory">
<property name="userName" value="username" />
<property name="password" value="password" />
<property name="serverURIs" value="${serveruri}"></property>
</bean>
<!-- intercept and log every message -->
<int:logging-channel-adapter id="logger"
level="ERROR" />
<int:wire-tap channel="logger" />
<!-- Mark the auto-startup="true" for starting MqttPahoMessageDrivenChannelAdapter from configuration -->
<int-mqtt:message-driven-channel-adapter
id="startCaseAdapter" client-id="clientId" url="${mqttbrokerurl}"
topics="topic" channel="startCase" auto-startup="true" />
<int:channel id="startCase" />
<int:service-activator id="startCaseService"
input-channel="startCase" ref="mqttCaseService" method="startCase" />
<bean id="mqttCaseService" class="com.XXX.integration.ieg.mqtt.MqttCaseService" />
</beans>
The properties(mqttbrokerurl, serveruri) are loaded from root context
RunMQTT
package com.XXX.integration.ieg.mqtt;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
public class RunMqtt {
public void test() throws MqttException{
ApplicationContext ac = new ClassPathXmlApplicationContext("/META-INF/spring/integration/mqtt/mqtt-context.xml");
System.out.println(ac);
MqttPahoMessageDrivenChannelAdapter startCaseAdapter = (MqttPahoMessageDrivenChannelAdapter)ac.getBean("startCaseAdapter");
//Uncomment to stop the adapter manually from program
//startCaseAdapter.start();
//DefaultMqttPahoClientFactory mqttClient = (DefaultMqttPahoClientFactory)ac.getBean("clientFactory");
DefaultMqttPahoClientFactory mqttClient = new DefaultMqttPahoClientFactory();
MqttClient mclient = mqttClient.getClientInstance("tcp://localhost:1883", "JavaSample");
String data = "This is what I am sending in 2nd attempt";
MqttMessage mm = new MqttMessage(data.getBytes());
mm.setQos(1);
mclient.connect();
mclient.publish("topic",mm);
mclient.disconnect();
//Uncomment to stop the adapter manually from program
//startCaseAdapter.stop();
}
public static void main(String[] args) throws MqttException {
new RunMqtt().test();
}
/*public static void main1(String[] args) {
String topic = "MQTT Examples";
String content = "Message from MqttPublishSample";
int qos = 2;
String broker = "tcp://localhost:1883";
String clientId = "JavaSample";
MemoryPersistence persistence = new MemoryPersistence();
try {
MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
System.out.println("Connecting to broker: "+broker);
sampleClient.connect(connOpts);
System.out.println("Connected");
System.out.println("Publishing message: "+content);
MqttMessage message = new MqttMessage(content.getBytes());
message.setQos(qos);
sampleClient.publish(topic, message);
System.out.println("Message published");
sampleClient.disconnect();
System.out.println("Disconnected");
System.exit(0);
} catch(MqttException me) {
System.out.println("reason "+me.getReasonCode());
System.out.println("msg "+me.getMessage());
System.out.println("loc "+me.getLocalizedMessage());
System.out.println("cause "+me.getCause());
System.out.println("excep "+me);
me.printStackTrace();
}
}*/
}
The root context
The root context is as follow
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- This file will be the root context file for web app. All other context will be imported here -->
<!-- Security context . Now the spring security with basic authentication implemented. OAuth2 will be implemented -->
<import resource="security-config.xml" />
<!-- rest service call context -->
<import resource="classpath:META-INF/spring/integration/rest/applicationContext-http-int.xml"/>
<!-- Sftp context-->
<import resource="classpath:META-INF/spring/integration/sftp/SftpInboundReceive-context.xml"/>
<import resource="classpath:META-INF/spring/integration/sftp/SftpOutboundTransfer-context.xml"/>
<import resource="classpath:META-INF/spring/integration/sftp/SftpOutboundTransfer-poll.xml"/>
<!-- mqtt context-->
<import resource="classpath:META-INF/spring/integration/mqtt/mqtt-context.xml"/>
<!--Component scan base package -->
<context:component-scan base-package="com.XXX.integration.ieg"/>
<!-- All the property configuration moved to parent context file to solve the propert not found exception -->
<context:property-placeholder order="1"
location="classpath:/sftpuser.properties, classpath:/sftpfile.properties,classpath:/resthttp.properties, classpath:/mqtt.properties" ignore-unresolvable="true"/>
</beans>
In this case either mqtt or sftp or resthttp property loading is failing. Please help to resolve
stacktrace
java.lang.IllegalArgumentException: ${mqttbrokerurl}
at org.eclipse.paho.client.mqttv3.MqttConnectOptions.validateURI(MqttConnectOptions.java:448)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.<init>(MqttAsyncClient.java:260)
at org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory.getAsyncClientInstance(DefaultMqttPahoClientFactory.java:119)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.connectAndSubscribe(MqttPahoMessageDrivenChannelAdapter.java:189)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.doStart(MqttPahoMessageDrivenChannelAdapter.java:110)
at org.springframework.integration.endpoint.AbstractEndpoint.start(AbstractEndpoint.java:94)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:770)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.XXX.integration.ieg.mqtt.RunMqtt.test(RunMqtt.java:18)
at com.XXX.integration.ieg.mqtt.RunMqtt.main(RunMqtt.java:39)
The properties file
mqtt.properties
mqttbrokerurl=tcp://172.18.128.150:1883
See this answer. When running in a web app, the classpath is relative to the web context.
According to StackTrace your property-placeholders aren't resolved and that's just because you don't have <context:property-placeholder> for your properties file.
Even if you say that it is:
The properties(mqttbrokerurl, serveruri) are loaded from root context
I don't see that stuff in your code:
You show only MQTT-Context.xml
Your RunMqtt starts only that context:
new ClassPathXmlApplicationContext("/META-INF/spring/integration/mqtt/mqtt-context.xml");
So, fix, please, those issues and come back to us with further progress.
I would like to keep the original payload of the original requests and ise it in a xslt-transformer or in other operation. I lose it because I use an xslt-transformer and I need just some of the elements in the transformation. So my scenario is:
1.inbound-gateway (incoming WS req) -> 2.xslt-transformer (mapping for calling an external WS) -> 3.outbound-gateway (calling the external WS) -> 4.xslt-transformer (creating response from the resp. of the external WS and the original req)
At the 4th step I don't have the original req but I'd need it as I have to put values from it to the response. How could I implement it?
Thanks,
V.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-ws="http://www.springframework.org/schema/integration/ws" xmlns:int-xml="http://www.springframework.org/schema/integration/xml" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration/xml http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="authenticator" class="uk.co.virginmedia.test.Authenticator"/>
<bean id="webserviceDestinationProvider" class="uk.co.virginmedia.test.WebserviceDestinationProvider"/>
<bean id="resultToDocumentTransformer" class="org.springframework.integration.xml.transformer.ResultToDocumentTransformer"/>
<util:map id="orderNamespaceMap">
<entry key="res" value="http://schema/ReserveAppointment/2/0" />
</util:map>
<int-ws:inbound-gateway id="ws-gateway-for-rbta" request-channel="incoming-req-channel" reply-channel=""/>
<int:channel id="incoming-req-channel"/>
<int:service-activator id="authentication" input-channel="incoming-req-channel" ref="authenticator" method="authenticate" output-channel="authenticated-channel" />
<int:channel id="authenticated-channel"/>
<int-xml:xpath-router id="servicetype-router" input-channel="authenticated-channel" evaluate-as-string="true">
<int-xml:xpath-expression expression="//res:ReserveAppointmentRequest/res:serviceType/text()" ns-prefix="res" ns-uri="http://schema/ReserveAppointment/2/0"/>
<int-xml:mapping value="Broadband" channel="broadband-channel"/>
<int-xml:mapping value="FTTC+WholesaleLineRental" channel="fttc-wlr-channel"/>
</int-xml:xpath-router>
<int:channel id="broadband-channel"/>
<int-xml:xslt-transformer id="req_for_bt_xslt_transformer" input-channel="broadband-channel" output-channel="domresult_for_bt_channel" xsl-resource="classpath:/xsl/ToBTReq.xsl" result-type="StringResult"/>
<int:channel id="domresult_for_bt_channel"/>
<int:transformer input-channel="domresult_for_bt_channel" output-channel="document_for_bt_channel" expression="payload.toString()"/>
<int:channel id="document_for_bt_channel"/>
<int-ws:outbound-gateway request-channel="document_for_bt_channel" reply-channel="resp_from_bt_channel" destination-provider="webserviceDestinationProvider" id="call_bt-outbound_gateway" />
<int:channel id="resp_from_bt_channel"/>
<int-xml:xslt-transformer id="resp_for_rbta_xslt_transformer" input-channel="resp_from_bt_channel" output-channel="resp_for_rbta_channel" xsl-resource="classpath:/xsl/ToBTReq.xsl" result-type="StringResult"/>
Since your original message is just text you could copy it to a header field. This should work as long as you don't do anything special in between when you store and afterwards retrieve it.
So what I would try is:
<int:header-enricher input-channel="authenticated-channel" output-channel="pre-routing-channel">
<int:header name="original-payload" expression="payload.toString()" />
</int:header-enricher>
<!-- changed input channel of router -->
<int-xml:xpath-router id="servicetype-router" input-channel="pre-routing-channel" evaluate-as-string="true">
If this is not working for you (maybe because you have to do something more special in between or the payload is too big), you still have the option to use a ClaimCheck. Which is actually exactly what you are asking for. For this you'll need a MessageStore and then just store the message payload before modifying it. So instead of the header-enricher you will call
<int:claim-check-in input-channel="authenticated-channel" output-channel="pre-routing-channel" message-store="payloadstore" />
<!-- MessageStore definition storing payload using in memory map -->
<bean id="simpleMessageStore"
class="org.springframework.integration.store.SimpleMessageStore"/>