You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2018/01/05 16:35:47 UTC

[23/50] [abbrv] qpid-proton git commit: PROTON-1537: [ruby] Fixes to Delivery and Codec

PROTON-1537: [ruby] Fixes to Delivery and Codec


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/72074d42
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/72074d42
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/72074d42

Branch: refs/heads/go1
Commit: 72074d42a444eceaac2362a55badb29314e1c615
Parents: c172383
Author: Alan Conway <ac...@redhat.com>
Authored: Sat Dec 9 14:14:44 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Dec 13 13:16:48 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/codec/data.rb      |   2 +-
 proton-c/bindings/ruby/lib/core/delivery.rb   |  31 +++---
 proton-c/bindings/ruby/lib/core/tracker.rb    |  14 +--
 proton-c/bindings/ruby/lib/core/transfer.rb   |   3 +
 proton-c/bindings/ruby/lib/handler/adapter.rb |   6 +-
 proton-c/bindings/ruby/lib/types/array.rb     |   2 +-
 proton-c/bindings/ruby/lib/types/hash.rb      |   2 +-
 proton-c/bindings/ruby/lib/util/wrapper.rb    |   3 +-
 proton-c/bindings/ruby/tests/test_delivery.rb | 106 +++++++++++++++++++++
 proton-c/bindings/ruby/tests/test_interop.rb  |   3 +-
 proton-c/bindings/ruby/tests/test_tools.rb    |  13 +++
 11 files changed, 157 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/codec/data.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/codec/data.rb b/proton-c/bindings/ruby/lib/codec/data.rb
index 86af3a1..1573b5c 100644
--- a/proton-c/bindings/ruby/lib/codec/data.rb
+++ b/proton-c/bindings/ruby/lib/codec/data.rb
@@ -120,7 +120,7 @@ module Qpid::Proton
 
       def expect(code)
         unless code == self.code
-          raise TypeError, "expected #{Cproton.pn_type_name(code)}, got #{Cproton.pn_type_name(code)}"
+          raise TypeError, "expected #{Cproton.pn_type_name(code)}, got #{Cproton.pn_type_name(self.code)}"
         end
       end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/core/delivery.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/delivery.rb b/proton-c/bindings/ruby/lib/core/delivery.rb
index b240784..ba89097 100644
--- a/proton-c/bindings/ruby/lib/core/delivery.rb
+++ b/proton-c/bindings/ruby/lib/core/delivery.rb
@@ -31,29 +31,34 @@ module Qpid::Proton
     # Release a message, indicating to the sender that it was not processed
     # but may be delivered again to this or another receiver.
     #
-    # @param mods [Hash] Instructions to the sender to modify re-delivery.
+    # @param opts [Hash] Instructions to the sender to modify re-delivery.
     #  To allow re-delivery with no modifications at all use +release(nil)+
     #
-    # @option mods [Boolean] :failed Instruct the sender to increase
+    # @option opts [Boolean] :failed (true) Instruct the sender to increase
     #  {Message#delivery_count} so future receivers will know there was a
     #  previous failed delivery.
     #
-    # @option mods [Boolean] :undeliverable Instruct the sender that this
+    # @option opts [Boolean] :undeliverable (false) Instruct the sender that this
     #  message should never be re-delivered to this receiver, although it may be
     #  delivered other receivers.
     #
-    # @option mods [Hash] :annotations Instruct the sender to update the
-    #  {Message#annotations} with these +key=>value+ pairs before re-delivery.
-    def release(mods = {:failed=>true})
-      mods = { :failed => true } if mods == true # Backwards compatibility
-      if !mods || mods.empty?
-        settle(RELEASED)
-      else
+    # @option opts [Hash] :annotations Instruct the sender to update the
+    #  {Message#annotations} with these +key=>value+ pairs before re-delivery,
+    #  replacing existing entries in {Message#annotations} with the same key.
+    def release(opts = nil)
+      opts = { :failed => false } if (opts == false) # deprecated
+      failed = !opts || opts.fetch(:failed, true)
+      undeliverable = opts && opts[:undeliverable]
+      annotations = opts && opts[:annotations]
+      annotations = nil if annotations && annotations.empty?
+      if failed || undeliverable || annotations
         d = Cproton.pn_delivery_local(@impl)
