Announcement Announcement Module
Collapse
No announcement yet.
How to get a connection using XML, how to access the connection? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to get a connection using XML, how to access the connection?

    In the example in the Reference Manual, "1.1.2 With XML Configuration," there is no host name, user or password. How is it supposed to connect to the RabbitMQ server? I have not been able to get it to work as described in the documentation:

    <rabbit:connection-factory id="connectionFactory"/>

    I presume that something is missing from the documentation. What?

  • #2
    Spring-AMQP delegates to the rabbit client ConnectionFactory, which uses a default host of "localhost" and port 5672.

    http://www.rabbitmq.com/javadoc/cons...AULT_AMQP_PORT

    Please upgrade to the latest version of Spring-AMQP (1.1.4).

    Comment


    • #3
      I am using Spring-AMQP 1.1.4. The Reference Manual, section "1.1.2 With XML Configuration" shows an example that does not work:

      http://static.springsource.org/sprin...our.html#d4e62

      It might work if you install RabbitMQ on the same machine you are developing on, but this does not reflect the normal scenario where RabbitMQ is hosted on a remote server.

      The examples in "2.2 Connection and Resource Management" are more thorough and include several variations, however the examples showing how to send messages in "2.4 Sending messages" do not show how to access the connection created.

      I have only successfully created a connection and sent messages using Java with annotations. I have not been able to get the XML configuration to work and the examples given don't work or are incomplete. Is there a more complete, simple example that shows how to initiate a connection with XML and send a message (or receive a message) using that connection?

      Comment


      • #4
        Sorry - when I saw 1.1.2, I assumed you meant you were using version 1.1.2.

        Anyway - most developers start with a local copy on their machine, but I do understand what you are saying.

        The whole point of using Spring-AMQP is to avoid you having to deal with low level connections and stuff - the RabbitTemplate provides an abstraction on top of that. Also the listener container is used for consuming messages and all you do is register a pojo. Again, this avoids you having to deal with the low-level APIs.

        As with many spring "template"s, the RabbitTemplate provides access to the low-level APIs (if you need them) using callbacks; such as

        Code:
        rabbitTemplate.execute(new ChannelCallback<Properties>() {
        			public Properties doInRabbit(Channel channel) throws Exception {
        ...
        The RabbitAdmin uses this technique in its getQueueProperties() method.

        However, this is fairly advanced and most normal use cases can be achieved using the high-level APIs to send and receive messages.

        There are a few sample apps here... https://github.com/SpringSource/spring-amqp-samples

        And for an even higher level abstraction, there is a Spring Integration sample here... https://github.com/garyrussell/sprin...ter/basic/amqp

        But, all these samples assume a local instance of RabbitMQ.

        To talk to a remote server, simply add host, port and user credentials to the connection factory - your IDE context assist should show you all the available attributes (host, port etc).

        Comment


        • #5
          I appreciate your help. I have looked through both of the examples you cited previously and spent weeks--not hours, but weeks--digging through them, running them and debugging them. The only thing I was able to accomplish from all that work was to create a connection using Java annotations. I have not been able to create and use a connection using XML. The spring-rabbit-stocks application is exceedingly complicated and very difficult to sort through, mixing both XML and Java-annotated configurations. It is not obvious which connection actually works and is being used by the publisher or listener on either the server or the client. And the examples in the documentation, as I pointed out, don't work except in the case where the RabbitMQ server is hosted on the same machine you are developing on--localhost--which is not a real world scenario.

          In contrast, when I first started working with RabbitMQ several months ago, I was able to quickly go through the tutorials on the RabbitMQ website and within an hour or two I was able to install the server and develop a Java application that connected to the server and published and received messages. Their examples where straightforward and easy to follow. The Spring-AMQP documentation and examples are unfortunately not so simple or straightforward.

          Of course Java web application development is considerably more difficult than writing a simple Java client application that publishes and receives messages, but it seems that the Spring-AMQP documentation and examples could be improved to make it easier to understand. My suggestion to help those of us who would like to use the libraries you have worked so hard to develop is:

          1. Document how to create a connection using inline Java (as you have), using a more complete example that also demonstrates a variation that shows how to make that connection without defaults (different host, user, password, etc.), and show how to use that connection to publish a message (direct, and using an exchange), and to listen for messages (binding a queue to an exchange).

          2. Document how to create a connection using XML <bean> definitions (as you have), using a more complete example that also demonstrates a variation that shows how to make that connection without defaults (different host, user, password, etc.), and show how to use that connection to publish a message (direct, and using an exchange), and to listen for messages (binding a queue to an exchange).

          3. Document how to create a connection using XML <rabbit:...> definitions (as you have), using a more complete example that also demonstrates a variation that shows how to make that connection without defaults (different host, user, password, etc.), and show how to use that connection to publish a message (direct, and using an exchange), and to listen for messages (binding a queue to an exchange).

          4. Document how to create a connection using Java annotations (as you have), using a more complete example that also demonstrates a variation that shows how to make that connection without defaults (different host, user, password, etc.), and show how to use that connection to publish a message (direct, and using an exchange), and to listen for messages (binding a queue to an exchange).

          Currently my XML definition looks like this (eventhub-server is a reverse proxy that forwards to a server called eventhub210):
          Code:
          	<rabbit:connection-factory id="connectionFactory" host="eventhub-server"
          							   username="guest" password="guest"
          							   channel-cache-size="5"/>
          
          	<bean id="jsonConverter" class="org.springframework.amqp.support.converter.JsonMessageConverter"/>
          
          	<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"
          					 message-converter="jsonConverter"/>
          
          	<rabbit:admin id="rabbitAdmin" connection-factory="connectionFactory"/>
          
          	<rabbit:topic-exchange id="eventExchange" name="eventsQueue" durable="true"/>
          When I load it on my Tomcat server I see this:
          Code:
          2013-04-07 15:21:57,315  INFO XmlWebApplicationContext Refreshing WebApplicationContext for namespace 'EventHub publish event-servlet': startup date [Sun Apr 07 15:21:57 MDT 2013]; root of context hierarchy
          
          2013-04-07 15:21:57,704  INFO RequestMappingHandlerMapping Mapped "{[/v1/status],methods=[GET],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public final java.lang.String eventhub.ws.publish.PublishEventController.testIt()
          
          2013-04-07 15:21:57,704  INFO RequestMappingHandlerMapping Mapped "{[/v1/rest],methods=[POST],params=[],headers=[],consumes=[application/json || application/xml],produces=[application/json || application/xml],custom=[]}" onto public eventhub.domain.EventType eventhub.ws.publish.PublishEventController.PublishRestEvent(eventhub.domain.EventType)
          
          2013-04-07 15:21:58,291  WARN CachingConnectionFactory Could not get host name, using 'localhost' as default value
          java.net.UnknownHostException: eventhub210: eventhub210
                  at java.net.InetAddress.getLocalHost(InetAddress.java:1360)
                  at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.getDefaultHostName(AbstractConnectionFactory.java:170)
                  at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.<init>(CachingConnectionFactory.java:89)
                  at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.<init>(CachingConnectionFactory.java:111)
                  at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.<init>(CachingConnectionFactory.java:76)
                  ....
          What am I missing?
          Last edited by Gary Russell; Apr 7th, 2013, 09:37 PM.

          Comment


          • #6
            There's something wrong with this picture. Line 170 in AbstractConnectionFactory is only invoked if no hostname is provided.

            I just ran a test with
            Code:
            <rabbit:connection-factory id="connectionFactory" host="10.0.0.13" port="5672"/>
            and everything worked just fine.

            java.net.UnknownHostException: eventhub210: eventhub210
            is thrown by

            Code:
            InetAddress localMachine = InetAddress.getLocalHost();

            Comment


            • #7
              Thank you for pointing that out. It was a problem with our DNS configuration for the server (or lack thereof) and the way ConnectionFactory resolves the server address. The reverse proxy name, eventhub-server, has a DNS entry that resolves to an IP address. ConnectionFactory is getting the actual server name, which in our case did not have an IP address associated with it. There are two ways to fix this: modify the hosts file on the server (eventhub210) to add the server name itself (rather than, or in addition to, the reverse proxy name), or add the server name to the DNS entries. I added it to the DNS entries and now it makes the connection.

              Comment

              Working...
              X