Re: Testing types in a message

2013-02-18 Thread Alan Conway
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

2013-02-15 Thread Rafael Schloming
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

2013-02-15 Thread Alan Conway
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

2013-02-15 Thread Rob Godfrey
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

2013-02-15 Thread Rob Godfrey
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

2013-02-15 Thread Rob Godfrey
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

2013-02-15 Thread Alan Conway
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

2013-02-15 Thread Alan Conway
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

2013-02-15 Thread Rafael Schloming
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.