You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by "Darryl L. Pierce" <dp...@redhat.com> on 2011/07/11 14:43:06 UTC

Ruby APIs on top of Swig-generated code...

This patch set is a set of APIs that sit on top of the code generated by
the swig code generator. This code is provides a set of APIs that are,
hopefully, more intuitive to Ruby developers.


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


[PATCH 06/11] Created the Sender class and its unit tests.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

The class is packaged as follows:

Qpid::Messaging::Sender

A Sender can send a message.
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb         |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb  |   82 ++++++++++
 qpid/cpp/bindings/qpid/ruby/test/test_sender.rb |  183 +++++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb |    1 +
 4 files changed, 267 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/test_sender.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index b5ac578..b72747d 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -22,4 +22,5 @@ require 'qpid/duration'
 require 'qpid/address'
 require 'qpid/encoding'
 require 'qpid/message'
+require 'qpid/sender'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb
new file mode 100644
index 0000000..5d59c20
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb
@@ -0,0 +1,82 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+module Qpid
+
+  module Messaging
+
+    # Sender defines a type for sending messages.
+    class Sender
+
+      def initialize(sender_impl) # :nodoc:
+        @sender_impl = sender_impl
+      end
+
+      def sender_impl # :nodoc:
+        @sender_impl
+      end
+
+      # Sends a message.
+      def send(message, args = {})
+        block = args[:block] || false
+        @sender_impl.send message.message_impl, block
+      end
+
+      # Closes the sender.
+      def close; @sender_impl.close; end
+
+      # Returns the name for the sender.
+      def name; @sender_impl.getName; end
+
+      # Sets the capacity for the sender, which is the number of outgoing
+      # messages that can be held pending confirmation or receipt by
+      # the broker.
+      def capacity=(capacity); @sender_impl.setCapacity capacity; end
+
+      # Returns the capacity.
+      def capacity; @sender_impl.getCapacity; end
+
+      # Returns the number of messages sent that are pending receipt
+      # confirmation by the broker.
+      def unsettled; @sender_impl.getUnsettled; end
+
+      # Returns the available capacity for sending messages.
+      def available
+        @sender_impl.getAvailable
+      end
+
+      # Returns the Session for this sender.
+      def session; Qpid::Messaging::Session.new @sender_impl.getSession; end
+
+      # Returns if the underlying sender is valid.
+      def valid?; @sender_impl.isValid; end
+
+      # Returns if the underlying sender is null.
+      def null?; @sender_impl.isNull; end
+
+      def swap sender
+        @sender_impl.swap sender.sender_impl
+      end
+
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb b/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb
new file mode 100644
index 0000000..64348b9
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb
@@ -0,0 +1,183 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+require 'flexmock/test_unit'
+
+require 'qpid/sender'
+
+class TestSender < Test::Unit::TestCase
+
+  def setup
+    @messaging = flexmock(Qpid::Messaging)
+    @message = flexmock("message")
+
+    @session_impl = flexmock("session_impl")
+
+    @sender_impl = flexmock("sender_impl")
+    @other_sender_impl = flexmock("other_sender_impl")
+    @sender = Qpid::Messaging::Sender.new @sender_impl
+    @other_sender = flexmock("other_sender")
+  end
+
+  def test_send
+    message_impl = "message_impl"
+    content = {:foo => :bar}
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(message_impl)
+    @sender_impl.
+      should_receive(:send).
+      once.
+      with(message_impl, false)
+
+    @sender.send @message
+  end
+
+  def test_send_and_dont_block
+    message_impl = "message_impl"
+    content = {:foo => :bar}
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(message_impl)
+    @sender_impl.
+      should_receive(:send).
+      once.
+      with(message_impl, false)
+
+    @sender.send @message, :block => false
+  end
+
+  def test_send_and_block
+    message_impl = "message_impl"
+    content = {:foo => :bar}
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(message_impl)
+    @sender_impl.
+      should_receive(:send).
+      once.
+      with(message_impl, true)
+
+    @sender.send @message, :block => true
+  end
+
+  def test_close
+    @sender_impl.
+      should_receive(:close).
+      once
+
+    @sender.close
+  end
+
+  def test_set_capacity
+    @sender_impl.
+      should_receive(:setCapacity).
+      once.
+      with(17)
+
+    @sender.capacity = 17
+  end
+
+  def test_get_capacity
+    @sender_impl.
+      should_receive(:getCapacity).
+      once.
+      and_return(12)
+
+    assert_equal 12, @sender.capacity
+  end
+
+  def test_unsettled
+    @sender_impl.
+      should_receive(:getUnsettled).
+      once.
+      and_return(5)
+
+    assert_equal 5, @sender.unsettled
+  end
+
+  def test_available
+    @sender_impl.
+      should_receive(:getAvailable).
+      once.
+      and_return(15)
+
+    assert_equal 15, @sender.available
+  end
+
+  def test_name
+    @sender_impl.
+      should_receive(:getName).
+      once.
+      and_return("myname")
+
+    assert_equal "myname", @sender.name
+  end
+
+  def test_session
+    @sender_impl.
+      should_receive(:getSession).
+      once.
+      and_return(@session_impl)
+
+    result = @sender.session
+
+    assert_not_nil result
+    assert_same @session_impl, result.session_impl
+  end
+
+  def test_is_valid
+    @sender_impl.
+      should_receive(:isValid).
+      once.
+      and_return(true)
+
+    assert @sender.valid?
+  end
+
+  def test_is_null
+    @sender_impl.
+      should_receive(:isNull).
+      once.
+      and_return(false)
+
+    assert !@sender.null?
+  end
+
+  def test_swap
+    @other_sender.
+      should_receive(:sender_impl).
+      once.
+      and_return(@other_sender_impl)
+    @sender_impl.
+      should_receive(:swap).
+      once.
+      with(@other_sender_impl)
+
+    @sender.swap @other_sender
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
index 8139983..a58b10f 100644
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -23,4 +23,5 @@ require 'test/unit'
 require 'test_encoding'
 require 'test_address'
 require 'test_message'
+require 'test_sender'
 
-- 
1.7.6


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


[PATCH 03/11] Created the encode and decode methods in Qpid::Messaging.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

These methods differ from the same methods in Cqpid in that they handle
working with symbols and other non-string values.
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb           |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb  |   56 ++++++++
 qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb |  146 +++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb   |    1 +
 4 files changed, 204 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index 597446d..725fa45 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -19,4 +19,5 @@
 
 require 'qpid/errors'
 require 'qpid/duration'
