Combine few channels in Spring Integration - java

I have a heavy loaded (allot of external network calls) integration flow, which uses PriorityQueue before entering main Service Activator. I want to add executor channel to improve the system load, but I see no straight forward ways to combine those channels.
<int:channel id="monitorInPriorityUpdate">
<int:priority-queue/>
</int:channel>
<int:transformer id="monitorLogTransformerStub"
input-channel="monitorInPriorityUpdate" output-channel="monitorInUpdate"
expression="payload" />
<int:channel id="monitorInUpdate">
<int:dispatcher task-executor="monitorExecutor"/>
</int:channel>
I needed to create 2 additional components, to make this work, but is there a way to combine few Spring Integration Channels in one, without adding new components?

Actually, looks like not ebough info. But I try to guess. You need this:
<int:channel id="priorityChannel">
<int:priority-queue/>
</int:channel>
<int:bridge input-channel="priorityChannel" output-channel="executorChannel">
<int:poller fixed-rate="100"/>
</int:bridge>
<int:channel id="executorChannel">
<int:dispatcher task-executor="threadPoolExecutor"/>
</int:channel>
Here you use a Bridge to shift messages from one channel to another one.
OR this:
<int:channel id="priorityChannel">
<int:priority-queue/>
</int:channel>
<int:service-activator input-channel="priorityChannel" ref="service">
<int:poller fixed-rate="100" task-executor="threadPoolExecutor"/>
</int:service-activator>
Here you just place your messages from priorityChannel to taskExecutor using Poller.
It is abnormal to mix concerns in one channel. Each channel type plays his own concreate role.
What you want to achieve is not just minimize typing, but even if that happen to be a solution for you, it would be very complex and not robust.

Related

Converting Spring xml config to java

I've an XML config for mail service in spring, that I'd like to transform to JAVA config.
XML Looks like this
<int:chain id="chain"
input-channel="outMailError"
output-channel="outMailEntry">
<int:poller max-messages-per-poll="1" fixed-rate="20000" />
<int:transformer ref="mailSendErrorTransformer" />
</int:chain>
<int:channel id="outMailError">
<int:queue capacity="500" />
</int:channel>
<int:channel id="outboundMailEntry" />
I was able to convert the channels to
#Bean
public DirectChannel outboundMailEntry() {
return new DirectChannel();
}
#Bean
public QueueChannel outboundMailErrorChannel() {
return new QueueChannel(500);
}
But I don't know how to the same for int:chain. I was able to debug and find out what type of bean does spring instantiate for "chain" part of xml - it is PollingConsumer that takes 2 params PollableChannel inputChannel, MessageHandler handler.
The first one is not a problem since I already have that, it is the
#Qualifier("outMailError")
QueueChannel channel
But I do not know about the second one... Spring itself initializes some MessageHandlerChain but I was unable to to set the outMailEntry to it and also dont know about the poller and transformer.. any ídeas?
There is no chain equivalent in Java Config. It was designed especially for XML to let to minimize XML coding.
On the other hand it doesn't look like you need that <chain> at all: you have only one <int:transformer> over there.
In Java Config you would use a #Trasnoformer annotation on your mailSendErrorTransformer method with appropriate inputChannel and outputChannel attributes. The <int:poller> equivalent is also present over there as a poller attribute with resective #Poller configuration.
See more info in the docs starting from here: https://docs.spring.io/spring-integration/docs/current/reference/html/overview.html#configuration-enable-integration

How to solve exception with inbound-channel-adapter poller?

Сould not find an answer.
Spring version 5.0.6.
My config:
<int:channel id="data"/>
<int:inbound-channel-adapter
id="dataAdapter"
channel="data"
auto-startup="false"
ref="dataGetter"
method="myMessageSource">
<int:poller max-messages-per-poll="10"/>
</int:inbound-channel-adapter>
<beans:bean
class="org.endpoints.DataGetter"
id="dataGetter"/>
Throw exception:
Configuration problem: A <poller> must have one and only one trigger configuration.
If no poller:
No poller has been defined for channel-adapter 'dataAdapter', and no default poller is available within the context.
How to properly setup the poller?
Look at your config:
<int:poller max-messages-per-poll="10"/>
You don't meet the condition to have or fixed-delay, or fixed-rate, or cron, or just trigger reference: https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/messaging-endpoints-chapter.html#endpoint-namespace

