Announcement Announcement Module
No announcement yet.
Multiple RabbitAdmin instances force dubious declarations. Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Multiple RabbitAdmin instances force dubious declarations.

    Hi Guys,

    I'm a little confused on the queue declaration policy for spring rabbit dist of amqp. Documentation suggests following

    2.12.1 Automatic Declaration of Exchanges, Queues and Bindings

    The RabbitAdmin component can declare exchanges, queues and bindings on startup. It does this lazily, through a ConnectionListener, so if the broker is not present on startup it doesn't matter. The first time a Connection is used (e.g. by sending a message) the listener will fire and the admin features will be applied. A further benefit of doing the auto declarations in a listener is that if the connection is dropped for any reason (e.g. broker death, network glitch, etc.) they will be applied again the next time they are needed.

    However, currently there is no mechanism for assigning a queue to a particular connection factory, so if I wanted to declare a queue on a particular broker with RabbitAdmin, it is currently not possible.

    The code at fault imo is the following :-
    final Collection<Exchange> exchanges = applicationContext.getBeansOfType(Exchange.class).values();
    		final Collection<Queue> queues = applicationContext.getBeansOfType(Queue.class).values();
    		final Collection<Binding> bindings = applicationContext.getBeansOfType(Binding.class).values();
    rabbitTemplate.execute(new ChannelCallback<Object>() {
    			public Object doInRabbit(Channel channel) throws Exception {
    				declareExchanges(channel, exchanges.toArray(new Exchange[exchanges.size()]));
    				declareQueues(channel, queues.toArray(new Queue[queues.size()]));
    				declareBindings(channel, bindings.toArray(new Binding[bindings.size()]));
    				return null;
    Which obviously is indiscriminate in its effort to create bindings.

    Are there any plans to fix this or any workaround ?

    Last edited by Gary Russell; Apr 19th, 2013, 10:34 AM.

  • #2
    When entering code and config, please use [ code ] ... [ /code ] tags (no spaces in brackets), I edited your post.

    This sounds like a reasonable request to me; please go ahead and open an 'Improvement' JIRA issue.

    There are a number of ways we might address it (list/pattern of items on the RabbitAdmin and/or assign an optional CF to each element, as you describe)

    In the meantime, there is a trick you can play as a work-around - use a separate application context for the declarations in each factory...

    main context
    	<bean id="declareInAnotherContext" class="">
    		<constructor-arg value="/META-INF/spring/integration/foo-context.xml" />
    	<rabbit:connection-factory id="connectionFactory" addresses="frodo:5672"/>
    	<rabbit:admin connection-factory="connectionFactory" />
    	<rabbit:queue name="foo.test.queue" />
    	<bean id="forceDeclarations" class="foo.ForceDeclarations">
    		<constructor-arg ref="connectionFactory" />
    public class ForceDeclarations {
    	public ForceDeclarations(CachingConnectionFactory factory) {
    Depending on your usage, you may need to define the queues etc in the main and the sub-contexts; in which case, simply omit the rabbit admin in the main context and do all the declarations in child context.

    Obviously, ForceDeclarations would have to be a bit more sophisticated than this, in order to reconnect/redeclare after a failure. Or, you can add a listener container that listens on a dummy queue - it wiill automatically reconnect, causing the redeclare.
    Last edited by Gary Russell; Apr 19th, 2013, 11:13 AM.


    • #3 - issue ref.


      • #4
        This feature is now available in the 1.2.0.RELEASE.

        Thanks for the suggestion!