+require 'qpid/encoding'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb
new file mode 100644
index 0000000..c8b843b
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb
@@ -0,0 +1,56 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'cqpid'
+
+module Qpid
+
+  module Messaging
+
+    # Encodes the supplied content into the given message.
+    def self.encode content, message, encoding = nil
+      prepared = content
+      case content
+      when Hash
+        prepared = {}
+        content.each_pair do |key,value|
+          prepared[key.to_s] = value.to_s
+        end
+        Cqpid::encode prepared, message.message_impl
+      when Array
+        prepared = []
+        content.each {|value| prepared << value.to_s}
+        Cqpid::encode prepared, message.message_impl
+      end
+    end
+
+    # Decodes and returns the message's content.
+    def self.decode(message, content_type = nil)
+      content_type = message.content_type unless content_type
+
+      case content_type
+        when "amqp/map":  Cqpid.decodeMap message.message_impl
+        when "amqp/list": Cqpid.decodeList message.message_impl
+      end
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb b/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb
new file mode 100644
index 0000000..060975a
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb
@@ -0,0 +1,146 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+require 'flexmock/test_unit'
+
+require 'cqpid'
+require 'qpid/encoding'
+
+class TestEncoding < Test::Unit::TestCase
+
+  def setup
+    @cqpid = flexmock(Cqpid)
+
+    @message = flexmock("message")
+    @message_impl = flexmock("message_impl")
+
+    @encoded = {"foo" => "bar"}
+  end
+
+  def test_encode_map_with_symbols
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @cqpid.
+      should_receive(:encode).
+      once.
+      with({"foo" => "bar"}, @message_impl).
+      and_return(@encoded)
+
+    result = Qpid::Messaging.encode({:foo => :bar}, @message)
+
+    assert_same @encoded, result
+  end
+
+  def test_encode_list_with_symbols
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @cqpid.
+      should_receive(:encode).
+      once.
+      with(["foo", "bar"], @message_impl).
+      and_return(@encoded)
+
+    result = Qpid::Messaging.encode([:foo, :bar], @message)
+
+    assert_same @encoded, result
+  end
+
+  def test_encode_with_content_type
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @cqpid.
+      should_receive(:encode).
+      once.
+      with({"foo" => "bar"}, @message_impl).
+      and_return(@encoded)
+
+    result = Qpid::Messaging.encode({:foo => :bar}, @message)
+
+    assert_same @encoded, result
+  end
+
+  def test_encode
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @cqpid.
+      should_receive(:encode).
+      once.
+      with({"foo" => "bar"}, @message_impl).
+      and_return(@encoded)
+
+    result = Qpid::Messaging.encode({"foo" => "bar"}, @message)
+
+    assert_same @encoded, result
+  end
+
+  def test_decode_for_map
+    decoded = {"foo" => "bar"}
+    @message.
+      should_receive(:content_type).
+      once.
+      and_return("amqp/map")
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @cqpid.
+      should_receive(:decodeMap).
+      once.
+      with(@message_impl).
+      and_return(decoded)
+
+    result = Qpid::Messaging.decode(@message)
+
+    assert_same decoded, result
+  end
+
+  def test_decode_for_list
+    decoded = ["foo", "bar"]
+    @message.
+      should_receive(:content_type).
+      once.
+      and_return("amqp/list")
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @cqpid.
+      should_receive(:decodeList).
+      once.
+      with(@message_impl).
+      and_return(decoded)
+
+    result = Qpid::Messaging.decode(@message)
+
+    assert_same decoded, result
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
index f5b7384..68af267 100644
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -20,4 +20,5 @@
 $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
 
 require 'test/unit'
+require 'test_encoding'
 
-- 
1.7.6


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


[PATCH 01/11] Created the Qpid Ruby libraries.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

The libraries provide a more Ruby-esque way of using the Qpid libraries
that are generated via SWIG.
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb         |   21 +++++++++++++++
 qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb  |   30 ++++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb |   31 +++++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb |   23 +++++++++++++++++
 4 files changed, 105 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
new file mode 100644
index 0000000..2cf0788
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'qpid/errors'
+
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb
new file mode 100644
index 0000000..7a16d08
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+module Qpid
+
+  module Messaging
+
+    class KeyError < RuntimeError
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb
new file mode 100644
index 0000000..a791b16
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb
@@ -0,0 +1,31 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+module Qpid
+
+  module Version
+
+    NUMBERS = [MAJOR = 0,
+               MINOR = 10,
+               BUILD = 0]
+  end
+
+  VERSION = Version::NUMBERS.join('.')
+
+end
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
new file mode 100644
index 0000000..f5b7384
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+
-- 
1.7.6


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


[PATCH 08/11] Created the Session class and its unit tests.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

The Session class is packaged as follows:

Qpid::Messaging::Session

A Session can create a Sender or a Receiver endpoint.
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb          |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb  |  186 +++++++++
 qpid/cpp/bindings/qpid/ruby/test/test_session.rb |  445 ++++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb  |    1 +
 4 files changed, 633 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/test_session.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index 3edb65c..65e6393 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -24,4 +24,5 @@ require 'qpid/encoding'
 require 'qpid/message'
 require 'qpid/sender'
 require 'qpid/receiver'
