qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rajith Attapattu <rajit...@gmail.com>
Subject Re: JMS client skips string message properties
Date Wed, 21 Sep 2011 15:20:37 GMT
On Wed, Sep 21, 2011 at 11:09 AM, Fraser Adams
<fraser.adams@blueyonder.co.uk> wrote:
> Jiri/Rajith/Gordon,
> I'm getting *deeply* concerned by this thread.
>
> I've already raised pretty vigorously my views that interoperability should
> be the default position. It has been some time since I looked but I seem to
> recall reading that in AMQP "String" is defined as UTF-8 so that IMHO makes
> things pretty clear that the C++ etc. runtimes should be defaulting strings
> to UTF-8. i get the C++ "but strings are just byte arrays" thing, but to be
> fair from an interoperability perspective I tend to take the perspective
> that property types should be limited to a similar range to JMS. If binary
> properties have to be supported then that should be the exception case with
> a specific method call (preferably prefixed with nonInterop or somesuch)
> used to make it clear to clients that what they are doing could break
> things.
>
> That said I'm particularly concerned by Rajith's posting "
>
> The getPropertyNames() will not return properties who's values are not
> legal as per the JMS spec.
> If you have properties with types like list, map or UUID it will not
> show up in the list. However you could still retrieve them using
> getObjectProperty().
> Also if you print the message you will not see them.
>
> If you do a getStringProperty on  a byte[] it will throw an exception.
> If you do a getStringProperty on  a list or map it will just return
> you the toString()
> "
> I've got some sympathy with trying to keep to the JMS spec, but whilst there
> remain general interoperability issues this is a risky strategy (risky for
> product users) as you could well start to break things.
>
> As I've said in a previous post I've had to work around some things - in my
> case I'm doing a lot of QMF and most of the "strings" sent by the c++ broker
> ManagementAgent end up as byte[] values stored in a Map. However more
> significantly I've also had a couple of Agents including the sample Agent in
> "/qpid-0.10/cpp/bindings/qmf2/examples/cpp" send properties (e.g. qmf.opcode
> etc.) as byte[]
>
> I'm pretty worried that you're comment "If you do a getStringProperty on a
> byte[] it will throw an exception."

What do you think the correct behaviour should be in this case ?

> What I *actually* do is (within my MessageListener):
>           String agentName =
> QmfData.getString(message.getObjectProperty("qmf.agent"));
>           String content =
> QmfData.getString(message.getObjectProperty("qmf.content"));
>           String opcode =
> QmfData.getString(message.getObjectProperty("qmf.opcode"));
>
> Where QmfData.getString() includes my defensive type testing code covered in
> the thread below.
>
> This approach isn't ideal, but at least it works for 0.8 and 0.10
> pleeeeeaaaassssseee tell me that you've not "fixed" things such that I can't
> actually retrieve agent/content/opcode (they are a bit critical for QMF2 as
> I'm sure you know!!) - notice I'm using getObjectProperty not
> getStringProperty.

Maybe you misunderstood. Currently we throw an exception only if you
try to retrieve a byte[] as a String property.
Frankly it doesn't make sense, so an exception is reasonable.

However if you try to retrieve as an objectProperty it should work :)

