问题
Considering any message bus can be deployed with spring-xd, is there any API provided by spring-xd that can write to the message bus deployed, say, Kafka/rabbitmq based on the configurations in xd/config/servers.yml or any other such place.
I am writing a processor (itemprocessor), which does some processing of the data and the writer will write the data to a rabbitmq queue for now. Since, in the current deployment scenario, rabbitmq may or may not be deployed, the processor should be able to write to the default Redis message bus.I know I can write to rabbitmq using apis provided by spring-rabbit, but that will tie my processor to RabbitMQ. I am looking for a way to generalize it. I tried to looked into spring-xd code to see if there were any examples like this. I found a MessageProcessor example, but this one is a stream processor, not sure how I can apply it or if I am on the right track.
https://github.com/spring-projects/spring-xd/blob/master/spring-xd-rxjava/src/test/java/org/springframework/xd/rxjava/PongMessageProcessor.java
I just started working with spring-xd, so please pardon my ignorance if this has already been discussed. Any pointers are greatly appreciated.
Update
Thanks Gary, based on your answer I tried out the spring-integration jms samples.
I have a spring batch job which has
<batch:chunk reader="reader" processor="processor" writer="writer" />
I want the output of the writer to be written to any underlying message bus, RabiitMQ to start with. So I added the following, based on what I saw in the examples:
<beans:bean id="writer" class="abc" scope="step">
</beans:bean>
<channel id="outputme"/>
<beans:bean id="requestQueue" class="org.apache.activemq.command.ActiveMQQueue">
<beans:constructor-arg value="queue.demo"/>
</beans:bean>
<beans:bean id="replyQueue" class="org.apache.activemq.command.ActiveMQQueue">
<beans:constructor-arg value="queue.reply"/>
</beans:bean>
<jms:outbound-gateway request-channel="outputme"
request-destination="requestQueue"
reply-channel="jmsReplyChannel"/>
<channel id="jmsReplyChannel" />
<beans:beans profile="default">
<stream:stdout-channel-adapter channel="jmsReplyChannel" append-newline="true"/>
</beans:beans>
When I execute this, I see the following output, which leads me to believe that something is getting written to the embedded ActiveMQ broker.
16:05:42,400 [AbstractApplicationContext] - Closing org.springframework.context.support.GenericApplicationContext@125a6d70: startup date [Tue Feb 03 16:05:40 PST 2015]; root of context hierarchy
16:05:42,401 [DefaultLifecycleProcessor$LifecycleGroup] - Stopping beans in phase 0
16:05:42,402 [EventDrivenConsumer] - Removing {jms:outbound-gateway} as a subscriber to the 'outputme' channel
16:05:42,402 [AbstractSubscribableChannel] - Channel 'org.springframework.context.support.GenericApplicationContext@125a6d70.outputme' has 0 subscriber(s).
16:05:42,402 [AbstractEndpoint] - stopped org.springframework.integration.config.ConsumerEndpointFactoryBean#0
16:05:42,402 [EventDrivenConsumer] - Removing {service-activator} as a subscriber to the 'jmsReplyChannel' channel
16:05:42,402 [AbstractSubscribableChannel] - Channel 'org.springframework.context.support.GenericApplicationContext@125a6d70.jmsReplyChannel' has 1 subscriber(s).
16:05:42,402 [AbstractEndpoint] - stopped org.springframework.integration.config.ConsumerEndpointFactoryBean#1
16:05:42,402 [EventDrivenConsumer] - Removing {stream:outbound-channel-adapter(character)} as a subscriber to the 'jmsReplyChannel' channel
16:05:42,403 [AbstractSubscribableChannel] - Channel 'org.springframework.context.support.GenericApplicationContext@125a6d70.jmsReplyChannel' has 0 subscriber(s).
16:05:42,403 [AbstractEndpoint] - stopped org.springframework.integration.config.ConsumerEndpointFactoryBean#2
However, when I try to change ActiveMQ with RabbitMQ by changing the connectionfactory like this:
<rabbit:connection-factory id="connectionFactory" />
I get an error saying:
Cannot convert value of type [org.springframework.amqp.rabbit.connection.CachingConnectionFactory] to required type [javax.jms.ConnectionFactory] for property 'connectionFactory'
which I understand based on what is mentioned in the schema file at http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd, as the required type is javax.jms.ConnectionFactory for the element connection-factory. I looked around, did not find a way to create the conenctionFactory for RabbitMQ the same way as we create the ConnectionFactory for ActiveMQ.
I looked around and am not sure how to fix this. Maybe I am missing something very basic. I am not even sure if this is the right approach. Can you please let me know what I am missing and if this is the right approach? I apologize in advance if this has been discussed already.
Thank you again for your time.
Thank you so much for your time.
regards,
Alice
回答1:
The MessageBus
SPI is very specific for XD intra-module commmunication; it's not designed for arbitrary application-level messaging.
That said, XD (and its message bus implementations) uses the Spring Integration project extensively.
That project provides the abstraction you need. You can send to a message channel (either using a MessagingGateway
or a MessagingTemplate
and, downstream of that channel, you can wire in any kind of channel adapter (rabbit [amqp], redis, etc).
So your item processor is decoupled from the actual technology that receives the message.
Take a look at the Spring Integration reference manual (there's a link on the project page).
来源:https://stackoverflow.com/questions/28226211/is-there-an-api-in-spring-xd-to-write-to-a-message-bus