+require 'qpid/session'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb
new file mode 100644
index 0000000..543c26c
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb
@@ -0,0 +1,186 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'cqpid'
+
+require 'qpid/errors'
+
+module Qpid
+
+  module Messaging
+
+    # A Session represents a distinct conversation between end points.
+    class Session
+
+      def initialize(session) # :nodoc:
+        @session_impl = session
+      end
+
+      def session_impl # :nodoc:
+        @session_impl
+      end
+
+      # Returns the +Connection+ for the +Session+.
+      def connection
+        connection_impl = @session_impl.getConnection
+        Qpid::Messaging::Connection.new "", {}, connection_impl
+      end
+
+      # Creates a new endpoint for sending messages.
+      def create_sender(address)
+        _address = address
+
+        if address.class == Qpid::Messaging::Address
+          _address = address.address_impl
+        end
+
+        Qpid::Messaging::Sender.new(@session_impl.createSender(_address))
+      end
+
+      # Retrieves the +Sender+ with the specified name.
+      def sender(name)
+        result = nil
+
+        begin
+          sender_impl = @session_impl.getSender name
+          result = Sender.for_impl sender_impl
+        rescue
+          # treat any error as a key error
+        end
+
+        raise Qpid::Messaging::KeyError, "No such sender: #{name}" if result.nil?
+        result
+      end
+
+      # Retrieves the +Receiver+ with the specified name.
+      def receiver(name)
+        result = nil
+
+        begin
+          receiver_impl = @session_impl.getReceiver name
+          result = Receiver.for_impl receiver_impl
+        rescue
+          # treat any error as a key error
+        end
+
+        raise Qpid::Messaging::KeyError, "No such receiver: #{name}" if result.nil?
+        result
+      end
+
+      # Creates a new endpoint for receiving messages.
+      def create_receiver(address)
+        result = nil
+
+        if address.class == Qpid::Messaging::Address
+          address_impl = address.address_impl
+          result = Qpid::Messaging::Receiver.new(@session_impl.createReceiver(address_impl))
+        else
+          result = Qpid::Messaging::Receiver.new(@session_impl.createReceiver(address))
+        end
+
+        return result
+      end
+
+      # Closes the Session and all associated Senders and Receivers.
+      # All Sessions are closed when the associated Connection is closed.
+      def close; @session_impl.close; end
+
+      # Commits any pending transactions for a transactional session.
+      def commit; @session_impl.commit; end
+
+      # Rolls back any uncommitted transactions on a transactional session.
+      def rollback; @session_impl.rollback; end
+
+      # Acknowledges one or more outstanding messages that have been received
+      # on this session.
+      #
+      # If a message is submitted (:message => something_message) then only
+      # that message is acknowledged. Otherwise all messsages are acknowledged.
+      #
+      # If :sync => true then the call will block until the server completes
+      # processing the acknowledgements.
+      # If :sync => true then the call will block until processed by the server (def. false)
+      def acknowledge(args = {})
+        sync = args[:sync] || false
+        message = args[:message] if args[:message]
+
+        unless message.nil?
+          @session_impl.acknowledge message.message_impl, sync
+        else
+          @session_impl.acknowledge sync
+        end
+      end
+
+      # Rejects the specified message. A rejected message will not be redelivered.
+      #
+      # NOTE: A message cannot be rejected once it has been acknowledged.
+      def reject(message); @session_impl.reject message.message_impl; end
+
+      # Releases the message, which allows the broker to attempt to
+      # redeliver it.
+      #
+      # NOTE: A message connot be released once it has been acknowled.
+      def release(message); @session_impl.release message.message_impl; end
+
+      # Requests synchronization with the server.
+      #
+      # If :block => true then the call will block until the server acknowledges.
+      #
+      # If :block => false (default) then the call will complete and the server
+      # will send notification on completion.
+      def sync(args = {})
+        block = args[:block] || false
+        @session_impl.sync block
+      end
+
+      # Returns the total number of receivable messages, and messages already received,
+      # by Receivers associated with this session.
+      def receivable; @session_impl.getReceivable; end
+
+      # Returns the number of messages that have been acknowledged by this session
+      # whose acknowledgements have not been confirmed as processed by the server.
+      def unsettled_acks; @session_impl.getUnsettledAcks; end
+
+      # Fetches the receiver for the next message.
+      def next_receiver(timeout = Qpid::Messaging::Duration::FOREVER)
+        receiver_impl = @session_impl.nextReceiver(timeout.duration_impl)
+        Qpid::Messaging::Receiver.new receiver_impl
+      end
+
+      # Returns whether there are errors on this session.
+      def error?; @session_impl.hasError; end
+
+      def check_error; @session_impl.checkError; end
+
+      # Returns if the underlying session is valid.
+      def valid?; @session_impl.isValid; end
+
+      # Returns if the underlying session is null.
+      def null?; @session_impl.isNull; end
+
+      def swap session
+        @session_impl.swap session.session_impl
+      end
+
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_session.rb b/qpid/cpp/bindings/qpid/ruby/test/test_session.rb
new file mode 100644
index 0000000..20f0559
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/test_session.rb
@@ -0,0 +1,445 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+require 'flexmock/test_unit'
+
+require 'qpid/errors'
+require 'qpid/duration'
+require 'qpid/session'
+
+class TestSession < Test::Unit::TestCase
+
+  def setup
+    @session_impl = flexmock("session_impl")
+    @other_session = flexmock("other_session")
+    @other_session_impl = flexmock("other_session_impl")
+    @sender = flexmock("sender")
+
+    @Connection_class = flexmock(Qpid::Messaging::Connection)
+    @connection_impl = flexmock("connection_impl")
+    @connection = flexmock("connection")
+
+    @Receiver_class = flexmock(Qpid::Messaging::Receiver)
+    @receiver = flexmock("receiver")
+    @receiver_impl = flexmock("receiver_impl")
+
+    @address = flexmock("address")
+    @address_impl = flexmock("address_impl")
+
+    @Sender_class = flexmock(Qpid::Messaging::Sender)
+    @sender = flexmock("sender")
+    @sender_impl = flexmock("sender_impl")
+
+    @message = flexmock("message")
+    @message_impl = flexmock("message_impl")
+
+    @duration = flexmock("duration")
+    @duration_impl = flexmock("duration_impl")
+
+    @session = Qpid::Messaging::Session.new(@session_impl)
+  end
+
+  def test_create_sender_with_Address
+    @address.
+      should_receive(:class).
+      once.
+      and_return(Qpid::Messaging::Address).
+      should_receive(:address_impl).
+      once.
+      and_return(@address_impl)
+    @session_impl.
+      should_receive(:createSender).
+      once.
+      with(@address_impl).
+      and_return(@sender_impl)
+
+    result = @session.create_sender @address
+
+    assert_not_nil result
+  end
+
+  def test_create_sender
+    @session_impl.
+      should_receive(:createSender).
+      once.
+      with_any_args.
+      and_return(@sender_impl)
+
+    result = @session.create_sender("my-queue")
+
+    assert_not_nil result
+  end
+
+  def test_create_sender_with_address_string
+    @session_impl.
+      should_receive(:createSender).
+      once.
+      with("my-queue;{create:always}").
+      and_return(@sender_impl)
+
+    result = @session.create_sender "my-queue;{create:always}"
+
+    assert_same @sender_impl, result.sender_impl
+  end
+
+  def test_create_receiver
+    @address.
+      should_receive(:class).
+      once.
+      and_return(Qpid::Messaging::Address).
+      should_receive(:address_impl).
+      once.
+      and_return(@address_impl)
+    @session_impl.
+      should_receive(:createReceiver).
+      once.
+      with(@address_impl).
+      and_return(@receiver_impl)
+
+    result = @session.create_receiver(@address)
+
+    assert_equal @receiver_impl, result.receiver_impl
+  end
+
+  def test_create_receiver_with_address_string
+    @session_impl.
+      should_receive(:createReceiver).
+      once.
+      with("my-queue").
+      and_return(@receiver_impl)
+
+    result = @session.create_receiver("my-queue")
+
+    assert_same @receiver_impl, result.receiver_impl
+  end
+
+  def test_close
+    @session_impl.
+      should_receive(:close).
+      once
+
+    @session.close
+  end
+
+  def test_commit
+    @session_impl.
+      should_receive(:commit).
+      once
+
+    @session.commit
+  end
+
+  def test_rollback
+    @session_impl.
+      should_receive(:rollback).
+      once
+
+    @session.rollback
+  end
+
+  def test_acknowledge_with_no_args
+    @session_impl.
+      should_receive(:acknowledge).
+      once.
+      with(false)
+
+    @session.acknowledge
+  end
+
+  def test_acknowledge_and_sync
+    @session_impl.
+      should_receive(:acknowledge).
+      once.
+      with(true)
+
+    @session.acknowledge :sync => true
+  end
+
+  def test_acknowledge_and_dont_sync
+    @session_impl.
+      should_receive(:acknowledge).
+      once.
+      with(false)
+
+    @session.acknowledge :sync => false
+  end
+
+  def test_acknowledge_message_without_sync
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @session_impl.
+      should_receive(:acknowledge).
+      once.
+      with(@message_impl, false)
+
+    @session.acknowledge :message => @message
+  end
+
+  def test_acknowledge_message_and_sync
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @session_impl.
+      should_receive(:acknowledge).
+      once.
+      with(@message_impl, true)
+
+    @session.acknowledge :message => @message, :sync => true
+  end
+
+  def test_acknowledge_message_and_dont_sync
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @session_impl.
+      should_receive(:acknowledge).
+      once.
+      with(@message_impl, false)
+
+    @session.acknowledge :message => @message, :sync => false
+  end
+
+  def test_reject_message
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @session_impl.
+      should_receive(:reject).
+      once.
+      with(@message_impl)
+
+    @session.reject @message
+  end
+
+  def test_release_message
+    @message.
+      should_receive(:message_impl).
+      once.
+      and_return(@message_impl)
+    @session_impl.
+      should_receive(:release).
+      once.
+      with(@message_impl)
+
+    @session.release @message
+  end
+
+  def test_sync_without_block
+    @session_impl.
+      should_receive(:sync).
+      once
+
+    @session.sync
+  end
+
+  def test_sync_and_block
+    @session_impl.
+      should_receive(:sync).
+      once.
+      with(true)
+
+    @session.sync :block => true
+  end
+
+  def test_sync_and_dont_block
+    @session_impl.
+      should_receive(:sync).
+      once.
+      with(false)
+
+    @session.sync :block => false
+  end
+
+  def test_receivable
+    @session_impl.
+      should_receive(:getReceivable).
+      once.
+      and_return(5)
+
+    assert_equal 5, @session.receivable
+  end
+
+  def test_unsettled_acks
+    @session_impl.
+      should_receive(:getUnsettledAcks).
+      once.
+      and_return(17)
+
+    assert_equal 17, @session.unsettled_acks
+  end
+
+  def test_next_receiver_with_no_duration
+    @session_impl.
+      should_receive(:nextReceiver).
+      once.
+      with(Qpid::Messaging::Duration::FOREVER.duration_impl).
+      and_return(@receiver_impl)
+
+    result = @session.next_receiver
+
+    assert_same @receiver_impl, result.receiver_impl
+  end
+
+  def test_next_receiver_with_duration
+    @duration.
+      should_receive(:duration_impl).
+      once.
+      and_return(@duration_impl)
+    @session_impl.
+      should_receive(:nextReceiver).
+      once.
+      with(@duration_impl).
+      and_return(@receiver_impl)
+
+    result = @session.next_receiver @duration
+
+    assert_same @receiver_impl, result.receiver_impl
+  end
+
+  def test_sender
+    @session_impl.
+      should_receive(:getSender).
+      once.
+      with("farkle").
+      and_return(@sender_impl)
+    @Sender_class.
+      should_receive(:for_impl).
+      once.
+      with(@sender_impl).
+      and_return(@sender)
+
+    result = @session.sender "farkle"
+
+    assert_same @sender, result
+  end
+
+  def test_sender_with_invalid_name
+    @session_impl.
+      should_receive(:getSender).
+      once.
+      with("farkle").
+      and_throw(RuntimeError)
+
+    assert_raise(Qpid::Messaging::KeyError) {@session.sender "farkle"}
+  end
+
+  def test_receiver
+    @session_impl.
+      should_receive(:getReceiver).
+      once.
+      with("farkle").
+      and_return(@receiver_impl)
+    @Receiver_class.
+      should_receive(:for_impl).
+      once.
+      with(@receiver_impl).
+      and_return(@receiver)
+
+    result = @session.receiver "farkle"
+
+    assert_same @receiver, result
+  end
+
+  def test_receiver_with_invalid_name
+    @session_impl.
+      should_receive(:getReceiver).
+      once.
+      with("farkle").
+      and_throw(RuntimeError)
+
+    assert_raise(Qpid::Messaging::KeyError) {@session.receiver "farkle"}
+  end
+
+  def test_connection
+    @session_impl.
+      should_receive(:getConnection).
+      once.
+      and_return(@connection_impl)
+
+    result = @session.connection
+
+    assert_same @connection_impl, result.connection_impl
+  end
+
+  def test_error_with_none
+    @session_impl.
+      should_receive(:hasError).
+      once.
+      and_return(false)
+
+    assert !@session.error?
+  end
+
+  def test_error
+    @session_impl.
+      should_receive(:hasError).
+      once.
+      and_return(true)
+
+    assert @session.error?
+  end
+
+  def test_check_error
+    @session_impl.
+      should_receive(:checkError).
+      once
+
+    @session.check_error
+  end
+
+  def test_is_valid
+    @session_impl.
+      should_receive(:isValid).
+      once.
+      and_return(false)
+
+    assert !@session.valid?
+  end
+
+  def test_is_null
+    @session_impl.
+      should_receive(:isNull).
+      once.
+      and_return(false)
+
+    assert !@session.null?
+  end
+
+  def test_swap
+    @other_session.
+      should_receive(:session_impl).
+      once.
+      and_return(@other_session_impl)
+    @session_impl.
+      should_receive(:swap).
+      once.
+      with(@other_session_impl)
+
+    @session.swap @other_session
+  end
+
+end
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
index 549e268..4d3b906 100644
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -25,4 +25,5 @@ require 'test_address'
 require 'test_message'
 require 'test_sender'
 require 'test_receiver'
+require 'test_session'
 
-- 
1.7.6


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


[PATCH 07/11] Created the Receiver class and its unit tests.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

The class is packaged as follows:

Qpid::Messaging::Receiver
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb           |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb  |  102 +++++++++
 qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb |  238 +++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb   |    1 +
 4 files changed, 342 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index b72747d..3edb65c 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -23,4 +23,5 @@ require 'qpid/address'
 require 'qpid/encoding'
 require 'qpid/message'
 require 'qpid/sender'
+require 'qpid/receiver'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb
new file mode 100644
index 0000000..d498aa9
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb
@@ -0,0 +1,102 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'cqpid'
+
+require 'qpid/duration'
+
+module Qpid
+
+  module Messaging
+
+    # Receiver defines a type for receiving messages.
+    class Receiver
+
+      def initialize(receiver_impl) # :nodoc:
+        @receiver_impl = receiver_impl
+      end
+
+      def receiver_impl # :nodoc:
+        @receiver_impl
+      end
+
+      # Retrieves a message from the receiver's local queue, or waits
+      # for up to the duration specified for one to become available.
+      def get(duration = Qpid::Messaging::Duration::FOREVER)
+        message_impl = @receiver_impl.get duration.duration_impl
+        create_message_wrapper message_impl unless message_impl.nil?
+      end
+
+      # Retrieves a message from the receiver's subscription, or waits
+      # for up to the duration specified for one to become available.
+      def fetch(duration = Qpid::Messaging::Duration::FOREVER)
+        message_impl = @receiver_impl.fetch duration.duration_impl
+        create_message_wrapper message_impl unless message_impl.nil?
+      end
+
+      # Sets the capacity.
+      #
+      # The capacity for a receiver determines the number of messages that
+      # can be held in the receiver before being fetched.
+      def capacity=(capacity); @receiver_impl.setCapacity capacity; end
+
+      # Returns the capacity.
+      def capacity; @receiver_impl.getCapacity; end
+
+      # Returns the number of available messages waiting to be fetched.
+      def available; @receiver_impl.getAvailable; end
+
+      # Returns the number of messages that have been received and acknowledged
+      # but whose acknowledgements have not been confirmed by the sender.
+      def unsettled; @receiver_impl.getUnsettled; end
+
+      # Cancels the reciever.
+      def close; @receiver_impl.close; end
+
+      # Returns whether the receiver is closed.
+      def closed?; @receiver_impl.isClosed; end
+
+      # Returns the name of the receiver
+      def name; @receiver_impl.getName; end
+
+      # Returns the Session for this receiver.
+      def session; Qpid::Messaging::Session.new(@receiver_impl.getSession); end
+
+      # Returns whether the underlying handle is valid.
+      def valid?; @receiver_impl.isValid; end
+
+      # Returns whether the underlying handle is null.
+      def null?; @receiver_impl.isNull; end
+
+      def swap receiver
+        @receiver_impl.swap receiver.receiver_impl
+      end
+
+      private
+
+      def create_message_wrapper message_impl
+        Qpid::Messaging::Message.new({}, message_impl)
+      end
+
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb b/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb
new file mode 100644
index 0000000..61a4db1
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb
@@ -0,0 +1,238 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+require 'flexmock/test_unit'
+
+require 'qpid/receiver'
+
+class TestReceiver < Test::Unit::TestCase
+
+  def setup
+    @session_impl = flexmock("session")
+
+    @Message_class = flexmock(Qpid::Messaging::Message)
+    @Messaging_module = flexmock(Qpid::Messaging)
+    @message_impl = flexmock("message_impl")
+    @message = flexmock("message")
+
+    @receiver_impl       = flexmock("receiver")
+    @other_receiver      = flexmock("other_receiver")
+    @other_receiver_impl = flexmock("other_receiver_impl")
+    @receiver            = Qpid::Messaging::Receiver.new @receiver_impl
+  end
+
+  def test_receiver_impl
+    assert_same @receiver_impl, @receiver.receiver_impl
+  end
+
+  def test_get
+    @receiver_impl.
+      should_receive(:get).
+      once.
+      with_any_args.
+      and_return(@message_impl)
+
+    result = @receiver.get
+
+    assert_not_nil result
+    assert_same @message_impl, result.message_impl
+  end
+
+  def test_get_with_duration
+    @receiver_impl.
+      should_receive(:get).
+      once.
+      with_any_args.
+      and_return(@message_impl)
+
+    result = @receiver.get Qpid::Messaging::Duration::MINUTE
+
+    assert_not_nil result
+    assert_same @message_impl, result.message_impl
+  end
+
+  def test_get_with_no_message_received
+    @receiver_impl.
+      should_receive(:get).
+      once.
+      with_any_args.
+      and_return(nil)
+
+    result = @receiver.get Qpid::Messaging::Duration::SECOND
+
+    assert_nil result
+  end
+
+  def test_fetch
+   @receiver_impl.
+      should_receive(:fetch).
+      once.
+      with_any_args.
+      and_return(@message_impl)
+
+    result = @receiver.fetch
+
+    assert_not_nil result
+    assert_same @message_impl, result.message_impl
+  end
+
+  def test_fetch_with_duration
+    @receiver_impl.
+      should_receive(:fetch).
+      once.
+      with_any_args.
+      and_return(@message_impl)
+
+    result = @receiver.fetch Qpid::Messaging::Duration::MINUTE
+
+    assert_not_nil result
+    assert_same @message_impl, result.message_impl
+  end
+
+  def test_fetch_with_no_message_received
+    @receiver_impl.
+      should_receive(:fetch).
+      once.
+      with_any_args.
+      and_return(nil)
+
+    result = @receiver.fetch Qpid::Messaging::Duration::SECOND
+
+    assert_nil result
+  end
+
+  def test_set_capacity
+    @receiver_impl.
+      should_receive(:setCapacity).
+      once.
+      with(15)
+
+    @receiver.capacity = 15
+  end
+
+  def test_get_capacity
+    @receiver_impl.
+      should_receive(:getCapacity).
+      once.
+      and_return(17)
+
+    assert_equal 17, @receiver.capacity
+  end
+
+  def test_get_available
+    @receiver_impl.
+      should_receive(:getAvailable).
+      once.
+      and_return(2)
+
+    assert_equal 2, @receiver.available
+  end
+
+  def test_get_unsettled
+    @receiver_impl.
+      should_receive(:getUnsettled).
+      once.
+      and_return(12)
+
+    assert_equal 12, @receiver.unsettled
+  end
+
+  def test_close
+    @receiver_impl.
+      should_receive(:close).
+      once
+
+    @receiver.close
+  end
+
+  def test_closed_when_open
+    @receiver_impl.
+      should_receive(:isClosed).
+      once.
+      and_return(false)
+
+    assert !@receiver.closed?
+  end
+
+  def test_closed
+    @receiver_impl.
+      should_receive(:isClosed).
+      once.
+      and_return(true)
+
+    assert @receiver.closed?
+  end
+
+  def test_get_name
+    @receiver_impl.
+      should_receive(:getName).
+      once.
+      and_return("my-queue")
+
+    assert_equal "my-queue", @receiver.name
+  end
+
+  def test_get_session
+    @receiver_impl.
+      should_receive(:getSession).
+      once.
+      and_return(@session_impl)
+
+    result = @receiver.session
+
+    assert_not_nil result
+    assert_same @session_impl, result.session_impl
+  end
+
+  def test_is_valid
+    @receiver_impl.
+      should_receive(:isValid).
+      once.
+      and_return(false)
+
+    assert !@receiver.valid?
+  end
+
+  def test_is_null
+    @receiver_impl.
+      should_receive(:isNull).
+      once.
+      and_return(true)
+
+    assert @receiver.null?
+  end
+
+  def test_swap
+    @other_receiver.
+      should_receive(:receiver_impl).
+      once.
+      and_return(@other_receiver_impl)
+    @receiver_impl.
+      should_receive(:swap).
+      once.
+      with(@other_receiver_impl)
+
+    @receiver.swap @other_receiver
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
index a58b10f..549e268 100644
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -24,4 +24,5 @@ require 'test_encoding'
 require 'test_address'
 require 'test_message'
 require 'test_sender'