> I've not had a chance to test with 0.12 yet as I've been trying hard to
> complete the Java QMF2 API implementation, but I shall be most upset if this
> fix to make things JMS pure has shot my code down in flames.
>
> I'm really interested in thoughts on this - and reassurance that you've not
> broken things for me, or what the new workaround is - I've already had to do
> some evil casting to Qpid specific types to get and set the content-type.
>
> Regards,
> Frase
>
>
>
> Jiri Krutil wrote:
>>
>> Rajith
>>
>> I think this makes perfect sense from the JMS point of view and it also
>> works fine if all peers are Java clients.
>>
>> What I find quite surprising and unfortunate is that if a C++ client sends
>> a
>> message to a Java client, the string message properties set by the C++
>> client are not visible by default for the Java client. (They only become
>> visible if the C++ client sets the property encoding to "utf8".)
>>
>> IMHO this should work by default, especially if both client libraries are
>> from the same vendor.
>> (Not sure if it would be better to make the C++ client use the utf8
>> encoding
>> by default, or to change the Java client to map byte[] properties to
>> Strings.)
>>
>> Regards
>> Jiri
>>
>>
>>
>> On Tue, Sep 20, 2011 at 5:29 PM, Rajith Attapattu
>> <rajith77@gmail.com>wrote:
>>
>>
>>>
>>> On Thu, Sep 15, 2011 at 2:34 PM, Fraser Adams
>>> <fraser.adams@blueyonder.co.uk> wrote:
>>>
>>>>
>>>> Hi Jiri
>>>> Out of curiosity have you looked at the type of the property. In other
>>>>
>>>
>>> words
>>>
>>>>
>>>> if you get the property and do a
>>>>
>>>
>>> myProperty.getClass().getCanonicalName().
>>>
>>>>
>>>> I'll bet that it'll come back as a byte array rather than a String. I
>>>> believe that if you have control of the C++ client you might be able to
>>>>
>>>
>>> set
>>>
>>>>
>>>> the encoding to UTF-8 but if not...
>>>>
>>>> I've seen this loads as I've been implementing a Java implementation of
>>>>
>>>
>>> the
>>>
>>>>
>>>> QMF2 API. Frankly it's a pain in the backside. I've resorted to
>>>> defensive
>>>> programming in my class that extracts String properties from headers and
>>>>
>>>
>>> Map
>>>
>>>>
>>>> messages as I've had some Agents send Strings and some byte[].
>>>>
>>>
>>> Fraser, this is fixed now from 0.12 release onwards.
>>> See https://issues.apache.org/jira/browse/QPID-2930 for details.
>>>
>>> The getPropertyNames() will not return properties who's values are not
>>> legal as per the JMS spec.
>>> If you have properties with types like list, map or UUID it will not
>>> show up in the list. However you could still retrieve them using
>>> getObjectProperty().
>>> Also if you print the message you will not see them.
>>>
>>> If you do a getStringProperty on  a byte[] it will throw an exception.
>>> If you do a getStringProperty on  a list or map it will just return
>>> you the toString() which is not useful IMO and for consistency we
>>> should throw an exception just like we do for byte[].
>>> For UUID at least it makes sense, and you will get a toString()
>>> representation of the UUID.
>>>
>>> We now allow some AMQP specific properties to be retrieved via the
>>> getStringProperty method using custom property names.
>>> Ex. app-id using "x-amqp-0-10.app-id"
>>>     routing-key using "x-amqp-0-10.routing-key"
>>>     userid using "JMSXUserID"
>>>
>>> Regards,
>>>
>>> Rajith
>>>
>>>>
>>>>  /**
>>>>   * There seem to be some inconsistencies where string properties are
>>>> sometimes returned as byte[] and
>>>>   * sometimes as Strings. It seems to vary depending on the Agent and
>>>> getting it wrong results in
>>>>   * ClassCastExceptions which is clearly unfortunate.
>>>>   *
>>>>   * This is basically a helper method to check the type of a property
>>>>
>>>
>>> and
>>>
>>>>
>>>> return the most "appropriate"
>>>>   * String representation for it.
>>>>   *
>>>>   * @param p a property in Object form
>>>>   * @return the most appropriate String representation of the property
>>>>   */
>>>>  public static String getString(Object p) {
>>>>      if (p == null) {
>>>>          return "";
>>>>      }
>>>>      if (p instanceof String) {
>>>>          return (String)p;
>>>>      }
>>>>      if (p instanceof byte[]) {
>>>>          return new String((byte[])p);
>>>>      }
>>>>      return p.toString();
>>>>  }
>>>>
>>>> My personal view is that the C++ client runtime should default to
>>>> sending
>>>> string properties as UTF-8 encoded as this makes the default behaviour
>>>> interoperable. There might be a small performance gain from not doing
>>>>
>>>
>>> that,
>>>
>>>>
>>>> but in an end to end system of systems I suspect the difference is very
>>>> small and worth paying for interoperability. One could always have a
>>>> flag
>>>>
>>>
>>> to
>>>
>>>>
>>>> switch off this behaviour, but I'd prefer Strings to be UTF-8 encoded as
>>>>
>>>
>>> a
>>>
>>>>
>>>> default (all IMHO of course).
>>>>
>>>> Hope this helps you out
>>>> Frase
>>>>
>>>>
>>>>
>>>> Jiri Krutil wrote:
>>>>
>>>>>
>>>>> Hi
>>>>>
>>>>> When sending messages from a C++ client and receiving them in a Java
>>>>> client,
>>>>> we are having problems with custom message properties in the message
>>>>> header.
>>>>> String message properties set on the C++ sender side are not visible
in
>>>>> the
>>>>> receiving Java app. Other property types seem to be processed fine.
>>>>>
>>>>> The C++ client is messaging v0.7, the Java client is 0.10.
>>>>>
>>>>> Any ideas?
>>>>>
>>>>> Cheers
>>>>> Jiri
>>>>>
>>>>>
>>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> Apache Qpid - AMQP Messaging Implementation
>>>> Project:      http://qpid.apache.org
>>>> Use/Interact: mailto:users-subscribe@qpid.apache.org
>>>>
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> Apache Qpid - AMQP Messaging Implementation
>>> Project:      http://qpid.apache.org
>>> Use/Interact: mailto:users-subscribe@qpid.apache.org
>>>
>>>
>>>
>>
>>
>
>
> ---------------------------------------------------------------------
> Apache Qpid - AMQP Messaging Implementation
> Project:      http://qpid.apache.org
> Use/Interact: mailto:users-subscribe@qpid.apache.org
>
>

---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:users-subscribe@qpid.apache.org


Mime
View raw message