none
Sample Service Bus Java AMQP example is failing.

    Question

  • Hi,

    I am beginner to Service Bus and AMQP. Trying to build and run sample code from https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-java-how-to-use-jms-api-amqp. Created servicebus.properties file as mentioned in page. The sample is bit outdated. For example the latest apache qpid amqp client library doesn't have PropertiesFileInitialContextFactory class. So I modified the source to use JmsInitialContextFactory as below.

    // Configure JNDI environment        
    Hashtable<String, String> env = new Hashtable<String, String>();        
    
    //env.put(Context.INITIAL_CONTEXT_FACTORY,                  "org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory");		
    env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory"); 
    env.put(Context.PROVIDER_URL, "servicebus.properties");        Context context = new InitialContext(env);

    No I am getting below error.

    javax.naming.NamingException: Exception while creating ConnectionFactory 'SBCF'. 
      [Root exception is java.lang.IllegalArgumentException: The supplied URI cannot contain a User-Info section]
        at org.apache.qpid.jms.jndi.JmsInitialContextFactory.createConnectionFactories(JmsInitialContextFactory.java:142)

    My servicebus.properties is as below.

    connectionfactory.SBCF = amqps://RootManageSharedAccessKey:6c**********%3D@tumatest.servicebus.windows.net
    queue.QUEUE = tumaqueue

    where "6c*******%3D" is Service bus namespace primary key of policy RootManageSharedAccessKey.

    Anybody knew what is going wrong here.


    Thursday, March 02, 2017 11:28 AM

Answers

  • Hi,

    Apologies for the document. These documents are being update for their stale info.

    Extra node: this is Qpid JMS which has AMQP support underneath. JMS and AMQP are 2 different things. If you want to have total control of AMQP, then you will need to use Qpid Proton-J. However, Azure service bus team is going to open source a new Java library in near future to help customers to use Azure Service Bus.

    below is a sample setting:

    few things:

    1. passing amqp.idleTimeout value > 120000. As service bus enforces timeout.

    2. instead of passing saspolicy and key with url, you could pass it when create connection to avoid url encode. (in case sas key as "/" in it)

    3. Set JMS ack mode to client ack

    4. Set message ack mode before acknowledging message. https://issues.apache.org/jira/browse/QPIDJMS-121

    this is how AMQP disposition translates to service bus operation.

    ACCEPTED = 1; -> Complete()
    REJECTED = 2; -> DeadLetter()

    RELEASED = 3; (just unlock the message in service bus, will then get redelivered)

    MODIFIED_FAILED = 4; -> Abandon() which increases delivery count

    MODIFIED_FAILED_UNDELIVERABLE = 5; -> Defer()

    // context hashtable
            Hashtable<String, String> hashtable = new Hashtable<>();
            hashtable.put("connectionfactory.SBCF", "amqps://[namespace].servicebus.windows.net?amqp.idleTimeout=120000");
            hashtable.put("queue.QUEUE", "queue");
    
            hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
            Context context = new InitialContext(hashtable);
    
            // Look up ConnectionFactory and Queue
            ConnectionFactory cf = (ConnectionFactory) context.lookup("SBCF");
            Destination queue = (Destination) context.lookup("QUEUE");
    
            // Create Connection
            connection = cf.createConnection("[saspolicy]", "[saskey]");
    
            //
            Session receiveSession = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
            MessageConsumer receiver = receiveSession.createConsumer(queue);
            receiver.setMessageListener(this);
    
    
            connection.setExceptionListener(new MyExceptionListener());
            connection.start();

    • Marked as answer by tumapath Thursday, March 16, 2017 3:03 AM
    Friday, March 03, 2017 3:11 PM

All replies

  • Hi,

    Apologies for the document. These documents are being update for their stale info.

    Extra node: this is Qpid JMS which has AMQP support underneath. JMS and AMQP are 2 different things. If you want to have total control of AMQP, then you will need to use Qpid Proton-J. However, Azure service bus team is going to open source a new Java library in near future to help customers to use Azure Service Bus.

    below is a sample setting:

    few things:

    1. passing amqp.idleTimeout value > 120000. As service bus enforces timeout.

    2. instead of passing saspolicy and key with url, you could pass it when create connection to avoid url encode. (in case sas key as "/" in it)

    3. Set JMS ack mode to client ack

    4. Set message ack mode before acknowledging message. https://issues.apache.org/jira/browse/QPIDJMS-121

    this is how AMQP disposition translates to service bus operation.

    ACCEPTED = 1; -> Complete()
    REJECTED = 2; -> DeadLetter()

    RELEASED = 3; (just unlock the message in service bus, will then get redelivered)

    MODIFIED_FAILED = 4; -> Abandon() which increases delivery count

    MODIFIED_FAILED_UNDELIVERABLE = 5; -> Defer()

    // context hashtable
            Hashtable<String, String> hashtable = new Hashtable<>();
            hashtable.put("connectionfactory.SBCF", "amqps://[namespace].servicebus.windows.net?amqp.idleTimeout=120000");
            hashtable.put("queue.QUEUE", "queue");
    
            hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
            Context context = new InitialContext(hashtable);
    
            // Look up ConnectionFactory and Queue
            ConnectionFactory cf = (ConnectionFactory) context.lookup("SBCF");
            Destination queue = (Destination) context.lookup("QUEUE");
    
            // Create Connection
            connection = cf.createConnection("[saspolicy]", "[saskey]");
    
            //
            Session receiveSession = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
            MessageConsumer receiver = receiveSession.createConsumer(queue);
            receiver.setMessageListener(this);
    
    
            connection.setExceptionListener(new MyExceptionListener());
            connection.start();

    • Marked as answer by tumapath Thursday, March 16, 2017 3:03 AM
    Friday, March 03, 2017 3:11 PM
  • Thanks, the only place where I could find the mapping between the ACK_TYPE / ack mode and the corresponding Azure service bus action.
    Thursday, March 30, 2017 9:02 AM