Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Connecting to two machines from spring AMQP

  1. #1
    Join Date
    Sep 2010
    Posts
    22

    Default Connecting to two machines from spring AMQP

    I have a situation where i need to connect to two hosts. I setup two separate configuration classes , with different connections and queue declarations and bindings.

    have

    <context:component-scan base-package="com.xx.tdb.queue_processor.config1,com.xx x.tdb.queue_processor.config2"/>

    entry in my spring config file. AMQP always seems to load and initialize only one of the config classes.None of the auto wiring init is happening in the other config class. what am i doing wrong?


    Thanks in advance,
    Suresh

  2. #2
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    Are you providing distinct bean names for the results of your @Bean-annotated methods?

  3. #3
    Join Date
    Sep 2010
    Posts
    22

    Default

    u mean methods like

    @Bean
    public Queue eventQueue() {
    return new Queue(queueName);
    }

    @Bean
    public DirectExchange tdbExchange() {
    return new DirectExchange(exchangeName);
    }

    /**
    * Binds to the TDB data exchange. Interested in any events.
    * @return binding object
    */
    @Bean
    public Binding tdbDataBinding() {
    return BindingBuilder.from(
    eventQueue()).to(tdbExchange()).with(routingKey);
    }



    shd these be distinct ?

  4. #4
    Join Date
    Sep 2010
    Posts
    22

    Default

    Dumb , got it

    thanks for your help

  5. #5
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    Have you verified that and got it working correctly now?

    I should have explained it in a bit more detail...

    The method names become bean names, and the behavior is similar to the use of bean IDs within XML files. They must be unique within a single ApplicationContext so if there is overlap, the last bean definition registered will replace any existing bean with the same ID/name.

    Hope that helps.
    -Mark

  6. #6
    Join Date
    Sep 2010
    Posts
    22

    Default

    Thanks Mark, yeah got that.

    Still facing an issue, I have two consumers connecting to two hosts.
    host1 and host2, I have two java config classes RabbitMqConfiguration1 and RabbitMqConfiguration2. The only difference is they both connect to a different host. When i try to start the listeners , I keep getting a queue not declared error in one of them. When i debug i do see both the bindings getting registered to the correct hosts in both the config classes.

    the error i get is as follows

    Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=404,reply-text=NOT_FOUND - no queue 'LWESEvents' in vhost 'TDB-Dev',class-id=50,method-id=10),null,""}



    when I start them by pointing them to the same host, either 1 or 2 then it works.

    @Bean(name = "eventQueue2")
    public Queue eventQueue() {

    }

    @Bean(name = "tdbExchange2")
    public DirectExchange tdbExchange() {
    }

    @Bean(name = "tdbDataBinding2")
    public Binding tdbDataBinding() {
    }

    @Bean(name = "messageListenerContainer2")
    public SimpleMessageListenerContainer messageListenerContainer() {
    }

    @Bean(name = "connectionFactory2")
    public ConnectionFactory connectionFactory() {
    //only host differs here rest of all the params are same
    }

    @Bean(name = "messageListenerAdapter2")
    public MessageListenerAdapter messageListenerAdapter() {
    }

    thanks again for your help
    Suresh

  7. #7
    Join Date
    Sep 2010
    Posts
    22

    Default

    Ahh!! its cause the amqpAdmin was a singleton.

    I fixed it by not implementing from AbstractRabbitConfiguration and providing my own adminbean

    @Bean(name = "amqpAdmin1")
    public AmqpAdmin amqpAdmin() {
    return new RabbitAdmin(rabbitTemplate());
    }

    @Bean(name = "template1")
    public RabbitTemplate rabbitTemplate() {
    return new RabbitTemplate(connectionFactory());
    }

    Is there a better way to do this, I see that the BIndings are registered for each of the admins twice, its ok in my case as everything except the host is the same.

    thanks,
    Suresh
    Last edited by avyaktha; Oct 8th, 2010 at 05:01 PM.

  8. #8
    Join Date
    Sep 2010
    Posts
    22

    Default

    any one , have any suggestions?

  9. #9
    Join Date
    Aug 2004
    Location
    New York, NY
    Posts
    74

    Default

    Hi,

    We should more explicitly support this type of scenario. What I can suggest is to either set autoStartup to false in RabbitAdmin or avoid its use completely so that it doesn't perform any of the declarations and instead do it yourself in code. Not ideal. Perhaps a better short term approach is to subclass RabbitAdmin and override the start method so that only the Exchange,Queues, and Bindings specific to a given broker/connection will be used. Instead of the current code that get all the queues, i.e.
    Code:
    applicationContext.getBeansOfType(Queue.class).values();
    It would instead use a lookup method that uses qualifier annotations to restrict the set of returned beans.

    Code:
    getBeansWithAnnotation(Class<? extends Annotation> annotationType)
    comes close but one would also like to specify the class... a getBeanOfTypeWithAnnotation method.... Otherwise you will have to filter out from the returned map the beans which are queues, exchanges, bindings...

    The @Configuration bean definitons would then have the qualifier annotation on them.

    Code:
    @Bean(name = "eventQueue2")
    @Qualifier("broker2")
    public Queue eventQueue() {
    }
    I don't think there is 'inheritance' of qualifier annotations on the @Configuration class to the methods, but that might be nice to consider.

    Then one would need two instances of this subclass of RabbitAdmin, each configured to use different qualifier annotations.

    HTH,
    Mark
    Last edited by Mark Pollack; Oct 13th, 2010 at 12:20 PM.

  10. #10
    Join Date
    Jun 2005
    Posts
    4,230

    Default

    Maybe two ApplicationContext instances, one for each host would help?

    Multiple vhosts is something we should support eventually (and Holly said she was interested in contributing in this area), so it will be useful to keep this discussion going. Open a JIRA or two maybe?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •