Re: Testing types in a message
On Fri, 2013-02-15 at 17:24 -0500, Rafael Schloming wrote: Couldn't you use map message the way Rob described in his later email to avoid having two? --Rafael On Fri, Feb 15, 2013 at 4:43 PM, Alan Conway acon...@redhat.com wrote: Another wrinkle in my type testing saga: Rob's DecoderImpl approach works in native java but not in JNI. Conversely the Data approach works in JNI but not in native. So it looks like I will write 2 tests. Can anybody tell me how to set up different junit tests to run based on the profile (-P proton-j vs. -P proton-jni) Thanks, Alan. I went with the Decoder approach for native Java and a Data object wrapped as a Decoder for JNI, so there's only one test.
Re: Testing types in a message
On Thu, Feb 14, 2013 at 5:44 PM, Alan Conway acon...@redhat.com wrote: I'm looking (in python first) to encode messages that contain all the different AMQP types. So far I was using the Data class to construct different AMQP data fragments. However I'd like to move towards using a map message as it's more widely decodable. So my question: how do I create a map message that contains specific AMQP types? I.e. I want to differentiate between shorts, ints and longs, between symbols and strings etc. Just setting message.body = Data(...) does not work, message wants to have a python dict or list as a body. For the python binding I've defined the following classes to cover types that python doesn't natively support: class UnmappedType class ulong(long) class timestamp(long) class symbol(unicode) class char(unicode) class Described(object) UNDESCRIBED = Constant(UNDESCRIBED) class Array(object) So you should just be able to do: message.body = {uulong: ulong(1234), uchar: char(u\u1234), utimestamp: timestamp(12345678), udescribed-string: Described(symbol(url-descriptor), uhttp://blah;), uarray: Array(UNDESCRIBED, Data.INT, 1, 2, 3, 4), udescribed-array: Array(symbol(url-descriptor), uhttp://blah1;, uhttp://blah2;)} --Rafael
Re: Testing types in a message
On Fri, 2013-02-15 at 09:12 -0500, Rafael Schloming wrote: On Thu, Feb 14, 2013 at 5:44 PM, Alan Conway acon...@redhat.com wrote: I'm looking (in python first) to encode messages that contain all the different AMQP types. So far I was using the Data class to construct different AMQP data fragments. However I'd like to move towards using a map message as it's more widely decodable. So my question: how do I create a map message that contains specific AMQP types? I.e. I want to differentiate between shorts, ints and longs, between symbols and strings etc. Just setting message.body = Data(...) does not work, message wants to have a python dict or list as a body. For the python binding I've defined the following classes to cover types that python doesn't natively support: class UnmappedType class ulong(long) class timestamp(long) class symbol(unicode) class char(unicode) class Described(object) UNDESCRIBED = Constant(UNDESCRIBED) class Array(object) So you should just be able to do: message.body = {uulong: ulong(1234), uchar: char(u\u1234), utimestamp: timestamp(12345678), udescribed-string: Described(symbol(url-descriptor), uhttp://blah;), uarray: Array(UNDESCRIBED, Data.INT, 1, 2, 3, 4), udescribed-array: Array(symbol(url-descriptor), uhttp://blah1;, uhttp://blah2;)} --Rafael I'm all good with the python binding. Now I'm trying to figure out what to do with Java (JNI and native), and soon with perl, php and ruby. For Java JNI I can use the Data object the same way I did in python, but Java native is a different story. In the jython test, all the codec test functions just throw unsupported-operation in the proton-j profile. proton_tests.codec.DataTest.testBinary .. skip ProtonUnsupportedOperationException: org.apache.qpid.proton.ProtonUnsupportedOperationException So I'm not sure how/if I can express AMQP types in proton-j. Cheers, Alan.
Re: Testing types in a message
Hi Alan, you can use the java Encoder/Decoders directly like this: import org.apache.qpid.proton.codec.EncoderImpl; import org.apache.qpid.proton.codec.DeccoderImpl; ... ByteBuffer buf = ByteBuffer.allocate(2048); DecoderImpl decoder = new DecoderImpl(); EncoderImpl encoder = new EncoderImpl(buf, decoder); // write an array of 12 (false) booleans boolean[] o = new boolean[12]; encoder.writeObject(o); // buf will now contain the encoded data, call flip() to move position to 0, // limit end of encoded data buf.flip(); // now read the encoded bytes decoder.setByteBuffer(buf); Object read = decoder.readObject(); ... Note that you need to set up both the encoder and the decoder even if you only wish to use one (they are sort of co-dependent in a horrible way that should be fixed some time). There are defined types for all of the AMQP types... Described types are a little more involved.. you can set the codec up to automatically convert to the right Java class for a given described type. -- Rob On 15 February 2013 16:42, Alan Conway acon...@redhat.com wrote: On Fri, 2013-02-15 at 09:12 -0500, Rafael Schloming wrote: On Thu, Feb 14, 2013 at 5:44 PM, Alan Conway acon...@redhat.com wrote: I'm looking (in python first) to encode messages that contain all the different AMQP types. So far I was using the Data class to construct different AMQP data fragments. However I'd like to move towards using a map message as it's more widely decodable. So my question: how do I create a map message that contains specific AMQP types? I.e. I want to differentiate between shorts, ints and longs, between symbols and strings etc. Just setting message.body = Data(...) does not work, message wants to have a python dict or list as a body. For the python binding I've defined the following classes to cover types that python doesn't natively support: class UnmappedType class ulong(long) class timestamp(long) class symbol(unicode) class char(unicode) class Described(object) UNDESCRIBED = Constant(UNDESCRIBED) class Array(object) So you should just be able to do: message.body = {uulong: ulong(1234), uchar: char(u\u1234), utimestamp: timestamp(12345678), udescribed-string: Described(symbol(url-descriptor), uhttp://blah;), uarray: Array(UNDESCRIBED, Data.INT, 1, 2, 3, 4), udescribed-array: Array(symbol(url-descriptor), uhttp://blah1;, uhttp://blah2;)} --Rafael I'm all good with the python binding. Now I'm trying to figure out what to do with Java (JNI and native), and soon with perl, php and ruby. For Java JNI I can use the Data object the same way I did in python, but Java native is a different story. In the jython test, all the codec test functions just throw unsupported-operation in the proton-j profile. proton_tests.codec.DataTest.testBinary .. skip ProtonUnsupportedOperationException: org.apache.qpid.proton.ProtonUnsupportedOperationException So I'm not sure how/if I can express AMQP types in proton-j. Cheers, Alan.
Re: Testing types in a message
Of course, if you are using the Message class then there's really no reason to go to the codec directly. you can just use Java Maps/Lists/Arrays etc, along with the Amqp specific types such as UnsignedLong. So you could have Message msg = MessageFactory.createMessage(); Map map = new LinkedHashMap(); map.put(Symbol.valueof(key), new boolean[12]); msg.setBody(new AmqpValue(map)); Which would set the body of the message to an AmqpValue section containing a map with a Symbolic key and a boolean array as a value. The above should work using either the JNI or pure Java implementation. -- Rob On 15 February 2013 17:03, Rob Godfrey rob.j.godf...@gmail.com wrote: Hi Alan, you can use the java Encoder/Decoders directly like this: import org.apache.qpid.proton.codec.EncoderImpl; import org.apache.qpid.proton.codec.DeccoderImpl; ... ByteBuffer buf = ByteBuffer.allocate(2048); DecoderImpl decoder = new DecoderImpl(); EncoderImpl encoder = new EncoderImpl(buf, decoder); // write an array of 12 (false) booleans boolean[] o = new boolean[12]; encoder.writeObject(o); // buf will now contain the encoded data, call flip() to move position to 0, // limit end of encoded data buf.flip(); // now read the encoded bytes decoder.setByteBuffer(buf); Object read = decoder.readObject(); ... Note that you need to set up both the encoder and the decoder even if you only wish to use one (they are sort of co-dependent in a horrible way that should be fixed some time). There are defined types for all of the AMQP types... Described types are a little more involved.. you can set the codec up to automatically convert to the right Java class for a given described type. -- Rob On 15 February 2013 16:42, Alan Conway acon...@redhat.com wrote: On Fri, 2013-02-15 at 09:12 -0500, Rafael Schloming wrote: On Thu, Feb 14, 2013 at 5:44 PM, Alan Conway acon...@redhat.com wrote: I'm looking (in python first) to encode messages that contain all the different AMQP types. So far I was using the Data class to construct different AMQP data fragments. However I'd like to move towards using a map message as it's more widely decodable. So my question: how do I create a map message that contains specific AMQP types? I.e. I want to differentiate between shorts, ints and longs, between symbols and strings etc. Just setting message.body = Data(...) does not work, message wants to have a python dict or list as a body. For the python binding I've defined the following classes to cover types that python doesn't natively support: class UnmappedType class ulong(long) class timestamp(long) class symbol(unicode) class char(unicode) class Described(object) UNDESCRIBED = Constant(UNDESCRIBED) class Array(object) So you should just be able to do: message.body = {uulong: ulong(1234), uchar: char(u\u1234), utimestamp: timestamp(12345678), udescribed-string: Described(symbol(url-descriptor), uhttp://blah;), uarray: Array(UNDESCRIBED, Data.INT, 1, 2, 3, 4), udescribed-array: Array(symbol(url-descriptor), uhttp://blah1;, uhttp://blah2;)} --Rafael I'm all good with the python binding. Now I'm trying to figure out what to do with Java (JNI and native), and soon with perl, php and ruby. For Java JNI I can use the Data object the same way I did in python, but Java native is a different story. In the jython test, all the codec test functions just throw unsupported-operation in the proton-j profile. proton_tests.codec.DataTest.testBinary .. skip ProtonUnsupportedOperationException: org.apache.qpid.proton.ProtonUnsupportedOperationException So I'm not sure how/if I can express AMQP types in proton-j. Cheers, Alan.
Re: Testing types in a message
On 15 February 2013 19:17, Alan Conway acon...@redhat.com wrote: On Fri, 2013-02-15 at 17:22 +0100, Rob Godfrey wrote: Of course, if you are using the Message class then there's really no reason to go to the codec directly. you can just use Java Maps/Lists/Arrays etc, along with the Amqp specific types such as UnsignedLong. So you could have Message msg = MessageFactory.createMessage(); Map map = new LinkedHashMap(); map.put(Symbol.valueof(key), new boolean[12]); msg.setBody(new AmqpValue(map)); Which would set the body of the message to an AmqpValue section containing a map with a Symbolic key and a boolean array as a value. Thanks Rob, this is great info. How would I do the converse using a Message? e.g. if decode a message with an AMQP list I see the Message.getBody() returns an AMQPValue. How do I convert that to I can iterate over? So you can call getValue() on the AmqpValue object, which will return the Java object representation of the AMQP object sent. In this case you would get some implementation of java.util.List, which you could then iterate over in the standard Java way. Object body = msg.getBody(); if(body instanceof AmqpValue) { Object valueObject = ((AmqpValue)body).getValue(); if(valueObject instanceof List) { for(Object element : (List) valueObject) { ... -- Rob The above should work using either the JNI or pure Java implementation. -- Rob On 15 February 2013 17:03, Rob Godfrey rob.j.godf...@gmail.com wrote: Hi Alan, you can use the java Encoder/Decoders directly like this: import org.apache.qpid.proton.codec.EncoderImpl; import org.apache.qpid.proton.codec.DeccoderImpl; ... ByteBuffer buf = ByteBuffer.allocate(2048); DecoderImpl decoder = new DecoderImpl(); EncoderImpl encoder = new EncoderImpl(buf, decoder); // write an array of 12 (false) booleans boolean[] o = new boolean[12]; encoder.writeObject(o); // buf will now contain the encoded data, call flip() to move position to 0, // limit end of encoded data buf.flip(); // now read the encoded bytes decoder.setByteBuffer(buf); Object read = decoder.readObject(); ... Note that you need to set up both the encoder and the decoder even if you only wish to use one (they are sort of co-dependent in a horrible way that should be fixed some time). There are defined types for all of the AMQP types... Described types are a little more involved.. you can set the codec up to automatically convert to the right Java class for a given described type. -- Rob On 15 February 2013 16:42, Alan Conway acon...@redhat.com wrote: On Fri, 2013-02-15 at 09:12 -0500, Rafael Schloming wrote: On Thu, Feb 14, 2013 at 5:44 PM, Alan Conway acon...@redhat.com wrote: I'm looking (in python first) to encode messages that contain all the different AMQP types. So far I was using the Data class to construct different AMQP data fragments. However I'd like to move towards using a map message as it's more widely decodable. So my question: how do I create a map message that contains specific AMQP types? I.e. I want to differentiate between shorts, ints and longs, between symbols and strings etc. Just setting message.body = Data(...) does not work, message wants to have a python dict or list as a body. For the python binding I've defined the following classes to cover types that python doesn't natively support: class UnmappedType class ulong(long) class timestamp(long) class symbol(unicode) class char(unicode) class Described(object) UNDESCRIBED = Constant(UNDESCRIBED) class Array(object) So you should just be able to do: message.body = {uulong: ulong(1234), uchar: char(u\u1234), utimestamp: timestamp(12345678), udescribed-string: Described(symbol(url-descriptor), uhttp://blah;), uarray: Array(UNDESCRIBED, Data.INT, 1, 2, 3, 4), udescribed-array: Array(symbol(url-descriptor), uhttp://blah1;, uhttp://blah2;)} --Rafael I'm all good with the python binding. Now I'm trying to figure out what to do with Java (JNI and native), and soon with perl, php and ruby. For Java JNI I can use the Data object the same way I did in python, but Java native is a different story. In the jython test, all the codec test functions just throw unsupported-operation in the proton-j profile. proton_tests.codec.DataTest.testBinary .. skip ProtonUnsupportedOperationException: org.apache.qpid.proton.ProtonUnsupportedOperationException So I'm not sure how/if I can express AMQP types in proton-j. Cheers, Alan.
Re: Testing types in a message
On Fri, 2013-02-15 at 16:00 -0500, Alan Conway wrote: On Fri, 2013-02-15 at 17:03 +0100, Rob Godfrey wrote: Hi Alan, you can use the java Encoder/Decoders directly like this: import org.apache.qpid.proton.codec.EncoderImpl; import org.apache.qpid.proton.codec.DeccoderImpl; ... ByteBuffer buf = ByteBuffer.allocate(2048); DecoderImpl decoder = new DecoderImpl(); EncoderImpl encoder = new EncoderImpl(buf, decoder); // write an array of 12 (false) booleans boolean[] o = new boolean[12]; encoder.writeObject(o); // buf will now contain the encoded data, call flip() to move position to 0, // limit end of encoded data buf.flip(); // now read the encoded bytes decoder.setByteBuffer(buf); Object read = decoder.readObject(); Having some trouble with this, I get a org.apache.qpid.proton.codec.DecodeException: Unknown constructor The value it is objecting to is decimal 65, 0x41, which is the constructor code for boolean true. Do I have to do something with DecoderImpl.register in order for its _constructors map to be populated? Never mind, found it: AmqpDefinedTypes.registerAllTypes
Re: Testing types in a message
Another wrinkle in my type testing saga: Rob's DecoderImpl approach works in native java but not in JNI. Conversely the Data approach works in JNI but not in native. So it looks like I will write 2 tests. Can anybody tell me how to set up different junit tests to run based on the profile (-P proton-j vs. -P proton-jni) Thanks, Alan.
Re: Testing types in a message
Couldn't you use map message the way Rob described in his later email to avoid having two? --Rafael On Fri, Feb 15, 2013 at 4:43 PM, Alan Conway acon...@redhat.com wrote: Another wrinkle in my type testing saga: Rob's DecoderImpl approach works in native java but not in JNI. Conversely the Data approach works in JNI but not in native. So it looks like I will write 2 tests. Can anybody tell me how to set up different junit tests to run based on the profile (-P proton-j vs. -P proton-jni) Thanks, Alan.