+require 'test_receiver'
 
-- 
1.7.6


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


[PATCH 02/11] Created the Duration namespace for duration contants.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

Added constants to map the C++ values to symbols within Ruby:

 * FOREVER
 * IMMEDIATE
 * MINUTE
 * SECOND
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb          |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb |   63 ++++++++++++++++++++++
 2 files changed, 64 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index 2cf0788..597446d 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -18,4 +18,5 @@
 #
 
 require 'qpid/errors'
+require 'qpid/duration'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb
new file mode 100644
index 0000000..c1f44e9
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb
@@ -0,0 +1,63 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'cqpid'
+
+module Qpid
+
+  module Messaging
+
+    # A Duration represents a period of time in milliseconds
+    #
+    # It defines the following named values as symbols:
+    #
+    # :FOREVER :: the maximum integer value for the platform
+    # :IMMEDIATE :: an alias for 0
+    # :SECOND :: 1,000ms
+    # :MINUTE :: 60,000ms
+    class Duration
+
+      def initialize duration # :nodoc:
+        @duration_impl = Cqpid::Duration.new duration
+      end
+
+      def duration_impl # :nodoc:
+        @duration_impl
+      end
+
+      def self.add_item(key, value) # :nodoc:
+        @hash ||= {}
+        @hash[key] = Duration.new value
+      end
+
+      def self.const_missing(key) # :nodoc:
+        @hash[key]
+      end
+
+      self.add_item :FOREVER,   Cqpid::Duration.FOREVER.getMilliseconds
+      self.add_item :IMMEDIATE, Cqpid::Duration.IMMEDIATE.getMilliseconds
+      self.add_item :SECOND,    Cqpid::Duration.SECOND.getMilliseconds
+      self.add_item :MINUTE,    Cqpid::Duration.MINUTE.getMilliseconds
+
+    end
+
+  end
+
+end
+
-- 
1.7.6


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


[PATCH 05/11] Created the Message class and its unit tests.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

The class is packaged as:

Qpid::Messaging::Message

A Message can return its content and be used to send a message over an
instance of Sender.
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb          |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb  |  129 +++++++++
 qpid/cpp/bindings/qpid/ruby/test/test_message.rb |  307 ++++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb  |    1 +
 4 files changed, 438 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/test_message.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index f9d5822..b5ac578 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -21,4 +21,5 @@ require 'qpid/errors'
 require 'qpid/duration'
 require 'qpid/address'
 require 'qpid/encoding'
+require 'qpid/message'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb
new file mode 100644
index 0000000..652b9fe
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb
@@ -0,0 +1,129 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'cqpid'
+
+module Qpid
+
+  module Messaging
+
+    # Message represents a message.
+    class Message
+
+      def initialize(args = {}, message_impl = nil)
+        @message_impl = message_impl
+        @message_impl = Cqpid::Message.new if @message_impl.nil?
+        @message_impl.setContent args[:content].to_s if args[:content]
+      end
+
+      def message_impl # :nodoc:
+        @message_impl
+      end
+
+      # Assigns the reply to address.
+      # The address must be an instance of Address.
+      def reply_to=(address); @message_impl.setReplyTo address.address_impl; end
+
+      # Returns the reply to address for the message as an instance of +Address+.
+      def reply_to
+        address_impl = @message_impl.getReplyTo
+        # only return an address if a reply to was specified
+        Qpid::Messaging::Address.new(nil, nil, nil, nil, address_impl) if address_impl
+      end
+
+      # Sets the subject.
+      def subject=(subject); @message_impl.setSubject subject; end
+
+      # Returns the subject.
+      def subject; @message_impl.getSubject; end
+
+      # Sets the content type.
+      def content_type=(content_type); @message_impl.setContentType content_type; end
+
+      # Returns the content type.
+      def content_type; @message_impl.getContentType; end
+
+      # Sets the message id.
+      def message_id=(message_id); @message_impl.setMessageId message_id.to_s; end
+
+      # Returns the message id.
+      def message_id; @message_impl.getMessageId; end
+
+      # Sets the user id.
+      def user_id=(user_id); @message_impl.setUserId user_id; end
+
+      # Returns the user id.
+      def user_id; @message_impl.getUserId; end
+
+      # Sets the correlation id.
+      def correlation_id=(correlation_id); @message_impl.setCorrelationId correlation_id; end
+
+      # Returns the correlation id.
+      def correlation_id; @message_impl.getCorrelationId; end
+
+      # Sets the priority.
+      def priority=(priority); @message_impl.setPriority priority; end
+
+      # Returns the priority.
+      def priority; @message_impl.getPriority; end
+
+      # Sets the time-to-live in milliseconds.
+      def ttl=(duration); @message_impl.setTtl duration; end
+
+      # Returns the time-to-live in milliseconds.
+      def ttl; @message_impl.getTtl; end
+
+      # Sets the durability.
+      def durable=(durable); @message_impl.setDurable durable; end
+
+      # Returns the durability.
+      def durable; @message_impl.getDurable; end
+
+      # Allows marking the message as redelivered.
+      def redelivered=(redelivered); @message_impl.setRedelivered redelivered; end
+
+      # Returns if the message was redelivered.
+      def redelivered; @message_impl.getRedelivered; end
+
+      # Returns all named properties.
+      # *NOTE:* It is recommended to use the +foo[key]+ method for
+      # retrieving properties.
+      def properties; @message_impl.getProperties; end
+
+      # Returns the value for the named property.
+      def [](key); self.properties[key.to_s]; end
+
+      # Assigns a value to the named property.
+      def []=(key, value); @message_impl.setProperty(key.to_s, value.to_s); end
+
+      # Sets the content.
+      def content=(content); @message_impl.setContent content.to_s; end
+
+      # Returns the content.
+      def content; @message_impl.getContent; end
+
+      # Returns the content's size.
+      def content_size; @message_impl.getContentSize; end
+
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_message.rb b/qpid/cpp/bindings/qpid/ruby/test/test_message.rb
new file mode 100644
index 0000000..0d71d42
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/test_message.rb
@@ -0,0 +1,307 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+require 'flexmock/test_unit'
+
+require 'qpid/encoding'
+require 'qpid/message'
+
+class TestMessage < Test::Unit::TestCase
+
+  def setup
+    @address = flexmock("address")
+    @address_impl = flexmock("address_impl")
+
+    @message_impl = flexmock("message")
+    @message = Qpid::Messaging::Message.new({}, @message_impl)
+ end
+
+  def test_message_impl
+    assert_same @message_impl, @message.message_impl
+  end
+
+  def test_set_reply_to
+    @address.
+      should_receive(:address_impl).
+      once.
+      and_return(@address_impl)
+    @message_impl.
+      should_receive(:setReplyTo).
+      once.
+      with(@address_impl)
+
+    @message.reply_to = @address
+  end
+
+  def test_get_reply_to
+    @message_impl.
+      should_receive(:getReplyTo).
+      once.
+      and_return(@address_impl)
+
+    result = @message.reply_to
+
+    assert_not_nil result
+    assert_same @address_impl, result.address_impl
+  end
+
+  def test_set_subject
+    @message_impl.
+      should_receive(:setSubject).
+      once.
+      with("New Subject")
+
+    @message.subject = "New Subject"
+  end
+
+  def test_get_subject
+    @message_impl.
+      should_receive(:getSubject).
+      once.
+      and_return("Old Subject")
+
+    assert_equal "Old Subject", @message.subject
+  end
+
+  def test_set_content_type
+    @message_impl.
+      should_receive(:setContentType).
+      once.
+      and_return("amqp/map")
+
+    @message.content_type = "amqp/map"
+  end
+
+  def test_get_content_type
+    @message_impl.
+      should_receive(:getContentType).
+      once.
+      and_return("amqp/list")
+
+    assert_equal "amqp/list", @message.content_type
+  end
+
+  def test_set_message_id
+    @message_impl.
+      should_receive(:setMessageId).
+      once.
+      with("717")
+
+    @message.message_id = "717"
+  end
+
+  def test_get_message_id
+    @message_impl.
+      should_receive(:getMessageId).
+      once.
+      and_return("1965")
+
+    assert_equal "1965", @message.message_id
+  end
+
+  def test_set_user_id
+    @message_impl.
+      should_receive(:setUserId).
+      once.
+      with("129")
+
+    @message.user_id = "129"
+  end
+
+  def test_get_user_id
+    @message_impl.
+      should_receive(:getUserId).
+      once.
+      and_return("1971")
+
+    assert_equal "1971", @message.user_id
+  end
+
+  def test_set_correlation_id
+    @message_impl.
+      should_receive(:setCorrelationId).
+      once.
+      with("320")
+
+    @message.correlation_id = "320"
+  end
+
+  def test_get_correlation_id
+    @message_impl.
+      should_receive(:getCorrelationId).
+      once.
+      and_return("1996")
+
+    assert_equal "1996", @message.correlation_id
+  end
+
+  def test_set_priority
+    @message_impl.
+      should_receive(:setPriority).
+      once.
+      with(9)
+
+    @message.priority = 9
+  end
+
+  def test_get_priority
+    @message_impl.
+      should_receive(:getPriority).
+      once.
+      and_return(21)
+
+    assert_equal 21, @message.priority
+  end
+
+  def test_set_ttl
+    @message_impl.
+      should_receive(:setTtl).
+      once.
+      with(Qpid::Messaging::Duration::FOREVER)
+
+    @message.ttl = Qpid::Messaging::Duration::FOREVER
+  end
+
+  def test_get_ttl
+    @message_impl.
+      should_receive(:getTtl).
+      once.
+      and_return(Qpid::Messaging::Duration::SECOND)
+
+    assert_equal Qpid::Messaging::Duration::SECOND, @message.ttl
+  end
+
+  def test_set_durable
+    @message_impl.
+      should_receive(:setDurable).
+      once.
+      with(true)
+
+    @message.durable = true
+  end
+
+  def test_set_not_durable
+    @message_impl.
+      should_receive(:setDurable).
+      once.
+      with(false)
+
+    @message.durable = false
+  end
+
+  def test_get_durable
+    @message_impl.
+      should_receive(:getDurable).
+      once.
+      and_return(true)
+
+    assert @message.durable
+  end
+
+  def test_set_redelivered
+    @message_impl.
+      should_receive(:setRedelivered).
+      once.
+      with(true)
+
+    @message.redelivered = true
+  end
+
+  def test_set_not_redelivered
+    @message_impl.
+      should_receive(:setRedelivered).
+      once.
+      with(false)
+
+    @message.redelivered = false
+  end
+
+  def test_get_redelivered
+    @message_impl.
+      should_receive(:getRedelivered).
+      once.
+      and_return(false)
+
+    assert !@message.redelivered
+  end
+
+  def test_get_properties
+    properties = {"foo" => "bar"}
+    @message_impl.
+      should_receive(:getProperties).
+      once.
+      and_return(properties)
+
+    result = @message.properties
+
+    assert_equal properties, result
+  end
+
+  def test_get_property
+    @message_impl.
+      should_receive(:getProperties).
+      once.
+      and_return({"foo" => "bar"})
+
+    result = @message["foo"]
+
+    assert_equal "bar", result
+  end
+
+  def test_set_property
+    @message_impl.
+      should_receive(:setProperty).
+      once.
+      with("foo", "bar")
+
+    @message["foo"] = "bar"
+  end
+
+  def test_set_content
+    @message_impl.
+      should_receive(:setContent).
+      once.
+      with("foo")
+
+    @message.content = "foo"
+  end
+
+  def test_get_content
+    @message_impl.
+      should_receive(:getContent).
+      once.
+      and_return("foo")
+
+    assert_equal "foo", @message.content
+  end
+
+  def test_get_content_size
+    @message_impl.
+      should_receive(:getContentSize).
+      once.
+      and_return(68)
+
+    assert_equal 68, @message.content_size
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
index 750d335..8139983 100644
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -22,4 +22,5 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
 require 'test/unit'
 require 'test_encoding'
 require 'test_address'
+require 'test_message'
 
-- 
1.7.6


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


[PATCH 04/11] Created the Ruby bindings for Address.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb          |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb  |  125 ++++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/test_address.rb |   39 +++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb  |    1 +
 4 files changed, 166 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/test_address.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index 725fa45..f9d5822 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -19,5 +19,6 @@
 
 require 'qpid/errors'
 require 'qpid/duration'
+require 'qpid/address'
 require 'qpid/encoding'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb
new file mode 100644
index 0000000..73b61bb
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb
@@ -0,0 +1,125 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'cqpid'
+
+module Qpid
+
+  module Messaging
+
+    # Address represents an address to which messages can be sent or from
+    # which they can be received.
+    #
+    # An Address can be described using the following pattern:
+    #
+    # <address> [ / <subject> ] ; [ { <key> : <value> , ... } ]
+    #
+    # where *address* is a simple name and *subject* is a subject or subject
+    # pattern.
+    #
+    # The options, enclosed in curly braces, are key:value pairs delimited by
+    # a comma. The values can be nested maps also enclosed in curly braces.
+    # Or they can be lists of values, where they are contained within square
+    # brackets but still comma delimited, such as:
+    #
+    # [value1,value2,value3]
+    #
+    # The following are the list of supported options:
+    #
+    # create:: Indicates if the address should be created; values are *always*,
+    #          *never*, *sender* or *reciever*.
+    #
+    # assert:: Indicates whether or not to assert any specified node properties;
+    #          values are *always*, *never*, *sender* or *receiver*.
+    #
+    # delete:: Indicates whether or not to delete the addressed node when a
+    #          sender or receiver is cancelled; values are *always*, *never*,
+    #          *sender* or *receiver*.
+    #
+    # node:: A nested map describing properties for the addressed node.
+    #        Properties are *type* (*topic* or *queue*), *durable* (a boolean),
+    #        *x-declare* (a nested map of amqp 0.10-specific options) and
+    #        *x-bindings*. (nested list which specifies a queue, exchange or
+    #        a binding key and arguments.
+    #
+    # link:: A nested map through which properties of the link can be specified;
+    #        properties are *durable*, *reliability*, *x-declare*, *x-subscribe*
+    #        and *x-bindings*.
+    #
+    # mode:: (*For receivers only*) indicates whether the receiver should consume
+    #        or browse messages; values are *consume* (the default) and *browse*.
+    class Address
+
+      def initialize(name, subject, options = {}, _type = "", address_impl = nil)
+        @address_impl = address_impl || Cqpid::Address.new(name, subject, convert_options(options), _type)
+      end
+
+       def address_impl # :nodoc:
+         @address_impl
+       end
+
+       # Returns the name.
+      def name; @address_impl.getName; end
+
+      # Sets the name.
+      def name=(name); @address_impl.setName name; end
+
+      # Returns the subject.
+      def subject; @address_impl.getSubject; end
+
+      # Sets the subject.
+      def subject=(subject); @address_impl.setSubject(subject); end
+
+      # Returns the type.
+      #---
+      # We cannot use "type" since that clashes with the Ruby object.type
+      # identifier.
+      def _type; @address_impl.getType; end
+
+      # Sets the type.
+      #
+      # The type of the address determines how Sender and Receiver objects
+      # are constructed for it. If no type is specified then it will be
+      # determined by querying the broker.
+      def _type=(_type); @address_impl.setType(_type); end
+
+      # Returns the options.
+      def options; @address_impl.getOptions; end
+
+      # Sets the options for the address.
+      # Any symbols are converted to strings.
+      def options=(options); @address_impl.setOptions(convert_options(options)); end
+
+      def to_s; @address_impl.str; end
+
+      private
+
+      def convert_options(options)
+        result = {}
+        options.each_pair {|key, value| result[key.to_s] = value.to_s}
+
+        return result
+      end
+
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_address.rb b/qpid/cpp/bindings/qpid/ruby/test/test_address.rb
new file mode 100644
index 0000000..f54e93a
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/test_address.rb
@@ -0,0 +1,39 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+require 'flexmock/test_unit'
+
+require 'cqpid'
+require 'qpid/address'
+
+class TestAddress < Test::Unit::TestCase
+
+  def test_constructor
+    result = Qpid::Messaging::Address.new "name", "subject", {:foo => :bar}, "type"
+
+    assert_equal "name", result.name
+    assert_equal "subject", result.subject
+    assert_equal "type", result._type
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
index 68af267..750d335 100644
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -21,4 +21,5 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
 
 require 'test/unit'
 require 'test_encoding'
+require 'test_address'
 
-- 
1.7.6


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


[PATCH 11/11] Ruby specific .gitignore file.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

Ignores pkg and html directories.
---
 qpid/cpp/bindings/qpid/ruby/.gitignore |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/.gitignore

diff --git a/qpid/cpp/bindings/qpid/ruby/.gitignore b/qpid/cpp/bindings/qpid/ruby/.gitignore
new file mode 100644
index 0000000..ab78513
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/.gitignore
@@ -0,0 +1,2 @@
+pkg
+html
-- 
1.7.6


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


[PATCH 09/11] Created the Connection class and its unit tests.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

The Connection class is packaged as follows:

Qpid::Messaging::Connection
---
 qpid/cpp/bindings/qpid/ruby/lib/qpid.rb            |    1 +
 qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb |  134 ++++++++++
 .../cpp/bindings/qpid/ruby/test/test_connection.rb |  257 ++++++++++++++++++++
 qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb    |    1 +
 4 files changed, 393 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb
 create mode 100644 qpid/cpp/bindings/qpid/ruby/test/test_connection.rb

diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
index 65e6393..1f00c13 100644
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
@@ -25,4 +25,5 @@ require 'qpid/message'
 require 'qpid/sender'
 require 'qpid/receiver'
 require 'qpid/session'