How to configure RabbitMQ in XML file to have 1) listener listening from multiple queues 2) 2 listeners listening to same queue?

I am trying to understand Spring RabbitMQ XML configuration. So far, I never came across xml configuration where a listener is listnening(subscribed) to multiple queues. Like wise, I never found codes wherein 2 listeners are subscribed to the same queue in the same xml file. After going through the XSD documentation where in I found that the attribute- "queue-names" is a comma separated list of queue names. So, I believe xml configuration can also be like -
<rabbit:queue id="springQueue1" name="spring.queue1" auto-delete="true" durable="false"/>
<rabbit:queue id="springQueue2" name="spring.queue1" auto-delete="true" durable="false"/>
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener queues="springQueue1, springQueue2" ref="messageListener"/>
</rabbit:listener-container>
<bean id="messageListener" class="com.ndpar.spring.rabbitmq.MessageHandler"/>
Is this correct? Is the syntax correct in "queues" attribute?? Also, if two listeners are receiving from same queue, then
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener queues="springQueue1" ref="messageListener1"/>
<rabbit:listener queues="springQueue1" ref="messageListener2"/>
</rabbit:listener-container>
<bean id="messageListener1" class="com.ndpar.spring.rabbitmq.MessageHandler1"/>
<bean id="messageListener2" class="com.ndpar.spring.rabbitmq.MessageHandler2"/>
Is this correct?? The "ref" attribute always refers to bean id??? or can it refer to bean name??
Is this valid -
<rabbit:listener queues="springQueue1" ref="messageListener1, messageListener2"/>
Please help.Thanks.
Is this correct? Is the syntax correct in "queues" attribute??
Yes, that is correct; a single consumer consumes from 2 queues.
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener queues="springQueue1" ref="messageListener1"/>
<rabbit:listener queues="springQueue1" ref="messageListener2"/>
</rabbit:listener-container>
It's functionally the same as a single listener with concurrency="2" - in that case, the container will create 2 consumers against the queue. In your case, we'll get 2 containers, each with one consumer.
The ref has to reference a single bean id. For normal <bean/>s, name is a synonym for id.
This is invalid:
<rabbit:listener queues="springQueue1" ref="messageListener1, messageListener2"/>

Multiple service activators of same input channel in spring integration

I have a requirement of processing the same information of a request in two different ways asynchronously. I am using spring integration in my project.
Can I have two service activators reading from the same input channel as below? I will get my data from a queue through an adapter and forwarded to the channel.
<int:channel id="dataChannel" />
<service-activator input-channel="dataChannel" ref="serviceA" method="method1">
<service-activator input-channel="dataChannel" ref="serviceB" method="method2">
<bean id="serviceA" class="a.b.test.ServiceA">
<bean id="serviceB" class="a.b.test.ServiceB">
Change dataChannel to
<int:publish-subscribe-channel id=`dataChannel` task-executor="exec" />
(declare a <task:executor ... />).

ImapIdleChannelAdapter task-scheduler threads configuration

I've been playing with the ImapIdleChannelAdapter integrated with Spring for a few.. and noticed that it starts 10 task-scheduler threads.
Mostly I have been checking the documentation for the ImapIdleChannelAdapter, but was not able to find a way to config how many threads it will start when listening to a email inbox.
Here is my Spring config:
<int:channel id="receiveChannel" >
<int:dispatcher task-executor="threadPool" />
</int:channel>
<int-mail:imap-idle-channel-adapter id="imapAdapter"
store-uri="imaps://#{systemProperties['imaps.encoded.username']}:#{systemProperties['imaps.encoded.password']}##{systemProperties['imaps.host']}:#{systemProperties['imaps.port']}/INBOX"
channel="receiveChannel" auto-startup="true" should-delete-messages="false" should-mark-messages-as-read="false"
java-mail-properties="javaMailProperties">
</int-mail:imap-idle-channel-adapter>
Thanks for the help.
by setting the number of threads in your executor -- it's the configuration of your "threadPool" bean not, of the imapAdapter itself -- though you can further configure the threading of the imapAdapter with setSendingTaskExecutor() and setTaskScheduler().

Categories