Messages in SpringIntegration - spring-integration

I have QueueChannel with the message-store attribute. Its configuration
<int:channel id="channel1">
<int:queue message-store="msgStore"></int:queue
</int:channel>
Then I want to send messages from channel "channel1" using <int-http:outbound-gateway/>
It looks so:
<int-http:outbound-gateway
url="someUrl"
http-method="PUT"
request-channel="channel1">
<int-http:request-handler-advice-chain>
<int:retry-advice max-attempts="3">
<int:exponential-back-off initial="1000" multiplier="2.0" maximum="8000"/>
</int:retry-advice>
</int-http:request-handler-advice-chain>
</int-http:outbound-gateway>
My problem:
If the message couldn't be sent, I need that it be in the channel "channel1". But it always is removed from channel.
How do that it remains in the channel?
EDIT1.
<int:poller
default="true"
fixed-rate="100"
receive-timeout="100">
<int:transactional/>
</int:poller>
EDIT2
<int-jdbc:message-store
id="msgStore" data-source="jdbcSQLiteDataSource"/>

Your configuration doesn't look right - you need a poller on the gateway to poll the channel for messages.
Without a transaction, you can't "leave it in the channel" after a failure; you could put it back into the channel with an ExpressionEvaluatingRequestHandlerAdvice (and a flow on its failure channel to transform the error message back to the original), but it will be at the tail of the queue, not the head.
If you message store supports transactions, you can make the poller transactional and the failure will rollback the message into the store.

Related

Spring Integration Poller dropping messages

I want to send the messages received from a jms queue to a spring pub sub channel in order to forward the same message to two destinations. The poller was working fine for a direct channel but is dropping messages when posting to pub sub channel. Please let me know what I am missing.
<int-jms:inbound-channel-adapter connection-factory="connectionFactory" destination-name="queue-name" channel="jmsChannel" extract-payload="false" acknowledge="transacted">
<int:poller max-messages-per-poll="5" fixed-delay="1000"></int:poller>
</int-jms:inbound-channel-adapter>
<int:publish-subscribe-channel id="jmsChannel" task-executor="executor" />
<task:executor id="executor" pool-size="10"/>
<int-jms:outbound-channel-adapter connection-factory="connectionFactory" channel="jmsChannel" destination-name="sample-q" />
The default behavior of a pub/sub channel is similar to a JMS topic with no durable subscriptions; if there are no subscribers, the message is dropped.

Spring Integration - Missing Messages

I have an integration application that mostly works, but noticed yesterday a message was lost. At the time, the service-activator endpoint was extremely busy processing a previous message.
Basically, my integration flow is:
jdbc:inbound-channel-adapter --> splitter -> aggregator (based on a type field) -> [pollable channel] --> service-activator
From the log, I can see a group of messages polled, split, aggregated, expired (via a message store reaper), and placed on the creation channel. There is a preSend and postSend event in the log for placing the message on the creationChannel, but that's the end of it. It never gets to my service-activator, there's no messages in the jdbc message store and I dont see any errors.
Could there an issue with how I have either the service-activator or poller configured (or a combination)?
Here is the configuration applicable to the issue.
<int:poller default="true" fixed-delay="1000" receive-timeout="0" />
<int-jdbc:message-store id="jdbc-messageStore" data-source="dataSource" />
<int:channel id="creationChannel" >
<int:queue message-store="jdbc-messageStore" />
</int:channel>
<!-- Endpoint responsible for creating Archive from List of Document objects -->
<bean id="archiveCreator" class="org.abc.ArchiveCreator"/>
<int:service-activator ref="archiveCreator" method="createArchive" input-channel="creationChannel" />
First of all you should mark your <poller> as <transactional>.
Another point switch on the org.springframework.integration DEBUG logging level and show here the log, when a message is lost.

inbound adapter skipping messages