+require 'qpid/connection'
 
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb
new file mode 100644
index 0000000..5c56c1f
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb
@@ -0,0 +1,134 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'cqpid'
+
+module Qpid
+
+  module Messaging
+
+    # Connection allows for establishing connections to a remote endpoint.
+    class Connection
+
+      # The following general options are supported (as strings or symbols):
+      #
+      # username::
+      # password::
+      # heartbeat::
+      # tcp_nodelay::
+      # sasl_mechanism::
+      # sasl_service::
+      # sasl_min_ssf::
+      # sasl_max_ssf::
+      # transport::
+      #
+      # The following options specifically control reconnection behavior:
+      #
+      # reconnect:: *true* or *false*; indicates whether to attempt reconnections
+      # reconnect_timeout:: the number of seconds to attempt reconnecting
+      # reconnect_limit:: the number of retries before reporting failure
+      # reconnect_interval_min:: initial delay, in seconds, before attempting a reconnecting
+      # reconnect_interval_max:: number of seconds to wait before additional reconnect attempts
+      # reconnect_interval:: shorthand for setting box min and max values
+      # reconnect_urls:: a list of alternate URLs to use for reconnection attempts
+      def initialize(url, options = {}, connection_impl = nil)
+        @url = url
+        @connection_impl = connection_impl
+        @options = options
+      end
+
+      def connection_impl # :nodoc:
+        @connection_impl
+      end
+
+      # Opens the connection.
+      def open
+        @connection_impl = Cqpid::Connection.new(@url, convert_options)
+        @connection_impl.open
+      end
+
+      # Reports whether the connection is open.
+      def open?; false || (@connection_impl.isOpen if @connection_impl); end
+
+      # Closes the connection.
+      def close; @connection_impl.close if open?; end
+
+      # Creates a new session.
+      #
+      # If :transactional => true then a transactional session is created.
+      # Otherwise a standard session is created.
+      def create_session(args = {})
+        name = args[:name] || ""
+        if open?
+          if args[:transactional]
+            session = @connection_impl.createTransactionalSession name
+          else
+            session = @connection_impl.createSession name
+          end
+          return Session.new(session)
+        else
+          raise RuntimeError.new "No connection available."
+        end
+      end
+
+      # Returns a session for the specified session name.
+      def session name
+        session_impl = @connection_impl.getSession name
+        Qpid::Messaging::Session.new session_impl if session_impl
+      end
+
+      # Returns the username used to authenticate with the connection.
+      def authenticated_username; @connection_impl.getAuthenticatedUsername if open?; end
+
+      # inherited from Handle
+
+      # Returns whether the underlying handle is valid; i.e., not null.
+      def valid?
+        @connection_impl.isValid
+      end
+
+      # Returns whether the underlying handle is null.
+      def null?
+        @connection_impl.isNull
+      end
+
+      # Swaps the underlying connection handle.
+      def swap connection
+        @connection_impl.swap connection.connection_impl
+      end
+
+      private
+
+      def convert_options
+        result = {}
+        # map only those options defined in the C++ layer
+        # TODO when new options are added, this needs to be updated.
+        unless @options.nil? || @options.empty?
+          @options.each_pair {|key, value| result[key.to_s] = value.to_s}
+        end
+
+        return result
+      end
+
+    end
+
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb b/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb
new file mode 100644
index 0000000..648fb05
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb
@@ -0,0 +1,257 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+
+require 'test/unit'
+require 'flexmock/test_unit'
+
+require 'cqpid'
+require 'qpid/connection'
+
+class TestConnection < Test::Unit::TestCase
+
+  def setup
+    @connection_impl       = flexmock("connection_impl")
+    @other_connection      = flexmock("other_connection")
+    @other_connection_impl = flexmock("other_connection_impl")
+    @cqpid_connection      = flexmock(Cqpid::Connection)
+
+    @session      = flexmock("session")
+    @session_name = "test-session"
+
+    @url     = "localhost"
+    @options = {}
+
+    @connection = Qpid::Messaging::Connection.new(@url, @options, @connection_impl)
+  end
+
+  def test_create_with_username_and_password
+    @cqpid_connection.
+      should_receive(:new).
+      once.with("localhost",
+                {"username" => "username",
+                  "password" => "password"}).
+      and_return(@connection_impl)
+    @connection_impl.
+      should_receive(:open).
+      once
+
+    result = Qpid::Messaging::Connection.new("localhost",
+                                             :username => "username",
+                                             :password => "password")
+    result.open
+
+    assert_same @connection_impl, result.connection_impl
+  end
+
+  def test_create_with_hostname
+    result = Qpid::Messaging::Connection.new("localhost")
+
+    assert_not_nil result
+  end
+
+  def test_open
+    @cqpid_connection.
+      should_receive(:new).
+      once.
+      with(@url, {}).
+      and_return(@connection_impl)
+    @connection_impl.
+      should_receive(:open).
+      once
+
+    @connection.open
+
+    assert_same @connection_impl, @connection.connection_impl
+  end
+
+  def test_check_open_when_open
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(true)
+
+    assert @connection.open?
+  end
+
+  def test_check_open_before_connection
+    result = Qpid::Messaging::Connection.new("hostname")
+
+    assert !result.open?
+  end
+
+  def test_check_open_when_closed
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(false)
+
+    assert !@connection.open?
+  end
+
+  def test_close_an_unopened_session
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(false)
+
+    @connection.close
+  end
+
+  def test_close
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(true).
+      should_receive(:close).
+      once
+
+    @connection.close
+  end
+
+  def test_create_session_without_name
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(true).
+      should_receive(:createSession).
+      once.
+      with("").
+      and_return(@session)
+
+    result = @connection.create_session
+
+    assert_not_nil result
+    assert_same @session, result.session_impl
+  end
+
+  def test_create_session
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(true).
+      should_receive(:createSession).
+      once.
+      with(@session_name).
+      and_return(@session)
+
+    result = @connection.create_session :name => @session_name
+
+    assert_not_nil result
+    assert_same @session, result.session_impl
+  end
+
+  def test_create_session_raises_exception_when_closed
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(false)
+
+    assert_raise(RuntimeError) {@connection.create_session @session_name}
+  end
+
+  def test_create_transactional_session
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(true).
+      should_receive(:createTransactionalSession).
+      once.
+      with("").
+      and_return(@session)
+
+    result = @connection.create_session :transactional => true
+
+    assert_not_nil result
+    assert_same @session, result.session_impl
+  end
+
+  def test_authenticated_username_when_not_connected
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(false)
+
+    result = @connection.authenticated_username
+
+    assert_nil result
+  end
+
+  def test_authenticated_username
+    @connection_impl.
+      should_receive(:isOpen).
+      once.
+      and_return(true).
+      should_receive(:getAuthenticatedUsername).
+      once.
+      and_return("farkle")
+
+    result = @connection.authenticated_username
+
+    assert_equal "farkle", result
+  end
+
+  def test_get_session_with_invalid_name
+    @connection_impl.
+      should_receive(:getSession).
+      once.
+      with(@session_name).
+      and_return(nil)
+
+    result = @connection.session @session_name
+
+    assert_nil result
+  end
+
+  # APIs inherited from Handle
+
+  def test_is_valid
+    @connection_impl.
+      should_receive(:isValid).
+      once.
+      and_return(true)
+
+    assert @connection.valid?
+  end
+
+  def test_is_null
+    @connection_impl.
+      should_receive(:isNull).
+      once.
+      and_return(false)
+
+    assert !@connection.null?
+  end
+
+  def test_swap
+    @other_connection.
+      should_receive(:connection_impl).
+      once.
+      and_return(@other_connection_impl)
+    @connection_impl.
+      should_receive(:swap).
+      once.
+      with(@other_connection_impl)
+
+    @connection.swap @other_connection
+  end
+
+end
+
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
index 4d3b906..7aa410c 100644
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
@@ -26,4 +26,5 @@ require 'test_message'
 require 'test_sender'
 require 'test_receiver'
 require 'test_session'
+require 'test_connection'
 
-- 
1.7.6


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


[PATCH 10/11] Created the Rakefile for automating tasks.

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
From: "Darryl L. Pierce" <dp...@redhat.com>

The Rakefile allows us to run both unit and integration tests.

Also included a README.rdoc file.

All tests are in the "test:" namespace, and can be run with the
commands:

rake test:units
rake test:integrations
rake test:all # runs both unit and integraton tests
rake test     # alias for test:all
---
 qpid/cpp/bindings/qpid/ruby/README.rdoc |   27 +++++++++++
 qpid/cpp/bindings/qpid/ruby/Rakefile    |   74 +++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 0 deletions(-)
 create mode 100644 qpid/cpp/bindings/qpid/ruby/README.rdoc
 create mode 100644 qpid/cpp/bindings/qpid/ruby/Rakefile

diff --git a/qpid/cpp/bindings/qpid/ruby/README.rdoc b/qpid/cpp/bindings/qpid/ruby/README.rdoc
new file mode 100644
index 0000000..960fdf6
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/README.rdoc
@@ -0,0 +1,27 @@
+= Qpid - Open Source AMQP Messaging
+
+Qpid is an cross-platform enterprise messaging system.
+
+Version :: 0.10.0.alpha.0
+
+= Links
+
+Documents :: http://qpid.apache.org/
+
+= Installation
+
+You can install Qpid with the following command.
+
+  $ gem install qpid
+
+== Examples
+
+Take a look at the integration tests for examples on how to leverage
+the messaging capabilities of Qpid in your Ruby applications.
+
+== License
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor licensing agreements.
+
+
diff --git a/qpid/cpp/bindings/qpid/ruby/Rakefile b/qpid/cpp/bindings/qpid/ruby/Rakefile
new file mode 100644
index 0000000..ef2b158
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/ruby/Rakefile
@@ -0,0 +1,74 @@
+# Rakefile for Qpid -*- ruby -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+task :noop
+
+require 'rubygems'
+require 'rake/clean'
+require 'rake/rdoctask'
+require 'rake/testtask'
+
+CLOBBER.include('pkg')
+
+load './lib/qpid/version.rb'
+
+desc 'Default: run all tests.'
+task :default => :'test:all'
+
+#---------------
+# Testing tasks.
+#---------------
+
+desc 'Run all tests (alias for test:all).'
+task :test => :'test:all'
+
+namespace :test do
+  desc "Run all tests (default)."
+  task :all => [:units, :integrations]
+
+  desc "Run unit tests."
+  Rake::TestTask.new(:units) do |t|
+    t.libs << '.'
+    t.pattern = 'test/test*.rb'
+    t.verbose = true
+  end
+
+  desc "Run integration tests."
+  Rake::TestTask.new(:integrations) do |t|
+    t.libs << '.'
+    t.pattern = 'test/integration/*.rb'
+    t.verbose = true
+  end
+
+end
+
+#---------------------
+# Documentation tasks.
+#---------------------
+
+Rake::RDocTask.new(
+                   :rdoc => 'rdoc',
+                   :clobber_rdoc => 'rdoc:clean',
+                   :rerdoc => 'rdoc:force'
+                   ) do |rd|
+  rd.main    = 'README.rdoc'
+  rd.options << '--all'
+  rd.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
+end
-- 
1.7.6


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