-        Cproton.pn_disposition_set_failed(mods[:failed])
-        Cproton.pn_disposition_set_undeliverable(mods[:undeliverable])
-        Data.from_object(Cproton.pn_disposition_annotations(d), mods[:annotations]) if mods.key? :annotations
+        Cproton.pn_disposition_set_failed(d, true) if failed
+        Cproton.pn_disposition_set_undeliverable(d, true) if undeliverable
+        Codec::Data.from_object(Cproton.pn_disposition_annotations(d), annotations) if annotations
         settle(MODIFIED)
+      else
+        settle(RELEASED)
       end
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/core/tracker.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/tracker.rb b/proton-c/bindings/ruby/lib/core/tracker.rb
index 79620de..cf04be9 100644
--- a/proton-c/bindings/ruby/lib/core/tracker.rb
+++ b/proton-c/bindings/ruby/lib/core/tracker.rb
@@ -23,14 +23,16 @@ module Qpid::Proton
     # @return [Sender] The parent {Sender} link.
     def sender() link; end
 
-    # Re-delivery modifications provided by the receiver in {Delivery#release}
-    # @return [Hash] See the {Delivery#release} +mods+ parameter.
+    # Re-delivery modifications sent by the receiver in {Delivery#release}
+    # @return [Hash] See the {Delivery#release} +opts+ parameter.
+    # @return [nil] If no modifications were requested by the receiver.
     def modifications()
-      return {}  unless (state == MODIFIED) && (d = Cproton.pn_delivery_remote(@impl))
+      return nil if (state != MODIFIED)
+      d = Cproton.pn_delivery_remote(@impl)
       {
-       :failed => Cproton.pn_disposition_get_failed(d),
-       :undeliverable => Cproton.pn_disposition_get_undeliverable(d),
-       :annotations => Data.to_object(Cproton.pn_disposition_annotations(d))
+       :failed => Cproton.pn_disposition_is_failed(d),
+       :undeliverable => Cproton.pn_disposition_is_undeliverable(d),
+       :annotations => Codec::Data.to_object(Cproton.pn_disposition_annotations(d))
       }
     end
   end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/core/transfer.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transfer.rb b/proton-c/bindings/ruby/lib/core/transfer.rb
index 57e8b55..cdf3419 100644
--- a/proton-c/bindings/ruby/lib/core/transfer.rb
+++ b/proton-c/bindings/ruby/lib/core/transfer.rb
@@ -112,7 +112,10 @@ module Qpid::Proton
     def settle(state = nil)
       update(state) unless state.nil?
       Cproton.pn_delivery_settle(@impl)
+      @inspect = inspect # Save the inspect string, the delivery pointer will go bad.
     end
 
+    def inspect() @inspect || super; end
+    def to_s() inspect; end
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/handler/adapter.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/adapter.rb b/proton-c/bindings/ruby/lib/handler/adapter.rb
index 8fe9bc5..25dd8c0 100644
--- a/proton-c/bindings/ruby/lib/handler/adapter.rb
+++ b/proton-c/bindings/ruby/lib/handler/adapter.rb
@@ -122,9 +122,8 @@ module Qpid::Proton::Handler
               d.release(true)
             end
           end
-        elsif d.updated? && d.settled?
-          delegate(:on_settled, event)
         end
+        delegate(:on_settled, event) if d.settled?
         add_credit(event)
       else                      # Outgoing message
         t = event.tracker
