通过Java客户端连接Azure服务总线

时间:2014-10-05 08:13:41

标签: java azure jndi amqp azureservicebus

我正在尝试将Java客户端的Azure服务总线与AMQP协议连接起来

我按照以下链接中的说明操作:
http://azure.microsoft.com/en-us/documentation/articles/service-bus-java-how-to-use-jms-api-amqp/

1)在Azure门户中创建了名称空间为“ availo ”的服务总线以及名为“ queue1 ”的队列 2)从服务总线连接信息我得到以下内容:

SharedAccessKeyName = RootManageSharedAccessKey
SharedAccessKey = {}键

3)为JNDI查找创建了“servicebus.properties”文件

   connectionfactory.SBCF = amqps://RootManageSharedAccessKey:encoded(key)@availo.servicebus.windows.net
   queue.QUEUE = queue1

4)下面是我的简单java主应用程序,在类路径中包含所有必需的jar(qpid)。

  public static void main(String[] args) {

    try {
        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.PROVIDER_URL,
                "C:\\Users\\Assaf-PC\\Documents\\GitHub\\availo\\rest-api\\src\\main\\resources\\servicebus.properties");
        Context context = new InitialContext(env);
        // Lookup ConnectionFactory and Queue
        ConnectionFactory cf = (ConnectionFactory) context.lookup("SBCF");
        Destination queue = (Destination) context.lookup("QUEUE");
        // Create Connection
        Connection connection = cf.createConnection();
        // Create sender-side Session and MessageProducer
        Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = sendSession.createProducer(queue);
    } catch (Exception e) {
        e.getLocalizedMessage();
    }

}

当我运行程序时,我在代码行中得到以下例外:

    MessageProducer producer = sendSession.createProducer(queue);

例外:

Exception in thread "main" javax.jms.JMSException: Peer did not create remote endpoint for link, target: queue1
at org.apache.qpid.amqp_1_0.jms.impl.MessageProducerImpl.<init>(MessageProducerImpl.java:98)
at org.apache.qpid.amqp_1_0.jms.impl.SessionImpl.createProducer(SessionImpl.java:390)
at org.apache.qpid.amqp_1_0.jms.impl.SessionImpl.createProducer(SessionImpl.java:59)
at availo.rest.services.ServiceBus.main(ServiceBus.java:43)
  Caused by: org.apache.qpid.amqp_1_0.client.Sender$SenderCreationException: Peer did not create    remote endpoint for link, target: queue1
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:191)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:119)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:112)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:98)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:84)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:78)
at org.apache.qpid.amqp_1_0.client.Session$1.<init>(Session.java:90)
at org.apache.qpid.amqp_1_0.client.Session.createSender(Session.java:89)
at org.apache.qpid.amqp_1_0.jms.impl.MessageProducerImpl.<init>(MessageProducerImpl.java:86)
... 3 more

如果没有成功,任何人都可以帮忙,浪费了很多时间来理解我做错了什么? 你的回答非常感谢。

4 个答案:

答案 0 :(得分:2)

确保您的队列未启用分区。 ServiceBus不支持具有分区队列的AMQP,但默认情况下会创建启用分区的队列。

我有这个完全相同的错误,并且未选中“启用分区”重新创建队列为我解决了这个问题。

请参阅本文底部的分区实体限制部分:https://msdn.microsoft.com/en-us/library/azure/dn520246.aspx

  

分区队列和主题仅可通过SBMP或HTTP / HTTPS使用。将来会增加AMQP支持。

答案 1 :(得分:1)

这个答案适用于像我这样的服务总线初学者。

第一件事就是为AMQP设置Unpartitioned队列/主题,因为其他答案说不支持分区。我们需要在从Azure Portal创建队列时取消选中“启用分区”。默认情况下,实体在服务总线中启用分区。

遇到这个问题,当我尝试使用Java客户端作为队列的侦听器时,我遇到了同样的问题,使用QQid实现JMS和AMQP,如example。问题是,即使ServiceBus位于Azure门户中,也未配置队列。

如果您计划使用不同的policyNames发送到/收听队列(请参阅this是否有帮助),请确保已使用正确的权限和策略名称在门户中为队列添加了正确的配置)。 “队列非服务总线”的策略名称是用于SAS身份验证的策略名称,相当于ACS中的用户名,主/辅助密钥等同于配置(servicebus.properties)文件中ACS的密码。

首先尝试使用主键。如果您收到身份验证错误,则可以尝试使用辅助密钥。如果密钥中有特殊字符,就像我转发斜杠(/)一样,用相应的UTF-8值替换它。所以我必须使用%2F来替换配置文件中的密钥/。

这清除了我的问题。希望这会有所帮助!!

<强> PTR(PointsToRemember):

  1. 建议不要像在当前用例中那样使用代码创建来用于AMQP。使用Service Bus Java API从代码创建队列时,会在启用分区的情况下创建队列,并且不会为该队列创建端点。所以,你最终会遇到两个例外,

    - 没有创建终点,如此上下文的问题。

    - 一旦你进入门户网站,在门户网站和配置文件中配置它,那么你就会得到'分区实体不支持AMQP'(你已经知道了!)。因此,您必须返回并在门户中再次创建队列,禁用分区并对其进行配置。一种双重工作..所以最好使用为AMQP创建和配置的队列。

  2. 如果主/辅助键中有特殊字符,则尝试重新生成它们,而不是使用它们并在配置文件中用相应的UTF-8替换特殊字符。

答案 2 :(得分:0)

据我所知,用户名/发布者名称不合适。

amqps://RootManageSharedAccessKey:encoded(key)@availo.servicebus.windows.net

应该是:

amqps://owner:encoded(key)@availo.servicebus.windows.net

因为来自amqp的用户名填充了sb端点的发布者名称,默认情况下是“所有者”(请使用你的天蓝色连接信息检查dbl)

希望这有帮助。

此致

答案 3 :(得分:0)

提示:使用更高版本的Qpid(qpid-jms-client-0.11.1.jar)时,connectionfactory属性不同:

connectionfactory.myFactoryLookup = connectionfactory.myFactoryLookup = amqps://example-open-bus.servicebus.windows.net?amqp.idleTimeout=150000&jms.username=somePolicy&jms.password=aM2k3PaZY5jdIkmGKm7G%2FcH%2BUFQaFAgHIYc3dSkuiLI%3D 

查看其他帖子 - &gt; How can I Send/Receive a message from Azure Service Bus from Qpid JMS (qpid-jms-client-0.11.1.jar)?