This is how my configuration looks like
<int-file:inbound-channel-adapter id="files" directory="${lz.dir.${ft}}">
<int:poller fixed-delay="3000" max-messages-per-poll="3" />
</int-file:inbound-channel-adapter>
<int:bridge input-channel="files" output-channel="sourceFiles" />
<int:channel id="sourceFiles">
<int:dispatcher task-executor="executor" />
</int:channel>
<int:service-activator input-channel="sourceFiles"
ref="moveToSource"
method="move" />
<int:aggregator id="filesBuffered"
input-channel="sourceFiles"
output-channel="stagedFiles"
release-strategy-expression="size() == 10"
correlation-strategy-expression="'mes-group'"
expire-groups-upon-completion="true"
/>
<int:channel id="stagedFiles" />
<int:service-activator input-channel="stagedFiles"
ref="moveToStage"
method="move" />
<task:executor id="executor" pool-size="5" queue-capacity="0" rejection-policy="CALLER_RUNS" />
The idea is to poll a directory every 3 second and emit 3 messages per poll to a dispatcher based on channel to allow asynchronous execution. Messages are then aggregated based on number of messages and then emitted to next service activator. The first service activator places files in source directory and second service activator which gets the aggregated list to move those files to staging directory.
What seems to be happening is that source folder skips some files but the staging folder does gets all the files. My guess is that poller sends the messages to the dispatcher channel but when its thread pool gets full it simply ignores the files but somehow the aggregator still gets all the files. Almost like dispatcher channel skips the first service activator step for files it receives after the thread pool limit has reached but those files are still passed to next channel and thats how they still end up getting processed by the second service activator.
What I would like to do is have the poller resend the files that were rejected by the dispatcher. Any ideas would be appreciated.
Thanks
Sorry, I don't understand what you describe, but by your configuration it looks like:
sourceFiles channel is point-to-point one. So, only one subscriber at a time can get message from that channel.
But you have two subscribers - service-activator and aggregator
By default dispatcher uses RoundRobinLoadBalancingStrategy. That means, that first message will be processed by first subscriber, the second one - by second subscriberб and so on, like relay.
So, if you want to have a sequential, there is need to subscribe aggregator to the outbound-channel of moveToSource service-activator and return from move method the same payload. In your case File.
If it isn't your case, so provide, please, correct config or explain your use-case.
Now it is confused, sorry.
HTH

Keep sending messages in Spring Integration

One module sends messages to the message broker every N second. The other module receive the messages from the broker. The messages is built in a method sendMessage of the service activator. The plan was to use inbound channel adapter (as in the answer) but for some reasons this solution does not work and I keep receiving "Received no Message during the poll, returning 'false'". What is wrong with this configuration?
<int-jms:inbound-channel-adapter id="keepAlivePoller" channel="keepAliveChannel" destination="keepAlive" connection-factory="connectionFactory">
<si:poller id="sendPoller" fixed-rate="${keepalive.sendinterval}" max-messages-per-poll="1"></si:poller>
</int-jms:inbound-channel-adapter>
<si:service-activator input-channel="keepAliveChannel" method="sendMessage" ref="keepAliveSender"/>
<bean class="com.foo.KeepAliveSender"/>
<si:channel id="keepAliveChannel"/>
That will only send a message if there is a message in the "keepAlive" queue.
You can simply use...
<int:inbound-channel-adapter id="keepAlivePoller" channel="keepAliveChannel"
expression="'foo'">
<si:poller id="sendPoller" fixed-rate="${keepalive.sendinterval}" />
</int:inbound-channel-adapter>
... and not use JMS at all.

message with no replyTo

The message will not have any replyTo. It just places the message on the queue and does expects any reply "one-way" however if the message processing fails, it needs to be rolled back so that other server could process it. So in-order to process that message I'm using publish-subscribe-channel like below
<int:publish-subscribe-channel id="SplitChannel">
</int:publish-subscribe-channel>
<int-jms:inbound-gateway request-channel="UChannel" request-destination-name="U" extract-request-payload="true" acknowledge="transacted" concurrent-consumers="5" max-messages-per-task="5"/>
<int:chain input-channel="UChannel">
<int-http:outbound-gateway
url="http://localhost/u.php?fileid={fileid}"
http-method="GET"
reply-channel="nullChannel">
<int-http:uri-variable name="fileid" expression="headers.fileid"/>
</int-http:outbound-gateway>
</int:chain>
I'm getting the error as follows
DEBUG: [May-30 00:43:28,768] jms.listener.DefaultMessageListenerContainer - Initiating transaction rollback on application exception
javax.jms.InvalidDestinationException: Cannot determine reply destination: Request message does not contain reply-to destination, and no default reply destination set.
DEBUG: [May-30 00:43:28,768] apache.activemq.ActiveMQSession - 43979-1369895783067-0:15:1 Transaction Rollback
A <gateway/> is for two-way integration; channel adapters are for one-way; use an <int-jms:message-driven-channel-adapter/> instead.

Resources