С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
Related
<task:scheduled-tasks>
<task:scheduled ref="testBean" method="testMethod" fixed-rate="1000"/>
</task:scheduled-tasks>
In the above snippet, I want to pass fixed-rate as variable fetched from the config file. How can I do that?
P.S. I don't want to move to the annotation-based scheduler.
After going through various articles and documentation I found a way to achieve the same. So sharing the same.
I created a configuration bean of a loader class. Loader class is responsbile to fetch the configs (either from file or any configuration management tool) and set in the system properties.
<bean id="configuration" class="com.test.config.loader">
</bean>
Say one the property is like
database:mysql
It can be accessed like
<task:scheduled-tasks>
<task:scheduled ref="testBean" method="testMethod" fixed-rate="#{configuration['database']}"/>
</task:scheduled-tasks>
I have the following XML configuration for a Kafka outbound channel adapter:
<int-kafka:outbound-channel-adapter id="kafkaOutboundChannelAdapter"
kafka-producer-context-ref="kafkaProducerContext"
auto-startup="true"
channel="activityOutputChannel">
<int:poller fixed-delay="1000" time-unit="MILLISECONDS" receive-timeout="0" task-executor="taskExecutor"/>
</int-kafka:outbound-channel-adapter>
<task:executor id="taskExecutor"
pool-size="5-25"
queue-capacity="20"
keep-alive="120"/>
This works just fine. I am trying to replicate this in the Java DSL, but I can't get too far. So far, I just have this:
.handle(Kafka.outboundChannelAdapter(kafkaConfig)
.addProducer(producerMetadata, brokerAddress)
.get());
I can't figure out how to add the taskExecutor and the poller with the DSL.
Any insight on how to incorporate these into my overall IntegrationFlow is appreciated.
The Spring Integration components (e.g. <int-kafka:outbound-channel-adapter>) consist with two beans: AbstractEndpoint to accept messages from the input-channel and MessageHandler to handle message.
So, Kafka.outboundChannelAdapter() is about MessageHandler. Any other endpoint-specific properties are up to the second Consumer<GenericEndpointSpec<H>> endpointConfigurer argument of .handle() EIP-method:
.handle(Kafka.outboundChannelAdapter(kafkaConfig)
.addProducer(producerMetadata, brokerAddress),
e -> e.id("kafkaOutboundChannelAdapter")
.poller(p -> p.fixedDelay(1000, TimeUnit.MILLISECONDS)
.receiveTimeout(0)
.taskExecutor(this.taskExecutor)));
See Reference Manual for more information.
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().
I have a spring app which listens on rabbitmq and processing the message, when the app runs, I will register on a hub database to note that one instance is running, during the registering if another instance is already running, then I need to quit app without init the rabbit connection/queue and listener, otherwise some message could be wrongly consumed. How to do that, I know there are callback when init a bean. So I should create bean and before init it, checking whether another instance is running, but how to make sure this bean will be init before other beans? But I also need to init database source bean before the checking bean, otherwise it can't use the database defined in configuration.
<rabbit:connection-factory id="connectionFactory" host="localhost" username="guest" password="guest" />
<rabbit:admin id="containerAdmin" connection-factory="connectionFactory" />
<rabbit:queue id="ETLQueue" name="ETLQueue" />
<rabbit:direct-exchange id="myExchange" name="ETL">
<rabbit:bindings>
<!--if doens't specifiy key here, the by default the key will be the same as queue name, and then need to send message with the correct key,
otherwise the listener can't receive the mssage-->
<rabbit:binding queue="ETLQueue" key="ETLQueue" />
</rabbit:bindings>
</rabbit:direct-exchange>
<bean id="aListener" class="com.testcom.amqp.listener.ConnectorListener" c:dataSource-ref="dataSource"/>
<!--concurrency will set how many threads running concurrently to consume the messsage, the code need to be thread safe-->
<rabbit:listener-container id="myListenerContainer" connection-factory="connectionFactory" prefetch="1" concurrency="10">
<rabbit:listener ref="aListener" queues="ETLQueue" />
</rabbit:listener-container>
As you are using xml configuration, the attribute depends-on normally helps to say that a bean should not be initialized before the target bean :
<bean id="A" .../>
<bean id="B" ... depends-on="A"/>
Bean B should be initialized after A (unless there are some cyclic dependency in which case spring only does its best ...)
Configs like this:
<int-amqp:inbound-channel-adapter connection-factory="connectionFactory" queue-names="#{prop['mq.queue.logging']}"
channel="emailLoggingChannel" message-converter="jsonMessageConverter" error-channel="errorChannel" />
<int:channel id="emailLoggingChannel"/>
<int:service-activator id="handleEmailLogging" input-channel="emailLoggingChannel"
ref="emailLoggingService" method="insertOrUpdate"/>
My question is:
How can I passing properties of AMQP message to int:service-activator?
Appreciated.
The AMQP MessageProperties are mepped to the MessageHeaders.
By default only standard AMQP properties (headers) are mepped.
To map all of them including any custom properties you should use this
mapped-request-headers="*"
for the <int-amqp:inbound-channel-adapter>.
See more info in the Reference Manual.