2012-08-06 65 views
0

我試圖使用.NET WMQ API通過.NET應用程序使用通過WebSphere MQ(WebSphere MQ Server v7)發送的JMS消息。我正在使用WebSphere MQ客戶端v7.5和amqmdnet.dll版本7.5.0.0。是否有可能在.NET WMQ API中讀取JMSDeliveryMode屬性?

閱讀JMSDeliveryMode屬性(Dlv屬性爲jms RFH2文件夾)時會出現一些非常奇怪的行爲。 JMS應用程序發送的屬性值(託管在WebSphere Application Server v7中的servlet)設置爲Persistent(2),但我的.NET客戶端始終讀取1(表示Non_persistent)。我需要閱讀正確的值,因爲我的.NET應用程序作爲路由器/轉發器工作,並且必須以正確的配置轉發消息。

我試着用RFHUtils來模擬JMS消息。當我將傳遞模式設置爲1並將其發送給我的.NET客戶端時,它將再次讀取1,但如果我還在MQMD中更改了MQ消息的持久性,它將讀取0.它看起來像JMSDeliveryMode中的值根本不使用,.NET客戶端總是從Persistence屬性讀取值,但這是不正確的行爲!這兩個屬性具有正確的值的不同範圍:

JMSDeliveryMode正確值(從jms.jar):

  • 1 - DeliveryMode.NON_PERSISTENT
  • 2 - DeliveryMode.PERSISTENT

Persistence正確的值(從amqmdnet.dll):

  • 0 - MQC.MQPER_NOT_PERSISTENT
  • 1 - MQC.MQPER_PERSISTENT
  • 2 - MQC.MQPER_PERSISTENCE_AS_Q_DEF/MQC.MQPER_PERSISTENCE_AS_TOPIC_DEF

回答

0

這又是IBM的amqmdnet.dll錯誤。與.NET Reflector拆卸庫和檢查負責讀取JMS屬性代碼(GetJmsPropertyMQMessage類的私有方法)後,我發現這一點:

if (name.Equals("JMSDeliveryMode")) 
{ 
    // Properties never contain the property with such name! 
    if (this.properties.ContainsKey("JMSDeliveryMode")) 
    { 
     ... 
    } 
    return this.Persistence; // Executes always 
} 

的問題是,properties集合從不包含任何財產與JMSDeliveryMode作爲重點。 properties集合包含格式爲的RFH2頭文件RFH2Folder.RFH2PropertyNameJMSDeliveryMode的正確屬性名稱是jms.Dlv!有趣的是GetJmsHeader方法讀取所有JMS屬性,而所有其他屬性在屬性集合中搜索時使用正確的RFH2名稱!

當我檢查逆向操作時,情況更糟 - 專用方法SetJmsPropertyMQMessage類。設置JMSDeliveryMode包含此代碼:

else if (name.Equals("JMSDeliveryMode")) 
{ 
    if (value is int) 
    { 
     int num2 = Convert.ToInt32(value); 
     switch (num2) 
     { 
      // Non persistent JMS message creates persistent MQ message 
      case 1: 
       this.Persistence = 1; 
       break; 
      // Invalid value for JMS delivery mode    
      case 0: 
       this.Persistence = 0; 
       break; 
      // Great if I try to create persistent JMS message I will 
      // get MQRC_PERSISTENCE_ERROR exception!    
      default: 
       base.throwNewMQException(2, 0x7ff); 
       break; 
     } 

     queue.Enqueue(num2); 
     // Correct RFH2 identifier is used 
     this.properties.Add("jms.Dlv", queue); 
    } 
    else 
    { 
     base.throwNewMQException(2, 0x9a9); 
    } 
} 

所以設置JMSDelivery模式要麼火異常或設置無效堅持!以下是重現此問題的小測試:

[Test] 
public void PutAndGetMessageWithDeliveryMode() { 
    using (MQQueue queue = _queueManager.AccessQueue(TestQueue, MQC.MQOO_OUTPUT | MQC.MQOO_INPUT_AS_Q_DEF)) { 

     MQMessage message = new MQMessage(); 
     message.SetInt4Property("JMSDeliveryMode", 2); 
     message.WriteString("some string"); 
     message.Format = MQC.MQFMT_STRING; 

     queue.Put(message); 

     MQMessage readMessage = new MQMessage(); 
     queue.Get(readMessage); 

     Assert.AreEqual(2, readMessage.GetInt4Property("JMSDeliveryMode")); 

     queue.Close(); 
    } 
} 
0

MQ中持久性的值。NET是正確的,您可以與cmqc.h頭文件進行比較,因爲amqmdnet和C MQI都是MQ本地API。

0 - MQC.MQPER_NOT_PERSISTENT 
1 - MQC.MQPER_PERSISTENT 
2 - MQC.MQPER_PERSISTENCE_AS_Q_DEF/MQC.MQPER_PERSISTENCE_AS_TOPIC_DEF 

jms.jar DeliveryMode枚舉定義了一個不同的值。我會想象MQ JMS實現將在內部適當地處理這個問題,並在MQMD和RFH2屬性中設置正確的MQ特定值。

關於您使用RFH2Util的測試。在MQMD選項卡和JMS中設置的值可能不同。您可以在JMS選項卡中將DeliveryMode設置爲1,並在MQMD選項卡中將Persistent Msg設置爲No。當放置消息時,MQMD.Persistence將顯示爲0,並且JMSDeliveryMode將顯示爲1.我通過在MQ Explorer中查看消息來確認此值。 MQ .NET API只是給你從消息中得到的東西。據我所知RFHUtil是一個設置RFH屬性的工具。它只是設置/獲取RFH屬性。它沒有MQ JMS實現的智能。

在我看來,「JMSxxxx」屬性最好由JMS實現來處理,而不是像MQ .NET這樣的本地實現。

+0

MQ .NET API不給我我在消息中得到的東西。它甚至不允許我發送正確的值。如果MQ.NET API是「本地」實現,它應該給我一個完整的控制。我不明白爲什麼高層(JMS)在傳輸層(MQ)中直接硬編碼的行爲。這應該在一些橋樑中單獨定義。 – 2012-08-06 18:28:49

相關問題