@@ -132,7 +131,8 @@ module Qpid::Proton::Handler
           case t.remote_state
           when Qpid::Proton::Delivery::ACCEPTED then delegate(:on_accepted, event)
           when Qpid::Proton::Delivery::REJECTED then delegate(:on_rejected, event)
-          when Qpid::Proton::Delivery::RELEASED, Qpid::Proton::Delivery::MODIFIED then delegate(:on_released, event)
+          when Qpid::Proton::Delivery::RELEASED then delegate(:on_released, event)
+          when Qpid::Proton::Delivery::MODIFIED then delegate(:on_modified, event)
           end
           delegate(:on_settled, event) if t.settled?
           t.settle if @opts[:auto_settle]

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/types/array.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/types/array.rb b/proton-c/bindings/ruby/lib/types/array.rb
index 3051f31..d00a86b 100644
--- a/proton-c/bindings/ruby/lib/types/array.rb
+++ b/proton-c/bindings/ruby/lib/types/array.rb
@@ -18,7 +18,7 @@
 
 #--
 # Patch the Array class to provide methods for adding its contents
-# to a Qpid::Proton::Data instance.
+# to a Qpid::Proton::Codec::Data instance.
 #++
 
 module Qpid::Proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/types/hash.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/types/hash.rb b/proton-c/bindings/ruby/lib/types/hash.rb
index 736bb8f..f70cbdb 100644
--- a/proton-c/bindings/ruby/lib/types/hash.rb
+++ b/proton-c/bindings/ruby/lib/types/hash.rb
@@ -18,7 +18,7 @@
 
 #--
 # Patch the Hash class to provide methods for adding its contents
-# to a Qpid::Proton::Data instance.
+# to a Qpid::Proton::Codec::Data instance.
 #++
 
 # @private

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/lib/util/wrapper.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/wrapper.rb b/proton-c/bindings/ruby/lib/util/wrapper.rb
index 347a9a5..08d1794 100644
--- a/proton-c/bindings/ruby/lib/util/wrapper.rb
+++ b/proton-c/bindings/ruby/lib/util/wrapper.rb
@@ -124,6 +124,7 @@ module Qpid::Proton
       attr_accessor :impl
 
       def inspect
+        return "#{self.class}<nil>" unless @impl
         pstr = Cproton.pn_string("")
         begin
           Cproton.pn_inspect(@impl, pstr)
@@ -133,7 +134,7 @@ module Qpid::Proton
         end
       end
 
-      alias to_s inspect
+      def to_s() inspect; end
 
       def self.registry
         @registry ||= {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/tests/test_delivery.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_delivery.rb b/proton-c/bindings/ruby/tests/test_delivery.rb
new file mode 100644
index 0000000..334450a
--- /dev/null
+++ b/proton-c/bindings/ruby/tests/test_delivery.rb
@@ -0,0 +1,106 @@
+# 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 'minitest/autorun'
+require 'qpid_proton'
+require 'test_tools'
+include Qpid::Proton
+
+# Test Delivery and Tracker
+class TestDelivery < Minitest::Test
+
+  # Duck-typed handler
+  class NoAutoHandler
+    @@options = {:auto_settle=>false, :auto_accept=>false}
+    def options() @@options; end
+  end
+
+  class SendHandler < NoAutoHandler
+    def initialize(to_send)
+      @unsent = to_send
+    end
+
+    def on_connection_opened(event)
+      @outcomes = []
+      @sender = event.connection.open_sender("x")
+      @unsettled = {}           # Awaiting remote settlement
+    end
+
+    attr_reader :outcomes, :unsent, :unsettled
+
+    def on_sendable(event)
+      return if @unsent.empty?
+      m = Message.new(@unsent.shift)
+      tracker = event.sender.send(m)
+      @unsettled[tracker] = m
+    end
+
+    def outcome(event)
+      t = event.tracker
+      m = @unsettled.delete(t)
+      @outcomes << [m.body, event.method, t.id, t.state, t.modifications]
+      event.connection.close if @unsettled.empty?
+    end
+
+    def on_accepted(event) outcome(event); end
+    def on_rejected(event) outcome(event); end
+    def on_released(event) outcome(event); end
+    def on_modified(event) outcome(event); end
+  end
+
+  class ReceiveHandler < NoAutoHandler
+    def initialize
+      @received = []
+    end
+
+    attr_reader :received
+
+    def on_message(event)
+      @received << event.message.body
+      case event.message.body
+      when "accept" then event.delivery.accept
+      when "reject" then event.delivery.reject
+      when "release-really" then event.delivery.release({:failed=>false}) # AMQP RELEASED
+      when "release" then event.delivery.release # AMQP MODIFIED{ :failed => true }
+      when "modify" then event.delivery.release({:undeliverable => true, :annotations => {:x => 42 }})
+      when "modify-empty" then event.delivery.release({:failed => false, :undeliverable => false, :annotations => {}})
+      when "modify-nil" then event.delivery.release({:failed => false, :undeliverable => false, :annotations => nil})
+      else raise event.inspect
+      end
+    end
+  end
+
+  def test_outcomes
+    rh = ReceiveHandler.new
+    sh = SendHandler.new(["accept", "reject", "release-really", "release", "modify", "modify-empty", "modify-nil"])
+    c = TestContainer.new(nil, { :handler => rh },  __method__)
+    c.connect(c.url, {:handler => sh})
+    c.run
+    o = sh.outcomes
+    assert_equal ["accept", :on_accepted, "1", Transfer::ACCEPTED, nil], o.shift
+    assert_equal ["reject", :on_rejected, "2", Transfer::REJECTED, nil], o.shift
+    assert_equal ["release-really", :on_released, "3", Transfer::RELEASED, nil], o.shift
+    assert_equal ["release", :on_modified, "4", Transfer::MODIFIED, {:failed=>true, :undeliverable=>false, :annotations=>nil}], o.shift
+    assert_equal ["modify", :on_modified, "5", Transfer::MODIFIED, {:failed=>true, :undeliverable=>true, :annotations=>{:x => 42}}], o.shift
+    assert_equal ["modify-empty", :on_released, "6", Transfer::RELEASED, nil], o.shift
+    assert_equal ["modify-nil", :on_released, "7", Transfer::RELEASED, nil], o.shift
+    assert_empty o
+    assert_equal ["accept", "reject", "release-really", "release", "modify", "modify-empty", "modify-nil"], rh.received
+    assert_empty sh.unsettled
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/tests/test_interop.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_interop.rb b/proton-c/bindings/ruby/tests/test_interop.rb
index 0a13a3d..326b481 100755
--- a/proton-c/bindings/ruby/tests/test_interop.rb
+++ b/proton-c/bindings/ruby/tests/test_interop.rb
@@ -15,10 +15,9 @@ end
 
 class InteropTest < MiniTest::Test
   include  Qpid::Proton
-  Data = Codec::Data
 
   def setup
-    @data = Data.new
+    @data = Codec::Data.new
     @message = Message.new
   end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/72074d42/proton-c/bindings/ruby/tests/test_tools.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_tools.rb b/proton-c/bindings/ruby/tests/test_tools.rb
index 2dc13b3..bc9c1d9 100644
--- a/proton-c/bindings/ruby/tests/test_tools.rb
+++ b/proton-c/bindings/ruby/tests/test_tools.rb
@@ -116,3 +116,16 @@ class DriverPair < Array
   end
 
 end
+
+# Container that listens on a random port for a single connection
+class TestContainer < Container
+
+  def initialize(handler, lopts=nil, id=nil)
+    super handler, id
+    @server = TCPServer.open(0)
+    @listener = listen_io(@server, ListenOnceHandler.new(lopts))
+  end
+
+  def port() @server.addr[1]; end
+  def url() "amqp://:#{port}"; end
+end


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org